<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 29, 2015 at 1:37 PM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, Apr 29, 2015 at 3:31 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> On Wed, Apr 29, 2015 at 11:04 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
> wrote:<br>
>><br>
>> On Wed, Apr 29, 2015 at 1:36 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>><br>
>> wrote:<br>
>> > Is the real problem that we're entering the lambda scope too early? The<br>
>> > scope shoudn't start until we get to the body -- things referenced from<br>
>> > within the parameter-declaration-clause of the inner lambda should not<br>
>> > be<br>
>> > captured by it, so the LSI->Lambda pointer for the inner lambda should<br>
>> > never<br>
>> > be referenced until we're ready to capture.<br>
>><br>
>> We're crashing on the following code:<br>
>><br>
>> template <int dimension><br>
>> class A;<br>
>><br>
>> int main ()<br>
>> {<br>
>>   const int dim = 3;<br>
>>   {<br>
>>     auto contraction = []() {<br>
>>       auto computeStrain = [](A<dim>& strain) {  };<br>
>>     };<br>
>>   }<br>
>> }<br>
>><br>
>> with a (partial) call stack of:<br>
>><br>
>>   clang.exe!clang::Sema::tryCaptureVariable(clang::VarDecl * Var,<br>
>> clang::SourceLocation ExprLoc, clang::Sema::TryCaptureKind Kind,<br>
>> clang::SourceLocation EllipsisLoc, bool BuildAndDiagnose,<br>
>> clang::QualType & CaptureType, clang::QualType & DeclRefType, const<br>
>> unsigned int * const FunctionScopeIndexToStopAt) Line 12883 C++<br>
>>   clang.exe!clang::MarkVarDeclODRUsed(clang::VarDecl * Var,<br>
>> clang::SourceLocation Loc, clang::Sema & SemaRef, const unsigned int *<br>
>> const FunctionScopeIndexToStopAt) Line 88 C++<br>
>>   clang.exe!clang::Sema::CleanupVarDeclMarking() Line 13047 C++<br>
>>   clang.exe!clang::Sema::PopExpressionEvaluationContext() Line 12009 C++<br>
>><br>
>> clang.exe!clang::EnterExpressionEvaluationContext::~EnterExpressionEvaluationContext()<br>
>> Line 8711 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseTemplateArgumentList(llvm::SmallVector<clang::ParsedTemplateArgument,16><br>
>> & TemplateArgs) Line 1252 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseTemplateIdAfterTemplateName(clang::OpaquePtr<clang::TemplateName><br>
>> Template, clang::SourceLocation TemplateNameLoc, const<br>
>> clang::CXXScopeSpec & SS, bool ConsumeLastToken, clang::SourceLocation<br>
>> & LAngleLoc, llvm::SmallVector<clang::ParsedTemplateArgument,16> &<br>
>> TemplateArgs, clang::SourceLocation & RAngleLoc) Line 876 C++<br>
>><br>
>> clang.exe!clang::Parser::AnnotateTemplateIdToken(clang::OpaquePtr<clang::TemplateName><br>
>> Template, clang::TemplateNameKind TNK, clang::CXXScopeSpec & SS,<br>
>> clang::SourceLocation TemplateKWLoc, clang::UnqualifiedId &<br>
>> TemplateName, bool AllowTypeAnnotation) Line 947 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseOptionalCXXScopeSpecifier(clang::CXXScopeSpec<br>
>> & SS, clang::OpaquePtr<clang::QualType> ObjectType, bool<br>
>> EnteringContext, bool * MayBePseudoDestructor, bool IsTypename,<br>
>> clang::IdentifierInfo * * LastII) Line 541 C++<br>
>>   clang.exe!clang::Parser::TryAnnotateCXXScopeToken(bool<br>
>> EnteringContext) Line 1691 C++<br>
>>   clang.exe!clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec<br>
>> & DS, const clang::Parser::ParsedTemplateInfo & TemplateInfo,<br>
>> clang::AccessSpecifier AS, clang::Parser::DeclSpecContext DSContext,<br>
>> clang::Parser::LateParsedAttrList * LateAttrs) Line 2898 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseParameterDeclarationClause(clang::Declarator<br>
>> & D, clang::ParsedAttributes & FirstArgAttrs,<br>
>> llvm::SmallVectorImpl<clang::DeclaratorChunk::ParamInfo> & ParamInfo,<br>
>> clang::SourceLocation & EllipsisLoc) Line 5652 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseLambdaExpressionAfterIntroducer(clang::LambdaIntroducer<br>
>> & Intro) Line 1086 C++<br>
>>   clang.exe!clang::Parser::ParseLambdaExpression() Line 729 C++<br>
>>   clang.exe!clang::Parser::ParseCastExpression(bool isUnaryExpression,<br>
>> bool isAddressOfOperand, bool & NotCastExpr,<br>
>> clang::Parser::TypeCastState isTypeCast) Line 1283 C++<br>
>>   clang.exe!clang::Parser::ParseCastExpression(bool isUnaryExpression,<br>
>> bool isAddressOfOperand, clang::Parser::TypeCastState isTypeCast) Line<br>
>> 441 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState<br>
>> isTypeCast) Line 170 C++<br>
>>   clang.exe!clang::Parser::ParseInitializer() Line 1522 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator<br>
>> & D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1998 C++<br>
>>   clang.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec & DS,<br>
>> unsigned int Context, clang::SourceLocation * DeclEnd,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1783 C++<br>
>>   clang.exe!clang::Parser::ParseSimpleDeclaration(unsigned int<br>
>> Context, clang::SourceLocation & DeclEnd,<br>
>> clang::Parser::ParsedAttributesWithRange & Attrs, bool RequireSemi,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1514 C++<br>
>>   clang.exe!clang::Parser::ParseDeclaration(unsigned int Context,<br>
>> clang::SourceLocation & DeclEnd,<br>
>> clang::Parser::ParsedAttributesWithRange & attrs) Line 1459 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc, clang::Parser::ParsedAttributesWithRange & Attrs)<br>
>> Line 212 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc) Line 110 C++<br>
>>   clang.exe!clang::Parser::ParseCompoundStatementBody(bool isStmtExpr)<br>
>> Line 958 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseLambdaExpressionAfterIntroducer(clang::LambdaIntroducer<br>
>> & Intro) Line 1249 C++<br>
>>   clang.exe!clang::Parser::ParseLambdaExpression() Line 729 C++<br>
>>   clang.exe!clang::Parser::ParseCastExpression(bool isUnaryExpression,<br>
>> bool isAddressOfOperand, bool & NotCastExpr,<br>
>> clang::Parser::TypeCastState isTypeCast) Line 1283 C++<br>
>>   clang.exe!clang::Parser::ParseCastExpression(bool isUnaryExpression,<br>
>> bool isAddressOfOperand, clang::Parser::TypeCastState isTypeCast) Line<br>
>> 441 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState<br>
>> isTypeCast) Line 170 C++<br>
>>   clang.exe!clang::Parser::ParseInitializer() Line 1522 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseDeclarationAfterDeclaratorAndAttributes(clang::Declarator<br>
>> & D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1998 C++<br>
>>   clang.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec & DS,<br>
>> unsigned int Context, clang::SourceLocation * DeclEnd,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1783 C++<br>
>>   clang.exe!clang::Parser::ParseSimpleDeclaration(unsigned int<br>
>> Context, clang::SourceLocation & DeclEnd,<br>
>> clang::Parser::ParsedAttributesWithRange & Attrs, bool RequireSemi,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1514 C++<br>
>>   clang.exe!clang::Parser::ParseDeclaration(unsigned int Context,<br>
>> clang::SourceLocation & DeclEnd,<br>
>> clang::Parser::ParsedAttributesWithRange & attrs) Line 1459 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc, clang::Parser::ParsedAttributesWithRange & Attrs)<br>
>> Line 212 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc) Line 110 C++<br>
>>   clang.exe!clang::Parser::ParseCompoundStatementBody(bool isStmtExpr)<br>
>> Line 958 C++<br>
>>   clang.exe!clang::Parser::ParseCompoundStatement(bool isStmtExpr,<br>
>> unsigned int ScopeFlags) Line 844 C++<br>
>>   clang.exe!clang::Parser::ParseCompoundStatement(bool isStmtExpr) Line<br>
>> 810 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc, clang::Parser::ParsedAttributesWithRange & Attrs)<br>
>> Line 229 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt<br>
>> *,32> & Stmts, bool OnlyStatement, clang::SourceLocation *<br>
>> TrailingElseLoc) Line 110 C++<br>
>>   clang.exe!clang::Parser::ParseCompoundStatementBody(bool isStmtExpr)<br>
>> Line 958 C++<br>
>>   clang.exe!clang::Parser::ParseFunctionStatementBody(clang::Decl *<br>
>> Decl, clang::Parser::ParseScope & BodyScope) Line 1876 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator<br>
>> & D, const clang::Parser::ParsedTemplateInfo & TemplateInfo,<br>
>> clang::Parser::LateParsedAttrList * LateParsedAttrs) Line 1104 C++<br>
>>   clang.exe!clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec & DS,<br>
>> unsigned int Context, clang::SourceLocation * DeclEnd,<br>
>> clang::Parser::ForRangeInit * FRI) Line 1729 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange<br>
>> & attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line<br>
>> 893 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange<br>
>> & attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line<br>
>> 909 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange<br>
>> & attrs, clang::ParsingDeclSpec * DS) Line 767 C++<br>
>><br>
>> clang.exe!clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef><br>
>> & Result) Line 569 C++<br>
>>   clang.exe!clang::ParseAST(clang::Sema & S, bool PrintStats, bool<br>
>> SkipFunctionBodies) Line 144 C++<br>
>><br>
>> So it looks like we're trying to do an implicit capture of the<br>
>> template argument "dim" within the parameter declaration, and<br>
>> attempting to diagnose the location using the lambda scope information<br>
>> (which is null, and winds up crashing).<br>
><br>
><br>
> Right, but there should not be any lambda scope information for the inner<br>
> lambda yet, because we have not yet entered its scope, right? Our current<br>
> lambda should still be the outer one.<br>
<br>
</div></div>We have entered its scope, but we've not generated any useful scope<br>
information. See ParseLambaExpressionAfterIntroducer, around line<br>
1062, that's where we push the lambda scope onto the stack. So we're<br>
definitely not pushing that scope when we hit the body. If I move it<br>
down to where we act on the start of the lambda definition itself (for<br>
parsing the body), I get a lot of llvm_unreachables from<br>
RecordParsingTemplateParameterDepth being called in<br>
ParseLambaExpressionAfterIntroducer.</blockquote><div><br></div><div>I'm not surprised that there's code that relies on us getting this wrong =) </div></div></div></div>