Skip to content

Commit 6cbd96e

Browse files
authored
[Clang] handle both gnu and cpp11 attributes to ensure correct parsing inside extern block (#102864)
Fixes #101990
1 parent 7ab2d50 commit 6cbd96e

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ Bug Fixes to C++ Support
257257
- Properly reject defaulted relational operators with invalid types for explicit object parameters,
258258
e.g., ``bool operator==(this int, const Foo&)`` (#GH100329), and rvalue reference parameters.
259259
- Properly reject defaulted copy/move assignment operators that have a non-reference explicit object parameter.
260+
- Clang now properly handles the order of attributes in `extern` blocks. (#GH101990).
260261
- Fixed an assertion failure by preventing null explicit object arguments from being deduced. (#GH102025).
261262

262263
Bug Fixes to AST Handling

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,10 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
425425
[[fallthrough]];
426426
default:
427427
ParsedAttributes DeclAttrs(AttrFactory);
428-
MaybeParseCXX11Attributes(DeclAttrs);
428+
ParsedAttributes DeclSpecAttrs(AttrFactory);
429+
while (MaybeParseCXX11Attributes(DeclAttrs) ||
430+
MaybeParseGNUAttributes(DeclSpecAttrs))
431+
;
429432
ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
430433
continue;
431434
}

clang/test/Parser/attr-order.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,16 @@ template <int a>
3131

3232
template <int a>
3333
[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok
34+
35+
extern "C" {
36+
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int l(int); // ok
37+
[[__maybe_unused__]] __attribute__ ((__warn_unused_result__)) int m(int); // ok
38+
}
39+
40+
extern "C" {
41+
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int n (int); // ok
42+
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] static int o (int x) { return x; }; // ok
43+
}
44+
45+
extern "C" __attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int p(int); // ok
46+
extern "C" [[__maybe_unused__]] __attribute__ ((__warn_unused_result__)) int q(int); // ok

0 commit comments

Comments
 (0)