[clang] [clang] Fix `gnu::init_priority` attribute handling for reserved values (PR #121577)

via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 24 23:11:55 PST 2025


https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/121577

>From 5551c179d4b1ed0f41885fc96fa4844c9b0435b5 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Fri, 3 Jan 2025 23:00:14 +0800
Subject: [PATCH 1/6] fix gnu::init_priority behavior

---
 clang/include/clang/Basic/DiagnosticGroups.td    |  1 +
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  3 +++
 clang/lib/Sema/SemaDeclAttr.cpp                  | 15 ++++++++++-----
 clang/test/SemaCXX/init-priority-attr.cpp        | 13 ++++++-------
 4 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 3ac490d30371b..046bd0c5c8f2b 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -510,6 +510,7 @@ def PrivateModule : DiagGroup<"private-module">;
 def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
 def InlineNamespaceReopenedNoninline
     : DiagGroup<"inline-namespace-reopened-noninline">;
+def InitPriorityReserved : DiagGroup<"init-priority-reserved">;
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
 def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
 def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 330ae045616ab..acc8868829df6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3324,6 +3324,9 @@ def err_attribute_argument_out_of_range : Error<
 def err_init_priority_object_attr : Error<
   "can only use 'init_priority' attribute on file-scope definitions "
   "of objects of class type">;
+def warn_init_priority_reserved : Warning<
+  "requested 'init_priority' %0 is reserved for internal use">,
+  InGroup<InitPriorityReserved>;
 def err_attribute_argument_out_of_bounds : Error<
   "%0 attribute parameter %1 is out of bounds">;
 def err_attribute_only_once_per_parameter : Error<
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index bb4d33560b93b..de3b867eaa7c5 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3591,15 +3591,20 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     return;
   }
 
+  if (prioritynum < 0 || prioritynum > 65535) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
+        << E->getSourceRange() << AL << 0 << 65535;
+    AL.setInvalid();
+    return;
+  }
+
   // Only perform the priority check if the attribute is outside of a system
   // header. Values <= 100 are reserved for the implementation, and libc++
   // benefits from being able to specify values in that range.
-  if ((prioritynum < 101 || prioritynum > 65535) &&
+  if (prioritynum < 101 &&
       !S.getSourceManager().isInSystemHeader(AL.getLoc())) {
-    S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
-        << E->getSourceRange() << AL << 101 << 65535;
-    AL.setInvalid();
-    return;
+    S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
+        << E->getSourceRange() << prioritynum;
   }
   D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
 }
diff --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp
index 8c0a17682bb02..0d41f4ddc6217 100644
--- a/clang/test/SemaCXX/init-priority-attr.cpp
+++ b/clang/test/SemaCXX/init-priority-attr.cpp
@@ -33,15 +33,15 @@ Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_
 
 Two coo[2]  __attribute__((init_priority(100)));
 #if !defined(SYSTEM)
-  // expected-error at -2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
+  // expected-warning at -2 {{requested 'init_priority' 100 is reserved for internal use}}
   // unknown-warning at -3 {{unknown attribute 'init_priority' ignored}}
 #endif
 
-Two boo[2]  __attribute__((init_priority(65536)));
-#if !defined(SYSTEM)
- // expected-error at -2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
- // unknown-warning at -3 {{unknown attribute 'init_priority' ignored}}
-#endif
+Two zoo[2]  __attribute__((init_priority(-1))); // expected-error {{'init_priority' attribute requires integer constant between 0 and 65535 inclusive}}
+// unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
+
+Two boo[2]  __attribute__((init_priority(65536))); // expected-error {{'init_priority' attribute requires integer constant between 0 and 65535 inclusive}}
+// unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
 
 Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
 // unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
@@ -49,7 +49,6 @@ Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_prio
 Two func()  __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}}
 // unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
 
-
 int i  __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
 // unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
 

>From 54430be35cbf4d4634521223aa5abcd19f76665a Mon Sep 17 00:00:00 2001
From: Iris <0.0 at owo.li>
Date: Fri, 3 Jan 2025 23:46:46 +0800
Subject: [PATCH 2/6] Apply suggestions from code review

---
 clang/include/clang/Basic/DiagnosticGroups.td    | 1 -
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +-
 clang/test/SemaCXX/init-priority-attr.cpp        | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 046bd0c5c8f2b..3ac490d30371b 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -510,7 +510,6 @@ def PrivateModule : DiagGroup<"private-module">;
 def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">;
 def InlineNamespaceReopenedNoninline
     : DiagGroup<"inline-namespace-reopened-noninline">;
-def InitPriorityReserved : DiagGroup<"init-priority-reserved">;
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
 def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
 def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index acc8868829df6..500016de957b8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3326,7 +3326,7 @@ def err_init_priority_object_attr : Error<
   "of objects of class type">;
 def warn_init_priority_reserved : Warning<
   "requested 'init_priority' %0 is reserved for internal use">,
-  InGroup<InitPriorityReserved>;
+  DiagGroup<"init-priority-reserved">, DefaultError;
 def err_attribute_argument_out_of_bounds : Error<
   "%0 attribute parameter %1 is out of bounds">;
 def err_attribute_only_once_per_parameter : Error<
diff --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp
index 0d41f4ddc6217..a0b4d95f2ee31 100644
--- a/clang/test/SemaCXX/init-priority-attr.cpp
+++ b/clang/test/SemaCXX/init-priority-attr.cpp
@@ -33,7 +33,7 @@ Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_
 
 Two coo[2]  __attribute__((init_priority(100)));
 #if !defined(SYSTEM)
-  // expected-warning at -2 {{requested 'init_priority' 100 is reserved for internal use}}
+  // expected-error at -2 {{requested 'init_priority' 100 is reserved for internal use}}
   // unknown-warning at -3 {{unknown attribute 'init_priority' ignored}}
 #endif
 

>From 0393dfe5fa6bca821d284e559d8260b31d7d6696 Mon Sep 17 00:00:00 2001
From: Iris <0.0 at owo.li>
Date: Fri, 3 Jan 2025 23:49:11 +0800
Subject: [PATCH 3/6] Update

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

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 500016de957b8..249bc5da236ec 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3326,7 +3326,7 @@ def err_init_priority_object_attr : Error<
   "of objects of class type">;
 def warn_init_priority_reserved : Warning<
   "requested 'init_priority' %0 is reserved for internal use">,
-  DiagGroup<"init-priority-reserved">, DefaultError;
+  InGroup<DiagGroup<"init-priority-reserved">>, DefaultError;
 def err_attribute_argument_out_of_bounds : Error<
   "%0 attribute parameter %1 is out of bounds">;
 def err_attribute_only_once_per_parameter : Error<

>From 14fb0cba975a405aa67178b1cfcbabb08c9138db Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Sat, 4 Jan 2025 09:32:47 +0800
Subject: [PATCH 4/6] add test for val 65535

---
 clang/test/SemaCXX/init-priority-attr.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp
index 0d41f4ddc6217..e36781f9eb94b 100644
--- a/clang/test/SemaCXX/init-priority-attr.cpp
+++ b/clang/test/SemaCXX/init-priority-attr.cpp
@@ -24,9 +24,13 @@ extern Two goo;
 extern Two coo[];
 extern Two koo[];
 
+// unknown-system-no-diagnostics
+
 Two foo __attribute__((init_priority(101))) ( 5, 6 );
- // unknown-system-no-diagnostics
- // unknown-warning at -2 {{unknown attribute 'init_priority' ignored}}
+// unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
+
+Two loo __attribute__((init_priority(65535))) ( 5, 6 );
+// unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}
 
 Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}}
 // unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}

>From 00e205e048317b5e0864e3a923e901d8fee4684f Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Fri, 17 Jan 2025 16:16:02 +0800
Subject: [PATCH 5/6] remove unneeded checks

---
 clang/lib/Sema/SemaDeclAttr.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index de3b867eaa7c5..3bf5dcc93a4a3 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3591,7 +3591,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     return;
   }
 
-  if (prioritynum < 0 || prioritynum > 65535) {
+  if (prioritynum > 65535) {
     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
         << E->getSourceRange() << AL << 0 << 65535;
     AL.setInvalid();
@@ -3601,8 +3601,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   // Only perform the priority check if the attribute is outside of a system
   // header. Values <= 100 are reserved for the implementation, and libc++
   // benefits from being able to specify values in that range.
-  if (prioritynum < 101 &&
-      !S.getSourceManager().isInSystemHeader(AL.getLoc())) {
+  if (prioritynum < 101) {
     S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
         << E->getSourceRange() << prioritynum;
   }

>From 61074e4063e3af2dcf12ab9afa6b2a3714ebf251 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 25 Feb 2025 15:11:37 +0800
Subject: [PATCH 6/6] update

---
 clang/docs/ReleaseNotes.rst               |  3 +++
 clang/lib/Sema/SemaDeclAttr.cpp           |  6 ++----
 clang/test/SemaCXX/init-priority-attr.cpp | 11 ++++++++---
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 699cbb17edca7..539d230a57983 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -131,6 +131,9 @@ Attribute Changes in Clang
   ``__attribute__((model("large")))`` on non-TLS globals in x86-64 compilations.
   This forces the global to be considered small or large in regards to the
   x86-64 code model, regardless of the code model specified for the compilation.
+- Clang now emits a warning ``-Wreserved-init-priority`` instead of a hard error 
+  when ``__attribute__((init_priority(n)))`` is used with values of n in the 
+  reserved range [0, 100]. The warning will be treated as an error by default.
 
 Improvements to Clang's diagnostics
 -----------------------------------
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c35dcbc39c7e5..8538218c46653 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3651,13 +3651,11 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     return;
   }
 
-  // Only perform the priority check if the attribute is outside of a system
-  // header. Values <= 100 are reserved for the implementation, and libc++
+  // Values <= 100 are reserved for the implementation, and libc++
   // benefits from being able to specify values in that range.
-  if (prioritynum < 101) {
+  if (prioritynum < 101)
     S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
         << E->getSourceRange() << prioritynum;
-  }
   D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
 }
 
diff --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp
index 27a3b5dfb9327..8151bf7aecb95 100644
--- a/clang/test/SemaCXX/init-priority-attr.cpp
+++ b/clang/test/SemaCXX/init-priority-attr.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -DSYSTEM -verify %s
+// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -DNOERROR -Wno-error=init-priority-reserved -verify %s
 // RUN: %clang_cc1 -triple=s390x-none-zos -fsyntax-only -verify=unknown %s
 // RUN: %clang_cc1 -triple=s390x-none-zos -fsyntax-only -DSYSTEM -verify=unknown-system %s
 
@@ -37,9 +38,13 @@ Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_
 
 Two coo[2]  __attribute__((init_priority(100)));
 #if !defined(SYSTEM)
-  // expected-error at -2 {{requested 'init_priority' 100 is reserved for internal use}}
-  // unknown-warning at -3 {{unknown attribute 'init_priority' ignored}}
-#endif
+#if !defined(NOERROR)
+  // expected-error at -3 {{requested 'init_priority' 100 is reserved for internal use}}
+#else  // defined(NOERROR)
+  // expected-warning at -5 {{requested 'init_priority' 100 is reserved for internal use}}
+#endif // !defined(NOERROR)
+  // unknown-warning at -7 {{unknown attribute 'init_priority' ignored}}
+#endif // !defined(SYSTEM)
 
 Two zoo[2]  __attribute__((init_priority(-1))); // expected-error {{'init_priority' attribute requires integer constant between 0 and 65535 inclusive}}
 // unknown-warning at -1 {{unknown attribute 'init_priority' ignored}}



More information about the cfe-commits mailing list