Author: ipriyanshi1708
Date: 2023-04-26T15:18:40-04:00
New Revision: b893368fd4fdf40b7778df8d0b17312def1a8156

URL: 
https://github.com/llvm/llvm-project/commit/b893368fd4fdf40b7778df8d0b17312def1a8156
DIFF: 
https://github.com/llvm/llvm-project/commit/b893368fd4fdf40b7778df8d0b17312def1a8156.diff

LOG: Fix the diagnostic about attribute placement for scoped enumerations

Fixed the error message for attribute placement. Earlier it was showing
'place it after "enum"' but it should be 'place it after "enum class"'
which I have fixed in this patch.

Fixes https://github.com/llvm/llvm-project/issues/61660
Differential Revision: https://reviews.llvm.org/D147989

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaDecl.cpp
    clang/test/SemaCXX/attr-declspec-ignored.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7dfca82c00876..8606f1478a00c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -331,6 +331,8 @@ Bug Fixes to Compiler Builtins
 
 Bug Fixes to Attribute Support
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed a bug where attribute annotations on type specifiers (enums, classes, 
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>`_)
 
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 18a0154b00411..9080d07fe19cf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2666,7 +2666,7 @@ def err_invalid_constexpr : Error<
 def err_invalid_constexpr_member : Error<"non-static data member cannot be "
   "constexpr%select{; did you intend to make it %select{const|static}0?|}1">;
 def err_constexpr_tag : Error<
-  "%select{class|struct|interface|union|enum}0 "
+  "%select{class|struct|interface|union|enum|enum class|enum struct}0 "
   "cannot be marked %sub{select_constexpr_spec_kind}1">;
 def err_constexpr_dtor : Error<
   "destructor cannot be declared %sub{select_constexpr_spec_kind}0">;
@@ -3423,7 +3423,7 @@ def warn_type_attribute_deprecated_on_decl : Warning<
   InGroup<DeprecatedAttributes>;
 def warn_declspec_attribute_ignored : Warning<
   "attribute %0 is ignored, place it after "
-  "\"%select{class|struct|interface|union|enum}1\" to apply attribute to "
+  "\"%select{class|struct|interface|union|enum|enum class|enum struct}1\" to 
apply attribute to "
   "type declaration">, InGroup<IgnoredAttributes>;
 def warn_attribute_precede_definition : Warning<
   "attribute declaration must precede definition">,
@@ -6928,7 +6928,7 @@ def warn_standalone_specifier : Warning<"'%0' ignored on 
this declaration">,
 def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration 
"
   "of a type">, InGroup<MissingDeclarations>;
 def err_standalone_class_nested_name_specifier : Error<
-  "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
+  "forward declaration of %select{class|struct|interface|union|enum|enum 
class|enum struct}0 cannot "
   "have a nested name specifier">;
 def err_typecheck_sclass_func : Error<"illegal storage class on function">;
 def err_static_block_func : Error<

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 719215d3f38c4..4cdf2982b99d5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5033,7 +5033,8 @@ void Sema::setTagNameForLinkagePurposes(TagDecl 
*TagFromDeclSpec,
   TagFromDeclSpec->setTypedefNameForAnonDecl(NewTD);
 }
 
-static unsigned GetDiagnosticTypeSpecifierID(DeclSpec::TST T) {
+static unsigned GetDiagnosticTypeSpecifierID(const DeclSpec &DS) {
+  DeclSpec::TST T = DS.getTypeSpecType();
   switch (T) {
   case DeclSpec::TST_class:
     return 0;
@@ -5044,12 +5045,17 @@ static unsigned 
GetDiagnosticTypeSpecifierID(DeclSpec::TST T) {
   case DeclSpec::TST_union:
     return 3;
   case DeclSpec::TST_enum:
+    if (const auto *ED = dyn_cast<EnumDecl>(DS.getRepAsDecl())) {
+      if (ED->isScopedUsingClassTag())
+        return 5;
+      if (ED->isScoped())
+        return 6;
+    }
     return 4;
   default:
     llvm_unreachable("unexpected type specifier");
   }
 }
-
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
 /// no declarator (e.g. "struct foo;") is parsed. It also accepts template
 /// parameters to cope with template friend declarations.
@@ -5107,7 +5113,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, 
AccessSpecifier AS,
     // the declaration of a function or function template
     if (Tag)
       Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_tag)
-          << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType())
+          << GetDiagnosticTypeSpecifierID(DS)
           << static_cast<int>(DS.getConstexprSpecifier());
     else
       Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_wrong_decl_kind)
@@ -5141,7 +5147,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, 
AccessSpecifier AS,
     //
     // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either.
     Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier)
-        << GetDiagnosticTypeSpecifierID(DS.getTypeSpecType()) << SS.getRange();
+        << GetDiagnosticTypeSpecifierID(DS) << SS.getRange();
     return nullptr;
   }
 
@@ -5306,10 +5312,10 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, 
AccessSpecifier AS,
         TypeSpecType == DeclSpec::TST_enum) {
       for (const ParsedAttr &AL : DS.getAttributes())
         Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
-            << AL << GetDiagnosticTypeSpecifierID(TypeSpecType);
+            << AL << GetDiagnosticTypeSpecifierID(DS);
       for (const ParsedAttr &AL : DeclAttrs)
         Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored)
-            << AL << GetDiagnosticTypeSpecifierID(TypeSpecType);
+            << AL << GetDiagnosticTypeSpecifierID(DS);
     }
   }
 

diff  --git a/clang/test/SemaCXX/attr-declspec-ignored.cpp 
b/clang/test/SemaCXX/attr-declspec-ignored.cpp
index f46e3910c56d7..dfea8cc4d47c8 100644
--- a/clang/test/SemaCXX/attr-declspec-ignored.cpp
+++ b/clang/test/SemaCXX/attr-declspec-ignored.cpp
@@ -9,6 +9,10 @@ namespace test1 {
   // expected-warning{{attribute 'aligned' is ignored, place it after "union" 
to apply attribute to type declaration}}
   __attribute__((visibility("hidden")))  __attribute__((aligned)) enum D {D}; 
// expected-warning{{attribute 'visibility' is ignored, place it after "enum" 
to apply attribute to type declaration}} \
   // expected-warning{{attribute 'aligned' is ignored, place it after "enum" 
to apply attribute to type declaration}}
+  __attribute__((visibility("hidden")))  __attribute__((aligned)) enum class 
EC {}; // expected-warning{{attribute 'visibility' is ignored, place it after 
"enum class" to apply attribute to type declaration}} \
+  // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
class" to apply attribute to type declaration}}
+  __attribute__((visibility("hidden")))  __attribute__((aligned)) enum struct 
ES {}; // expected-warning{{attribute 'visibility' is ignored, place it after 
"enum struct" to apply attribute to type declaration}} \
+  // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
struct" to apply attribute to type declaration}}
 
   // Test that we get the same warnings for type declarations nested in a 
record.
   struct X {
@@ -20,7 +24,11 @@ namespace test1 {
     // expected-warning{{attribute 'aligned' is ignored, place it after 
"union" to apply attribute to type declaration}}
     __attribute__((visibility("hidden")))  __attribute__((aligned)) enum D 
{D}; // expected-warning{{attribute 'visibility' is ignored, place it after 
"enum" to apply attribute to type declaration}} \
     // expected-warning{{attribute 'aligned' is ignored, place it after "enum" 
to apply attribute to type declaration}}
-
+    __attribute__((visibility("hidden")))  __attribute__((aligned)) enum class 
EC {}; // expected-warning{{attribute 'visibility' is ignored, place it after 
"enum class" to apply attribute to type declaration}} \
+    // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
class" to apply attribute to type declaration}}
+    __attribute__((visibility("hidden")))  __attribute__((aligned)) enum 
struct ES {}; // expected-warning{{attribute 'visibility' is ignored, place it 
after "enum struct" to apply attribute to type declaration}} \
+    // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
struct" to apply attribute to type declaration}}
+  
     // Also test [[]] attribute syntax. (On a non-nested declaration, these
     // generate a hard "misplaced attributes" error, which we test for
     // elsewhere.)
@@ -32,6 +40,10 @@ namespace test1 {
     // expected-warning{{attribute 'aligned' is ignored, place it after 
"union" to apply attribute to type declaration}}
     [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum H {H}; // 
expected-warning{{attribute 'visibility' is ignored, place it after "enum" to 
apply attribute to type declaration}} \
     // expected-warning{{attribute 'aligned' is ignored, place it after "enum" 
to apply attribute to type declaration}}
+    [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum class I {}; // 
expected-warning{{attribute 'visibility' is ignored, place it after "enum 
class" to apply attribute to type declaration}} \
+    // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
class" to apply attribute to type declaration}}
+    [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum struct J {}; // 
expected-warning{{attribute 'visibility' is ignored, place it after "enum 
struct" to apply attribute to type declaration}} \
+    // expected-warning{{attribute 'aligned' is ignored, place it after "enum 
struct" to apply attribute to type declaration}}
   };
 }
 
@@ -40,16 +52,22 @@ namespace test2 {
   __attribute__((visibility("hidden")))  __attribute__((aligned)) struct B {} 
b;
   __attribute__((visibility("hidden")))  __attribute__((aligned)) union C {} c;
   __attribute__((visibility("hidden")))  __attribute__((aligned)) enum D {D} d;
+  __attribute__((visibility("hidden")))  __attribute__((aligned)) enum class 
EC {} ec;
+  __attribute__((visibility("hidden")))  __attribute__((aligned)) enum struct 
ES {} es;
 
   struct X {
     __attribute__((visibility("hidden")))  __attribute__((aligned)) class A {} 
a;
     __attribute__((visibility("hidden")))  __attribute__((aligned)) struct B 
{} b;
     __attribute__((visibility("hidden")))  __attribute__((aligned)) union C {} 
c;
     __attribute__((visibility("hidden")))  __attribute__((aligned)) enum D {D} 
d;
+    __attribute__((visibility("hidden")))  __attribute__((aligned)) enum class 
EC {} ec;
+    __attribute__((visibility("hidden")))  __attribute__((aligned)) enum 
struct ES {} es;
 
     [[gnu::visibility("hidden")]]  [[gnu::aligned]] class E {} e;
     [[gnu::visibility("hidden")]]  [[gnu::aligned]] struct F {} f;
     [[gnu::visibility("hidden")]]  [[gnu::aligned]] union G {} g;
     [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum H {H} h;
+    [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum class I {} i;
+    [[gnu::visibility("hidden")]]  [[gnu::aligned]] enum struct J {} j;
   };
 }


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to