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