<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 29, 2015 at 11:04 AM, 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"><span class="">On Wed, Apr 29, 2015 at 1:36 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> 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 be<br>
> captured by it, so the LSI->Lambda pointer for the inner lambda should never<br>
> be referenced until we're ready to capture.<br>
<br>
</span>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>
  clang.exe!clang::EnterExpressionEvaluationContext::~EnterExpressionEvaluationContext()<br>
Line 8711 C++<br>
  clang.exe!clang::Parser::ParseTemplateArgumentList(llvm::SmallVector<clang::ParsedTemplateArgument,16><br>
& TemplateArgs) Line 1252 C++<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>
  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>
  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>
  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>
  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>
  clang.exe!clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState<br>
isTypeCast) Line 170 C++<br>
  clang.exe!clang::Parser::ParseInitializer() Line 1522 C++<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>
  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>
  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::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>
  clang.exe!clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState<br>
isTypeCast) Line 170 C++<br>
  clang.exe!clang::Parser::ParseInitializer() Line 1522 C++<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>
  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>
  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 810 C++<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>
  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>
  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>
  clang.exe!clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange<br>
& attrs, clang::ParsingDeclSpec & DS, clang::AccessSpecifier AS) Line<br>
893 C++<br>
  clang.exe!clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange<br>
& attrs, clang::ParsingDeclSpec * DS, clang::AccessSpecifier AS) Line<br>
909 C++<br>
  clang.exe!clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange<br>
& attrs, clang::ParsingDeclSpec * DS) Line 767 C++<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).</blockquote><div><br></div><div>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.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
><br>
> On Wed, Apr 29, 2015 at 10:09 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
> wrote:<br>
>><br>
>> Ping<br>
>><br>
>> On Thu, Apr 23, 2015 at 11:31 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
>> wrote:<br>
>> > Ping<br>
>> ><br>
>> > On Fri, Apr 10, 2015 at 10:08 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
>> > wrote:<br>
>> >> PR23021 demonstrates a case where diagnostic reporting on an inner<br>
>> >> lambda would crash due to a null pointer dereference. Since captures<br>
>> >> happen from calling ParseParameterDeclarationClause, which is before<br>
>> >> the semantic lambda object is created, another mechanism is required<br>
>> >> to get the lambda introducer location.<br>
>> >><br>
>> >> This patch addresses it by storing the introducer location into the<br>
>> >> scope object directly, and using that location when reporting the<br>
>> >> diagnostics. The result is the same, but no longer relies on a lambda<br>
>> >> object being created first.<br>
>> >><br>
>> >> ~Aaron<br>
><br>
><br>
</div></div></blockquote></div><br></div></div>