[clang] af1d3e6 - Allow init_priority values <= 100 and > 65535 within system headers.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 23 12:27:07 PDT 2020


Author: Aaron Ballman
Date: 2020-09-23T15:26:50-04:00
New Revision: af1d3e655991e5f0c86df372b8583a60d20268e0

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

LOG: Allow init_priority values <= 100 and > 65535 within system headers.

This also adds some bare-bones documentation for the attribute rather
than leaving it undocumented.

Added: 
    

Modified: 
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/SemaCXX/init-priority-attr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index e8ac819c8b556..7222f396089e0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2196,7 +2196,7 @@ def InitPriority : InheritableAttr {
   let Spellings = [GCC<"init_priority", /*AllowInC*/0>];
   let Args = [UnsignedArgument<"Priority">];
   let Subjects = SubjectList<[Var], ErrorDiag>;
-  let Documentation = [Undocumented];
+  let Documentation = [InitPriorityDocs];
 }
 
 def Section : InheritableAttr {

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 9c119218656d8..3e27924589e4a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -57,6 +57,32 @@ global variable or function should be in after translation.
   let Heading = "section, __declspec(allocate)";
 }
 
+def InitPriorityDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+In C++, the order in which global variables are initialized across translation
+units is unspecified, unlike the ordering within a single translation unit. The
+``init_priority`` attribute allows you to specify a relative ordering for the
+initialization of objects declared at namespace scope in C++. The priority is
+given as an integer constant expression between 101 and 65535 (inclusive).
+Priorities outside of that range are reserved for use by the implementation. A
+lower value indicates a higher priority of initialization. Note that only the
+relative ordering of values is important. For example:
+
+.. code-block:: c++
+
+  struct SomeType { SomeType(); };
+  __attribute__((init_priority(200))) SomeType Obj1;
+  __attribute__((init_priority(101))) SomeType Obj2;
+
+``Obj1`` will be initialized *before* ``Obj2`` despite the usual order of
+initialization being the opposite.
+
+This attribute is only supported for C++ and Objective-C++ and is ignored in
+other language modes.
+  }];
+}
+
 def InitSegDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6edeb79396296..3babbe05ca8f9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3313,7 +3313,11 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     return;
   }
 
-  if (prioritynum < 101 || prioritynum > 65535) {
+  // 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) &&
+      !S.getSourceManager().isInSystemHeader(AL.getLoc())) {
     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
         << E->getSourceRange() << AL << 101 << 65535;
     AL.setInvalid();

diff  --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp
index 8f31e2fd62d00..5b5e3b9eb940e 100644
--- a/clang/test/SemaCXX/init-priority-attr.cpp
+++ b/clang/test/SemaCXX/init-priority-attr.cpp
@@ -1,4 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -DSYSTEM -verify %s
+
+#if defined(SYSTEM)
+#5 "init-priority-attr.cpp" 3 // system header
+#endif
 
 class Two {
 private:
@@ -21,7 +26,15 @@ Two foo __attribute__((init_priority(101))) ( 5, 6 );
 
 Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}}
 
-Two coo[2]  __attribute__((init_priority(3)));	// expected-error {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
+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}}
+#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}}
+#endif
 
 Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
 
@@ -30,6 +43,5 @@ Two func()  __attribute__((init_priority(1001))); // expected-error {{'init_prio
 int i  __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
 
 int main() {
-	Two foo __attribute__((init_priority(1001)));	// expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
+  Two foo __attribute__((init_priority(1001)));	// expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
 }
-


        


More information about the cfe-commits mailing list