Skip to content

Commit 4bd81c5

Browse files
[Clang] Fix eager skipping in ParseExpressionList() (llvm#110133)
i.e., in a call like `function(new Unknown);` the parser should skip only until the semicolon. Before this change, everything was skipped until a balanced closing parenthesis or brace was found. This strategy can cause completely bogus ASTs. For instance, in the case of the test `new-unknown-type.cpp`, `struct Bar` would end nested under the namespace `a::b`.
1 parent b38b34c commit 4bd81c5

File tree

4 files changed

+27
-3
lines changed

4 files changed

+27
-3
lines changed

clang/lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3694,7 +3694,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
36943694
SawError = true;
36953695
if (FailImmediatelyOnInvalidExpr)
36963696
break;
3697-
SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
3697+
SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
36983698
} else {
36993699
Exprs.push_back(Expr.get());
37003700
}

clang/test/AST/new-unknown-type.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -verify -ast-dump %s | FileCheck %s
2+
3+
extern void foo(Unknown*); // expected-error {{unknown type name 'Unknown'}}
4+
5+
namespace a {
6+
void computeSomething() {
7+
foo(new Unknown()); // expected-error {{unknown type name 'Unknown'}}
8+
foo(new Unknown{}); // expected-error {{unknown type name 'Unknown'}}
9+
foo(new Unknown); // expected-error {{unknown type name 'Unknown'}}
10+
}
11+
} // namespace a
12+
13+
namespace b {
14+
struct Bar{};
15+
} // namespace b
16+
17+
// CHECK: |-NamespaceDecl 0x{{[^ ]*}} <line:5:1, line:11:1> line:5:11 a
18+
// CHECK-NEXT: | `-FunctionDecl 0x{{[^ ]*}} <line:6:3, line:10:3> line:6:8 computeSomething 'void ()'
19+
// CHECK-NEXT: | `-CompoundStmt 0x{{[^ ]*}} <col:27, line:10:3>
20+
// CHECK-NEXT: |-NamespaceDecl 0x{{[^ ]*}} <line:13:1, line:15:1> line:13:11 b
21+
// CHECK-NEXT: | `-CXXRecordDecl 0x{{[^ ]*}} <line:14:3, col:14> col:10 referenced struct Bar definition
22+
23+
static b::Bar bar;
24+
// CHECK: `-VarDecl 0x{{[^ ]*}} <line:23:1, col:15> col:15 bar 'b::Bar' static callinit
25+
// CHECK-NEXT: `-CXXConstructExpr 0x{{[^ ]*}} <col:15> 'b::Bar' 'void () noexcept'

clang/test/Parser/colon-colon-parentheses.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ int S::(*e; // expected-error{{expected unqualified-id}}
1111
int S::*f;
1212
int g = S::(a); // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'a'}}
1313
int h = S::(b; // expected-error {{expected unqualified-id}} expected-error {{use of undeclared identifier 'b'}}
14-
);
14+
); // expected-error {{expected unqualified-id}}
1515
int i = S::c;
1616

1717
void foo() {

clang/test/Parser/cxx-ambig-paren-expr-asan.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@ int H((int()[)]);
66
// expected-error@-1 {{expected expression}}
77
// expected-error@-2 {{expected ']'}}
88
// expected-note@-3 {{to match this '['}}
9-
// expected-error@-4 {{expected ';' after top level declarator}}

0 commit comments

Comments
 (0)