[PATCH] D76696: [AST] Build recovery expressions by default for C++.
Bevin Hansson via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 26 07:33:40 PDT 2020
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
More information about the cfe-commits
mailing list