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

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 3 07:21:32 PST 2025


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

Closes #121108.

- Added a new diagnostic group `InitPriorityReserved`
- Allow values within the range 0-100 of `init_priority` to be used outside system library, but with a warning
- Updated relavant tests

>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] 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 3ac490d30371b1..046bd0c5c8f2b9 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 330ae045616aba..acc8868829df64 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 bb4d33560b93b8..de3b867eaa7c52 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 8c0a17682bb02a..0d41f4ddc62179 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}}
 



More information about the cfe-commits mailing list