[clang] [Clang] allow GNU attrs before bit-field width in member declarators (PR #185322)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 8 14:32:33 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Oleksandr Tarasiuk (a-tarasyuk)
<details>
<summary>Changes</summary>
Fixes #<!-- -->184954
---
This PR fixes the parsing of member bit-field declarators by allowing GNU attributes between the declarator and the bit-field width.
```cpp
struct S {
int x __attribute__((packed)) : 4;
};
```
---
Full diff: https://github.com/llvm/llvm-project/pull/185322.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+5-1)
- (modified) clang/test/Parser/cxx-attributes.cpp (+7)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5d07bfc210e05..d1583f9f89ac0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -207,6 +207,8 @@ Attribute Changes in Clang
type-level control over overflow behavior. There is also an accompanying type
specifier for each behavior kind via `__ob_wrap` and `__ob_trap`.
+- Clang now allows GNU attributes between a member declarator and bit-field width. (#GH184954)
+
Improvements to Clang's diagnostics
-----------------------------------
- Added ``-Wlifetime-safety`` to enable lifetime safety analysis,
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 274c354d59808..8c324e0768c71 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2512,11 +2512,15 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
else
DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
+ const bool IsFunctionDeclarator = DeclaratorInfo.isFunctionDeclarator();
+ if (!IsFunctionDeclarator)
+ MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
+
if (getLangOpts().HLSL)
MaybeParseHLSLAnnotations(DeclaratorInfo, nullptr,
/*CouldBeBitField*/ true);
- if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
+ if (!IsFunctionDeclarator && TryConsumeToken(tok::colon)) {
assert(DeclaratorInfo.isPastIdentifier() &&
"don't know where identifier would go yet?");
BitfieldSize = ParseConstantExpression();
diff --git a/clang/test/Parser/cxx-attributes.cpp b/clang/test/Parser/cxx-attributes.cpp
index cd09f8d11f1a6..d108535ea9b98 100644
--- a/clang/test/Parser/cxx-attributes.cpp
+++ b/clang/test/Parser/cxx-attributes.cpp
@@ -41,6 +41,13 @@ void fn() {
pi = &i[0];
}
+namespace GH184954 {
+ struct S {
+ int a __attribute__((packed)) : 4;
+ int b __attribute__((aligned(16))) : 4;
+ };
+}
+
[[deprecated([""])]] int WrongArgs; // expected-error {{expected string literal as argument of 'deprecated' attribute}}
[[,,,,,]] int Commas1; // ok
[[,, maybe_unused]] int Commas2; // ok
``````````
</details>
https://github.com/llvm/llvm-project/pull/185322
More information about the cfe-commits
mailing list