ebevhan added a comment.

We found an odd case in our downstream fork after this patch landed. We have a 
diagnostic in `CheckVariableDeclarationType` that checks for automatic 
variables that are too large for the stack address space, and it chokes on the 
testcase `Parser/objcxx11-invalid-lambda.cpp`:

  void foo() {  // expected-note {{to match this '{'}}
    int bar;
    auto baz = [
        bar(  // expected-note {{to match this '('}} expected-note {{to match 
this '('}}
          foo_undeclared() // expected-error{{use of undeclared identifier 
'foo_undeclared'}}
        /* ) */
      ] () { };   // expected-error{{expected ')'}}
  }               // expected-error{{expected ')'}} expected-error {{expected 
',' or ']'}} expected-error{{expected ';' at end of declaration}} 
expected-error{{expected '}'}}

When the lambda is parsed, the parsing of the initializer expression of the 
'bar' capture fails since the paren is unbalanced, so it will build:

  ParenListExpr 0xc592ce8 'NULL TYPE' contains-errors
  `-RecoveryExpr 0xc592cc0 '<dependent type>' contains-errors lvalue
    `-UnresolvedLookupExpr 0xc592c38 '<overloaded function type>' lvalue (ADL) 
= 'foo_undeclared' empty

Then, when building the lambda closure type, it will be given an auto member 
for `bar` with its type deduced to `AutoType 0xc592d40 'auto' dependent`:

  CXXRecordDecl 0xdfeb798 <...> col:14 implicit class definition
  |-DefinitionData lambda pass_in_registers standard_layout trivially_copyable 
can_const_default_init
  | |-DefaultConstructor
  | |-CopyConstructor simple trivial has_const_param needs_implicit 
implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment trivial has_const_param needs_implicit 
implicit_has_const_param
  | |-MoveAssignment
  | `-Destructor simple irrelevant trivial
  |-CXXMethodDecl 0xdfeb8d0 <line:10:8, col:12> line:5:14 operator() 'void () 
const' inline
  | `-CompoundStmt 0xdfeba20 <line:10:10, col:12>
  |-FieldDecl 0xdfeba58 <line:6:7> col:7 implicit 'auto'
  `-CXXDestructorDecl 0xdfebb08 <line:5:14> col:14 implicit referenced ~ 'void 
() noexcept' inline default trivial

However, this just means that `baz` has a very odd type; it's a variable of 
closure type that contains a dependent member that will never be resolved. Our 
diagnostic breaks, since the variable's type isn't dependent, but it has a 
member which is, and we can't take the size of that.

Is the lambda parser really supposed to build this kind of odd type when faced 
with RecoveryExpr?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76696/new/

https://reviews.llvm.org/D76696



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to