[clang] 789a7aa - Properly disambiguate between array declarators and array subscript expressions.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 27 17:55:16 PST 2019
Author: Richard Smith
Date: 2019-11-27T17:54:26-08:00
New Revision: 789a7aa37d0cca70d6e48908ce3e8bb4e761e266
URL: https://github.com/llvm/llvm-project/commit/789a7aa37d0cca70d6e48908ce3e8bb4e761e266
DIFF: https://github.com/llvm/llvm-project/commit/789a7aa37d0cca70d6e48908ce3e8bb4e761e266.diff
LOG: Properly disambiguate between array declarators and array subscript expressions.
Added:
Modified:
clang/lib/Parse/ParseTentative.cpp
clang/test/Parser/cxx-ambig-decl-expr.cpp
Removed:
################################################################################
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index e2e16ca63d1e..9cc41328c469 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -2066,9 +2066,21 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
///
Parser::TPResult Parser::TryParseBracketDeclarator() {
ConsumeBracket();
- if (!SkipUntil(tok::r_square, StopAtSemi))
+
+ // A constant-expression cannot begin with a '{', but the
+ // expr-or-braced-init-list of a postfix-expression can.
+ if (Tok.is(tok::l_brace))
+ return TPResult::False;
+
+ if (!SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch))
return TPResult::Error;
+ // If we hit a comma before the ']', this is not a constant-expression,
+ // but might still be the expr-or-braced-init-list of a postfix-expression.
+ if (Tok.isNot(tok::r_square))
+ return TPResult::False;
+
+ ConsumeBracket();
return TPResult::Ambiguous;
}
diff --git a/clang/test/Parser/cxx-ambig-decl-expr.cpp b/clang/test/Parser/cxx-ambig-decl-expr.cpp
index 6507eafb74cd..02857e21f7c3 100644
--- a/clang/test/Parser/cxx-ambig-decl-expr.cpp
+++ b/clang/test/Parser/cxx-ambig-decl-expr.cpp
@@ -17,3 +17,25 @@ auto (*q)() -> int(*)(unknown); // expected-error {{unknown type name 'unknown'}
auto (*r)() -> int(*)(unknown + 1); // expected-error {{undeclared identifier 'unknown'}}
int f(unknown const x); // expected-error {{unknown type name 'unknown'}}
+
+// Disambiguating an array declarator from an array subscripting.
+void arr() {
+ int x[] = {1}; // expected-note 2{{previous}}
+
+ // This is array indexing not an array declarator because a comma expression
+ // is not syntactically a constant-expression.
+ int(x[1,1]); // expected-warning 2{{unused}}
+
+ // This is array indexing not an array declaration because a braced-init-list
+ // is not syntactically a constant-expression.
+ int(x[{0}]); // expected-error {{array subscript is not an integer}}
+ struct A {
+ struct Q { int n; };
+ int operator[](Q);
+ } a;
+ int(a[{0}]); // expected-warning {{unused}}
+
+ // These are array declarations.
+ int(x[(1,1)]); // expected-error {{redefinition}}
+ int(x[true ? 1,1 : 1]); // expected-error {{redefinition}}
+}
More information about the cfe-commits
mailing list