aaron.ballman created this revision.
aaron.ballman added reviewers: hubert.reinterpretcast, rsmith.
aaron.ballman requested review of this revision.

The C++ grammar allows you to specify an attribute list on an anonymous 
bit-field, but we were not properly parsing that case. This would lead to a 
rejects-valid diagnostic with code like:

  struct A {
    int x, [[]] : 0;
  };

This patch addresses it by optionally parsing an attribute specifier in the 
case the identifier is elided.


https://reviews.llvm.org/D88333

Files:
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/test/CXX/class/class.bit/p1.cpp


Index: clang/test/CXX/class/class.bit/p1.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class/class.bit/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+constexpr int foo() { return 1; }
+
+struct A {
+  int a [[]] : 1;
+  int x, [[]] : 0;
+  int [[]] : 0;
+  int b [[]] : 1 = 1;
+  int c [[]] : 1 {1};
+  int d : foo() = foo();
+};
+
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2308,11 +2308,13 @@
   //   declarator pure-specifier[opt]
   //   declarator requires-clause
   //   declarator brace-or-equal-initializer[opt]
-  //   identifier[opt] ':' constant-expression
-  if (Tok.isNot(tok::colon))
+  //   identifier[opt] attribute-specifier-seq[opt] ':' constant-expression
+  if (Tok.isNot(tok::colon) && !isCXX11AttributeSpecifier())
     ParseDeclarator(DeclaratorInfo);
-  else
+  else {
     DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
+    MaybeParseCXX11Attributes(DeclaratorInfo);
+  }
 
   if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
     assert(DeclaratorInfo.isPastIdentifier() &&


Index: clang/test/CXX/class/class.bit/p1.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class/class.bit/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+constexpr int foo() { return 1; }
+
+struct A {
+  int a [[]] : 1;
+  int x, [[]] : 0;
+  int [[]] : 0;
+  int b [[]] : 1 = 1;
+  int c [[]] : 1 {1};
+  int d : foo() = foo();
+};
+
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2308,11 +2308,13 @@
   //   declarator pure-specifier[opt]
   //   declarator requires-clause
   //   declarator brace-or-equal-initializer[opt]
-  //   identifier[opt] ':' constant-expression
-  if (Tok.isNot(tok::colon))
+  //   identifier[opt] attribute-specifier-seq[opt] ':' constant-expression
+  if (Tok.isNot(tok::colon) && !isCXX11AttributeSpecifier())
     ParseDeclarator(DeclaratorInfo);
-  else
+  else {
     DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
+    MaybeParseCXX11Attributes(DeclaratorInfo);
+  }
 
   if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
     assert(DeclaratorInfo.isPastIdentifier() &&
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D88333: C... Aaron Ballman via Phabricator via cfe-commits

Reply via email to