From: Aaron Ballman Date: Wed, 23 Sep 2020 19:24:52 +0000 (-0400) Subject: Allow init_priority values <= 100 and > 65535 within system headers. X-Git-Tag: llvmorg-13-init~11123 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=af1d3e655991e5f0c86df372b8583a60d20268e0;p=platform%2Fupstream%2Fllvm.git 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. --- diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index e8ac819..7222f39 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 9c11921..3e27924 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 6edeb79..3babbe0 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 8f31e2f..5b5e3b9 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@-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@-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}} } -