llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.16k stars 12.03k forks source link

Stack overflow in Sema involving attribute enable_if on constructor used for conversion #39854

Open comex opened 5 years ago

comex commented 5 years ago
Bugzilla Link 40508
Version trunk
OS All
CC @DougGregor,@zygoloid

Extended Description

Code:

struct B; struct A { A(B b); }; struct B { attribute((enable_if(true, "xxx"))) B(A a); }; void test(A a) { B b(a); }

When compiling this, Clang crashes due to infinite recursion. Note that the enable_if is required for it to crash, even though the expression is simply 'true'.

Backtrace:

[snip...]

frame #​5424: 0x000000011599e70a libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbed088, S=0x000000011d824000, Entity=0x00007ffeefbeebc0, Kind=0x00007ffeefbed038, Args=clang::MultiExprArg @ 0x00007ffeefbece50, TopLevelOfInitList=false, TreatUnavailableAsInvalid=true) at SemaInit.cpp:5323
frame #​5425: 0x000000011599ff0f libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbed088, S=0x000000011d824000, Entity=0x00007ffeefbeebc0, Kind=0x00007ffeefbed038, Args=clang::MultiExprArg @ 0x00007ffeefbecf20, TopLevelOfInitList=false, TreatUnavailableAsInvalid=true) at SemaInit.cpp:5322
frame #​5426: 0x00000001159b30ac libclangSema.dylib`clang::Sema::PerformCopyInitialization(this=0x000000011d824000, Entity=0x00007ffeefbeebc0, EqualLoc=(ID = 133), Init=(PtrWithInvalid = 4773125760), TopLevelOfInitList=false, AllowExplicit=false) at SemaInit.cpp:9140
frame #&#8203;5427: 0x0000000115b2b784 libclangSema.dylib`convertArgsForAvailabilityChecks(S=0x000000011d824000, Function=0x000000011c801be8, ThisArg=0x0000000000000000, Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbeec60, Trap=0x00007ffeefbeee48, MissingImplicitThis=true, ConvertedThis=0x00007ffeefbeedb0, ConvertedArgs=0x00007ffeefbeedb8) at SemaOverload.cpp:6321
frame #&#8203;5428: 0x0000000115b2aa9d libclangSema.dylib`clang::Sema::CheckEnableIf(this=0x000000011d824000, Function=0x000000011c801be8, Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbeee90, MissingImplicitThis=false) at SemaOverload.cpp:6370
frame #&#8203;5429: 0x0000000115b2988f libclangSema.dylib`clang::Sema::AddOverloadCandidate(this=0x000000011d824000, Function=0x000000011c801be8, FoundDecl=(Ptr = 4773125096), Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbef260, CandidateSet=0x00007ffeefbef770, SuppressUserConversions=true, PartialOverloading=false, AllowExplicit=false, IsADLCandidate=NotADL, EarlyConversions=clang::ConversionSequenceList @ 0x00007ffeefbef2d0) at SemaOverload.cpp:6183
frame #&#8203;5430: 0x0000000115b22c4d libclangSema.dylib`IsUserDefinedConversion(S=0x000000011d824000, From=0x000000011c801e80, ToType=QualType @ 0x00007ffeefbef5f0, User=0x00007ffeefbf1498, CandidateSet=0x00007ffeefbef770, AllowExplicit=false, AllowObjCConversionOnExplicit=false) at SemaOverload.cpp:3396
frame #&#8203;5431: 0x0000000115b4e6db libclangSema.dylib`TryUserDefinedConversion(S=0x000000011d824000, From=0x000000011c801e80, ToType=QualType @ 0x00007ffeefbef768, SuppressUserConversions=false, AllowExplicit=false, InOverloadResolution=true, CStyle=false, AllowObjCWritebackConversion=false, AllowObjCConversionOnExplicit=false) at SemaOverload.cpp:1274
frame #&#8203;5432: 0x0000000115b1c5bd libclangSema.dylib`TryImplicitConversion(S=0x000000011d824000, From=0x000000011c801e80, ToType=QualType @ 0x00007ffeefbf1250, SuppressUserConversions=false, AllowExplicit=false, InOverloadResolution=true, CStyle=false, AllowObjCWritebackConversion=false, AllowObjCConversionOnExplicit=false) at SemaOverload.cpp:1406
frame #&#8203;5433: 0x0000000115b2a90d libclangSema.dylib`TryCopyInitialization(S=0x000000011d824000, From=0x000000011c801e80, ToType=QualType @ 0x00007ffeefbf1330, SuppressUserConversions=false, InOverloadResolution=true, AllowObjCWritebackConversion=false, AllowExplicit=false) at SemaOverload.cpp:5066
frame #&#8203;5434: 0x0000000115b29777 libclangSema.dylib`clang::Sema::AddOverloadCandidate(this=0x000000011d824000, Function=0x000000011c8017f8, FoundDecl=(Ptr = 4773124088), Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbf16b0, CandidateSet=0x00007ffeefbf2558, SuppressUserConversions=false, PartialOverloading=false, AllowExplicit=false, IsADLCandidate=NotADL, EarlyConversions=clang::ConversionSequenceList @ 0x00007ffeefbf1720) at SemaOverload.cpp:6164
frame #&#8203;5435: 0x00000001159b8468 libclangSema.dylib`ResolveConstructorOverload(S=0x000000011d824000, DeclLoc=(ID = 133), Args=clang::MultiExprArg @ 0x00007ffeefbf1950, CandidateSet=0x00007ffeefbf2558, DestType=QualType @ 0x00007ffeefbf1948, Ctors=lookup_result @ 0x00007ffeefbf19a0, Best=0x00007ffeefbf1b80, CopyInitializing=true, AllowExplicit=false, OnlyListConstructors=false, IsListInit=false, SecondStepOfCopyInit=false) at SemaInit.cpp:3749
frame #&#8203;5436: 0x00000001159a2d61 libclangSema.dylib`TryConstructorInitialization(S=0x000000011d824000, Entity=0x00007ffeefbf3fd0, Kind=0x00007ffeefbf2448, Args=clang::MultiExprArg @ 0x00007ffeefbf1c48, DestType=QualType @ 0x00007ffeefbf1c40, DestArrayType=QualType @ 0x00007ffeefbf1c38, Sequence=0x00007ffeefbf2498, IsListInit=false, IsInitListCopy=false) at SemaInit.cpp:3912
frame #&#8203;5437: 0x000000011599f6de libclangSema.dylib`clang::InitializationSequence::InitializeFrom(this=0x00007ffeefbf2498, S=0x000000011d824000, Entity=0x00007ffeefbf3fd0, Kind=0x00007ffeefbf2448, Args=clang::MultiExprArg @ 0x00007ffeefbf21b0, TopLevelOfInitList=false, TreatUnavailableAsInvalid=true) at SemaInit.cpp:5609

[repeats starting here:]

frame #&#8203;5438: 0x000000011599e70a libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbf2498, S=0x000000011d824000, Entity=0x00007ffeefbf3fd0, Kind=0x00007ffeefbf2448, Args=clang::MultiExprArg @ 0x00007ffeefbf2260, TopLevelOfInitList=false, TreatUnavailableAsInvalid=true) at SemaInit.cpp:5323
frame #&#8203;5439: 0x000000011599ff0f libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbf2498, S=0x000000011d824000, Entity=0x00007ffeefbf3fd0, Kind=0x00007ffeefbf2448, Args=clang::MultiExprArg @ 0x00007ffeefbf2330, TopLevelOfInitList=false, TreatUnavailableAsInvalid=true) at SemaInit.cpp:5322
frame #&#8203;5440: 0x00000001159b30ac libclangSema.dylib`clang::Sema::PerformCopyInitialization(this=0x000000011d824000, Entity=0x00007ffeefbf3fd0, EqualLoc=(ID = 133), Init=(PtrWithInvalid = 4773125760), TopLevelOfInitList=false, AllowExplicit=false) at SemaInit.cpp:9140
frame #&#8203;5441: 0x0000000115b2b784 libclangSema.dylib`convertArgsForAvailabilityChecks(S=0x000000011d824000, Function=0x000000011c801be8, ThisArg=0x0000000000000000, Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbf4070, Trap=0x00007ffeefbf4258, MissingImplicitThis=true, ConvertedThis=0x00007ffeefbf41c0, ConvertedArgs=0x00007ffeefbf41c8) at SemaOverload.cpp:6321
frame #&#8203;5442: 0x0000000115b2aa9d libclangSema.dylib`clang::Sema::CheckEnableIf(this=0x000000011d824000, Function=0x000000011c801be8, Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbf42a0, MissingImplicitThis=false) at SemaOverload.cpp:6370
frame #&#8203;5443: 0x0000000115b2988f libclangSema.dylib`clang::Sema::AddOverloadCandidate(this=0x000000011d824000, Function=0x000000011c801be8, FoundDecl=(Ptr = 4773125096), Args=ArrayRef<clang::Expr *> @ 0x00007ffeefbf4670, CandidateSet=0x00007ffeefbf5c08, SuppressUserConversions=false, PartialOverloading=false, AllowExplicit=false, IsADLCandidate=NotADL, EarlyConversions=clang::ConversionSequenceList @ 0x00007ffeefbf46e0) at SemaOverload.cpp:6183
frame #&#8203;5444: 0x00000001159b8468 libclangSema.dylib`ResolveConstructorOverload(S=0x000000011d824000, DeclLoc=(ID = 131), Args=clang::MultiExprArg @ 0x00007ffeefbf4910, CandidateSet=0x00007ffeefbf5c08, DestType=QualType @ 0x00007ffeefbf4908, Ctors=lookup_result @ 0x00007ffeefbf4960, Best=0x00007ffeefbf4b40, CopyInitializing=false, AllowExplicit=true, OnlyListConstructors=false, IsListInit=false, SecondStepOfCopyInit=false) at SemaInit.cpp:3749
frame #&#8203;5445: 0x00000001159a2d61 libclangSema.dylib`TryConstructorInitialization(S=0x000000011d824000, Entity=0x00007ffeefbf58d0, Kind=0x00007ffeefbf58c0, Args=clang::MultiExprArg @ 0x00007ffeefbf4c08, DestType=QualType @ 0x00007ffeefbf4c00, DestArrayType=QualType @ 0x00007ffeefbf4bf8, Sequence=0x00007ffeefbf5b48, IsListInit=false, IsInitListCopy=false) at SemaInit.cpp:3912
frame #&#8203;5446: 0x000000011599f6de libclangSema.dylib`clang::InitializationSequence::InitializeFrom(this=0x00007ffeefbf5b48, S=0x000000011d824000, Entity=0x00007ffeefbf58d0, Kind=0x00007ffeefbf58c0, Args=clang::MultiExprArg @ 0x00007ffeefbf5170, TopLevelOfInitList=false, TreatUnavailableAsInvalid=false) at SemaInit.cpp:5609
frame #&#8203;5447: 0x000000011599e70a libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbf5b48, S=0x000000011d824000, Entity=0x00007ffeefbf58d0, Kind=0x00007ffeefbf58c0, Args=clang::MultiExprArg @ 0x00007ffeefbf5220, TopLevelOfInitList=false, TreatUnavailableAsInvalid=false) at SemaInit.cpp:5323
frame #&#8203;5448: 0x000000011599ff0f libclangSema.dylib`clang::InitializationSequence::InitializationSequence(this=0x00007ffeefbf5b48, S=0x000000011d824000, Entity=0x00007ffeefbf58d0, Kind=0x00007ffeefbf58c0, Args=clang::MultiExprArg @ 0x00007ffeefbf52f0, TopLevelOfInitList=false, TreatUnavailableAsInvalid=false) at SemaInit.cpp:5322
frame #&#8203;5449: 0x000000011531439e libclangSema.dylib`clang::Sema::AddInitializerToDecl(this=0x000000011d824000, RealDecl=0x000000011c801eb0, Init=0x000000011c801f10, DirectInit=true) at SemaDecl.cpp:11151
frame #&#8203;5450: 0x0000000114d5e6ff libclangParse.dylib`clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(this=0x000000011d82ae00, D=0x00007ffeefbf7f78, TemplateInfo=0x00007ffeefbf7d40, FRI=0x0000000000000000) at ParseDecl.cpp:2373
frame #&#8203;5451: 0x0000000114d5b820 libclangParse.dylib`clang::Parser::ParseDeclGroup(this=0x000000011d82ae00, DS=0x00007ffeefbf8790, Context=BlockContext, DeclEnd=0x00007ffeefbf8ea0, FRI=0x0000000000000000) at ParseDecl.cpp:2058
frame #&#8203;5452: 0x0000000114d56287 libclangParse.dylib`clang::Parser::ParseSimpleDeclaration(this=0x000000011d82ae00, Context=BlockContext, DeclEnd=0x00007ffeefbf8ea0, Attrs=0x00007ffeefbf9158, RequireSemi=true, FRI=0x0000000000000000) at ParseDecl.cpp:1783
frame #&#8203;5453: 0x0000000114d55d59 libclangParse.dylib`clang::Parser::ParseDeclaration(this=0x000000011d82ae00, Context=BlockContext, DeclEnd=0x00007ffeefbf8ea0, attrs=0x00007ffeefbf9158) at ParseDecl.cpp:1724
frame #&#8203;5454: 0x0000000114e33b9f libclangParse.dylib`clang::Parser::ParseStatementOrDeclarationAfterAttributes(this=0x000000011d82ae00, Stmts=0x00007ffeefbf94b0, Allowed=ACK_Any, TrailingElseLoc=0x0000000000000000, Attrs=0x00007ffeefbf9158) at ParseStmt.cpp:213
frame #&#8203;5455: 0x0000000114e332c0 libclangParse.dylib`clang::Parser::ParseStatementOrDeclaration(this=0x000000011d82ae00, Stmts=0x00007ffeefbf94b0, Allowed=ACK_Any, TrailingElseLoc=0x0000000000000000) at ParseStmt.cpp:109
frame #&#8203;5456: 0x0000000114e3bc42 libclangParse.dylib`clang::Parser::ParseCompoundStatementBody(this=0x000000011d82ae00, isStmtExpr=false) at ParseStmt.cpp:1037
frame #&#8203;5457: 0x0000000114e3cdeb libclangParse.dylib`clang::Parser::ParseFunctionStatementBody(this=0x000000011d82ae00, Decl=0x000000011c801da0, BodyScope=0x00007ffeefbf9920) at ParseStmt.cpp:2046
frame #&#8203;5458: 0x0000000114e66eef libclangParse.dylib`clang::Parser::ParseFunctionDefinition(this=0x000000011d82ae00, D=0x00007ffeefbf9ee8, TemplateInfo=0x00007ffeefbf9d80, LateParsedAttrs=0x00007ffeefbf9e88) at Parser.cpp:1245
frame #&#8203;5459: 0x0000000114d5b3fb libclangParse.dylib`clang::Parser::ParseDeclGroup(this=0x000000011d82ae00, DS=0x00007ffeefbfa800, Context=FileContext, DeclEnd=0x0000000000000000, FRI=0x0000000000000000) at ParseDecl.cpp:2000
frame #&#8203;5460: 0x0000000114e65d83 libclangParse.dylib`clang::Parser::ParseDeclOrFunctionDefInternal(this=0x000000011d82ae00, attrs=0x00007ffeefbfadb0, DS=0x00007ffeefbfa800, AS=AS_none) at Parser.cpp:1014
frame #&#8203;5461: 0x0000000114e65360 libclangParse.dylib`clang::Parser::ParseDeclarationOrFunctionDefinition(this=0x000000011d82ae00, attrs=0x00007ffeefbfadb0, DS=0x0000000000000000, AS=AS_none) at Parser.cpp:1030
frame #&#8203;5462: 0x0000000114e641aa libclangParse.dylib`clang::Parser::ParseExternalDeclaration(this=0x000000011d82ae00, attrs=0x00007ffeefbfadb0, DS=0x0000000000000000) at Parser.cpp:855
frame #&#8203;5463: 0x0000000114e62fb6 libclangParse.dylib`clang::Parser::ParseTopLevelDecl(this=0x000000011d82ae00, Result=0x00007ffeefbfaf00) at Parser.cpp:609
wheatman commented 1 year ago

reproduced on 9.0.1 with a stack dump crash

starting from 10.0.0 and going to trunk it still segfaults, but it does so after issuing the warning ":5:8: warning: stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely [-Wstack-exhausted]" which I assume is fine

https://godbolt.org/z/YPj7h4nbM

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-frontend

Endilll commented 1 year ago

Segfaulting without backtrace is not good, I think. CC @shafik @AaronBallman

AaronBallman commented 1 year ago

We issue a warning about the stack exhaustion: https://godbolt.org/z/s1Kx8n8oq

but yeah, this code should not cause an infinite loop.