eandrews updated this revision to Diff 527406.
eandrews added a comment.

Thanks for the review! I've added a release note.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151837/new/

https://reviews.llvm.org/D151837

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/Parser/attr-order.cpp


Index: clang/test/Parser/attr-order.cpp
===================================================================
--- clang/test/Parser/attr-order.cpp
+++ clang/test/Parser/attr-order.cpp
@@ -13,12 +13,21 @@
 [[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void b(); // ok
 [[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void c(); // ok
 
-// [[]] attributes before a declaration must be at the start of the line.
 __declspec(dllexport) [[noreturn]] __attribute__((cdecl)) void d(); // 
expected-error {{an attribute list cannot appear here}}
 __declspec(dllexport) __attribute__((cdecl)) [[noreturn]] void e(); // 
expected-error {{an attribute list cannot appear here}}
 __attribute__((cdecl)) __declspec(dllexport) [[noreturn]] void f(); // 
expected-error {{an attribute list cannot appear here}}
-__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g();
+
+__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); // ok
 
 [[noreturn]] __attribute__((cdecl))
 [[]]
 __declspec(dllexport) void h();
+
+template <int a>
+__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void i(); // ok
+
+template <int a>
+[[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void j(); // ok
+
+template <int a>
+[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok
Index: clang/lib/Parse/ParseTemplate.cpp
===================================================================
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -210,7 +210,15 @@
   }
 
   ParsedAttributes prefixAttrs(AttrFactory);
-  MaybeParseCXX11Attributes(prefixAttrs);
+  ParsedAttributes DeclSpecAttrs(AttrFactory);
+
+  // GNU attributes are applied to the declaration specification while the
+  // standard attributes are applied to the declaration.  We parse the two
+  // attribute sets into different containters so we can apply them during
+  // the regular parsing process.
+  while (MaybeParseCXX11Attributes(prefixAttrs) ||
+         MaybeParseGNUAttributes(DeclSpecAttrs))
+    ;
 
   if (Tok.is(tok::kw_using)) {
     auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, 
TemplateInfo, DeclEnd,
@@ -223,6 +231,9 @@
   // Parse the declaration specifiers, stealing any diagnostics from
   // the template parameters.
   ParsingDeclSpec DS(*this, &DiagsFromTParams);
+  DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
+  DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
+  DS.takeAttributesFrom(DeclSpecAttrs);
 
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
                              getDeclSpecContextFromDeclaratorContext(Context));
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -411,6 +411,9 @@
   structs, unions, and scoped enums) were not properly ignored, resulting in
   misleading warning messages. Now, such attribute annotations are correctly
   ignored. (`#61660 <https://github.com/llvm/llvm-project/issues/61660>`_)
+- GNU attributes preceding C++ style attributes on templates were not properly
+  handled, resulting in compilation error. This has been corrected to match the
+  behaviour exhibited by GCC.
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^


Index: clang/test/Parser/attr-order.cpp
===================================================================
--- clang/test/Parser/attr-order.cpp
+++ clang/test/Parser/attr-order.cpp
@@ -13,12 +13,21 @@
 [[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void b(); // ok
 [[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void c(); // ok
 
-// [[]] attributes before a declaration must be at the start of the line.
 __declspec(dllexport) [[noreturn]] __attribute__((cdecl)) void d(); // expected-error {{an attribute list cannot appear here}}
 __declspec(dllexport) __attribute__((cdecl)) [[noreturn]] void e(); // expected-error {{an attribute list cannot appear here}}
 __attribute__((cdecl)) __declspec(dllexport) [[noreturn]] void f(); // expected-error {{an attribute list cannot appear here}}
-__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g();
+
+__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); // ok
 
 [[noreturn]] __attribute__((cdecl))
 [[]]
 __declspec(dllexport) void h();
+
+template <int a>
+__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void i(); // ok
+
+template <int a>
+[[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void j(); // ok
+
+template <int a>
+[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok
Index: clang/lib/Parse/ParseTemplate.cpp
===================================================================
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -210,7 +210,15 @@
   }
 
   ParsedAttributes prefixAttrs(AttrFactory);
-  MaybeParseCXX11Attributes(prefixAttrs);
+  ParsedAttributes DeclSpecAttrs(AttrFactory);
+
+  // GNU attributes are applied to the declaration specification while the
+  // standard attributes are applied to the declaration.  We parse the two
+  // attribute sets into different containters so we can apply them during
+  // the regular parsing process.
+  while (MaybeParseCXX11Attributes(prefixAttrs) ||
+         MaybeParseGNUAttributes(DeclSpecAttrs))
+    ;
 
   if (Tok.is(tok::kw_using)) {
     auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
@@ -223,6 +231,9 @@
   // Parse the declaration specifiers, stealing any diagnostics from
   // the template parameters.
   ParsingDeclSpec DS(*this, &DiagsFromTParams);
+  DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
+  DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
+  DS.takeAttributesFrom(DeclSpecAttrs);
 
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
                              getDeclSpecContextFromDeclaratorContext(Context));
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -411,6 +411,9 @@
   structs, unions, and scoped enums) were not properly ignored, resulting in
   misleading warning messages. Now, such attribute annotations are correctly
   ignored. (`#61660 <https://github.com/llvm/llvm-project/issues/61660>`_)
+- GNU attributes preceding C++ style attributes on templates were not properly
+  handled, resulting in compilation error. This has been corrected to match the
+  behaviour exhibited by GCC.
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to