On Wed, Apr 29, 2015 at 1:58 PM, Aaron Ballman <[email protected]> wrote:
> 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? I think so, yes, unless there's a reason that's unworkable.
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
