[clang] [clang] Improve `_Alignas` on a `struct` declaration diagnostic (PR #65638)

Jerin Philip via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 7 09:51:38 PDT 2023


https://github.com/jerinphilip created https://github.com/llvm/llvm-project/pull/65638:

Fixes https://github.com/llvm/llvm-project/issues/58637. 

Additionally accounts for `_AlignAs` when constructing Attribute Form. This
breaks a few tests because `IsAlignAs` is coupled with `CXX11Attribute`.
Decoupling `isAlignas()` one level up gets the broken tests back functional.

Once an instance of `_AlignAs` existing in source is recorded properly, it is
possible to narrow the case at a later stage to stream in a solution.  

Based on https://reviews.llvm.org/D141177. 

>From 941af68ab8dad68ed8df65f6e0559476f137bfe2 Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Sat, 19 Aug 2023 16:43:53 +0530
Subject: [PATCH 1/6] Fix `Form` to recognize `_Alignas` in addition to
 `alignas`

---
 clang/include/clang/Basic/AttributeCommonInfo.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h
index e57adc4bf5b99a2..36f4eb885cf12f8 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -94,7 +94,7 @@ class AttributeCommonInfo {
           IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
     constexpr Form(tok::TokenKind Tok)
         : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
-          IsAlignas(Tok == tok::kw_alignas),
+          IsAlignas(Tok == tok::kw_alignas || Tok == tok::kw__Alignas),
           IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
 
     Syntax getSyntax() const { return Syntax(SyntaxUsed); }

>From 8c0bfe350dfa2d4d24988eb544f5c1a9eb1aec6d Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Thu, 7 Sep 2023 18:53:57 +0530
Subject: [PATCH 2/6] Avoid mixing `isCXX11Attribute` with `isAlignAs`

---
 clang/include/clang/Basic/AttributeCommonInfo.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h
index 36f4eb885cf12f8..669227589dfacd5 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -186,14 +186,14 @@ class AttributeCommonInfo {
   bool isGNUScope() const;
   bool isClangScope() const;
 
-  bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
+  bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11; }
 
   bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
 
   /// The attribute is spelled [[]] in either C or C++ mode, including standard
   /// attributes spelled with a keyword, like alignas.
   bool isStandardAttributeSyntax() const {
-    return isCXX11Attribute() || isC23Attribute();
+    return isCXX11Attribute() || isC23Attribute() || IsAlignas;
   }
 
   bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }

>From 8f699d5dfe62b2a1eb1f67f37ffa3d4ba1f2bfce Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Thu, 7 Sep 2023 19:15:03 +0530
Subject: [PATCH 3/6] Fix diagnostic warning post `isAlignAs` decoupling

---
 clang/include/clang/Basic/AttributeCommonInfo.h | 2 +-
 clang/lib/Parse/ParseDecl.cpp                   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h
index 669227589dfacd5..f1e3325d44f0e1a 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -186,8 +186,8 @@ class AttributeCommonInfo {
   bool isGNUScope() const;
   bool isClangScope() const;
 
+  bool isAlignas() const { return IsAlignas; }
   bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11; }
-
   bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
 
   /// The attribute is spelled [[]] in either C or C++ mode, including standard
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4a9f2caf654713e..f91141f7cd39cbf 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3405,8 +3405,8 @@ void Parser::ParseDeclarationSpecifiers(
       else {
         // Reject C++11 / C23 attributes that aren't type attributes.
         for (const ParsedAttr &PA : attrs) {
-          if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
-              !PA.isRegularKeywordAttribute())
+          if (!PA.isAlignas() && !PA.isCXX11Attribute() &&
+              !PA.isC23Attribute() && !PA.isRegularKeywordAttribute())
             continue;
           if (PA.getKind() == ParsedAttr::UnknownAttribute)
             // We will warn about the unknown attribute elsewhere (in

>From e7ddd755f1a873421809a05a4d5d999b7a15f62e Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Sat, 19 Aug 2023 16:44:51 +0530
Subject: [PATCH 4/6] Add attribute-ignored diagnostic warning variant

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ac4df8edb242f6..f76f872a98288f7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3491,10 +3491,14 @@ def err_attribute_invalid_on_decl : Error<
 def warn_type_attribute_deprecated_on_decl : Warning<
   "applying attribute %0 to a declaration is deprecated; apply it to the type instead">,
   InGroup<DeprecatedAttributes>;
-def warn_declspec_attribute_ignored : Warning<
+def warn_declspec_attribute_ignored_place_after : Warning<
   "attribute %0 is ignored, place it after "
   "\"%select{class|struct|interface|union|enum|enum class|enum struct}1\" to apply attribute to "
   "type declaration">, InGroup<IgnoredAttributes>;
+def warn_declspec_attribute_ignored : Warning<
+  "attribute %0 before "
+  "\"%select{class|struct|interface|union|enum|enum class|enum struct}1\" "
+  "is ignored">, InGroup<IgnoredAttributes>;
 def err_declspec_keyword_has_no_effect : Error<
   "%0 cannot appear here, place it after "
   "\"%select{class|struct|interface|union|enum}1\" to apply it to the "

>From ca03b9efbd0eaec1904656ce16f2d47915a26f17 Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Wed, 16 Aug 2023 16:09:52 +0530
Subject: [PATCH 5/6] Fix diagnostic emission for C Alignas

---
 clang/lib/Sema/SemaDecl.cpp | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d94366dac102a2a..97d74b413d3f911 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/Randstruct.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Basic/Builtins.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/HLSLRuntime.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -5339,16 +5340,23 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
         TypeSpecType == DeclSpec::TST_interface ||
         TypeSpecType == DeclSpec::TST_union ||
         TypeSpecType == DeclSpec::TST_enum) {
-      for (const ParsedAttr &AL : DS.getAttributes())
-        Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
-                              ? diag::err_declspec_keyword_has_no_effect
-                              : diag::warn_declspec_attribute_ignored)
-            << AL << GetDiagnosticTypeSpecifierID(DS);
-      for (const ParsedAttr &AL : DeclAttrs)
-        Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
-                              ? diag::err_declspec_keyword_has_no_effect
-                              : diag::warn_declspec_attribute_ignored)
-            << AL << GetDiagnosticTypeSpecifierID(DS);
+
+      auto EmitAttributeDiagnostic = [this, &DS](const ParsedAttr &AL) {
+        if (AL.isAlignas() && !getLangOpts().CPlusPlus) {
+          Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
+              << AL << GetDiagnosticTypeSpecifierID(DS);
+
+        } else {
+          Diag(AL.getLoc(),
+               AL.isRegularKeywordAttribute()
+                   ? diag::err_declspec_keyword_has_no_effect
+                   : diag::warn_declspec_attribute_ignored_place_after)
+              << AL << GetDiagnosticTypeSpecifierID(DS);
+        }
+      };
+
+      llvm::for_each(DS.getAttributes(), EmitAttributeDiagnostic);
+      llvm::for_each(DeclAttrs, EmitAttributeDiagnostic);
     }
   }
 

>From 1c1d4c60ee6cf4349b6ff0aa41a11603022aa425 Mon Sep 17 00:00:00 2001
From: Jerin Philip <jerinphilip at live.in>
Date: Thu, 7 Sep 2023 20:06:40 +0530
Subject: [PATCH 6/6] Fix test for C files

---
 clang/test/C/drs/dr4xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c
index b8ccceaad12c59f..0e25952be26f50d 100644
--- a/clang/test/C/drs/dr4xx.c
+++ b/clang/test/C/drs/dr4xx.c
@@ -168,7 +168,7 @@ void dr444(void) {
   * where the diagnostic recommends causes a different, more inscrutable error
   * about anonymous structures.
   */
-  _Alignas(int) struct T { /* expected-warning {{attribute '_Alignas' is ignored, place it after "struct" to apply attribute to type declaration}} */
+  _Alignas(int) struct T { /* expected-warning {{attribute '_Alignas' before "struct" is ignored}} */
     int i;
   };
 



More information about the cfe-commits mailing list