Skip to content

Commit b26b33e

Browse files
author
git apple-llvm automerger
committed
Merge commit '5f4f145e912e' from apple/main into swift/next
2 parents 6366619 + 5f4f145 commit b26b33e

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2264,7 +2264,7 @@ def InitPriority : InheritableAttr {
22642264
let Spellings = [GCC<"init_priority", /*AllowInC*/0>];
22652265
let Args = [UnsignedArgument<"Priority">];
22662266
let Subjects = SubjectList<[Var], ErrorDiag>;
2267-
let Documentation = [Undocumented];
2267+
let Documentation = [InitPriorityDocs];
22682268
}
22692269

22702270
def Section : InheritableAttr {

clang/include/clang/Basic/AttrDocs.td

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ global variable or function should be in after translation.
5757
let Heading = "section, __declspec(allocate)";
5858
}
5959

60+
def InitPriorityDocs : Documentation {
61+
let Category = DocCatVariable;
62+
let Content = [{
63+
In C++, the order in which global variables are initialized across translation
64+
units is unspecified, unlike the ordering within a single translation unit. The
65+
``init_priority`` attribute allows you to specify a relative ordering for the
66+
initialization of objects declared at namespace scope in C++. The priority is
67+
given as an integer constant expression between 101 and 65535 (inclusive).
68+
Priorities outside of that range are reserved for use by the implementation. A
69+
lower value indicates a higher priority of initialization. Note that only the
70+
relative ordering of values is important. For example:
71+
72+
.. code-block:: c++
73+
74+
struct SomeType { SomeType(); };
75+
__attribute__((init_priority(200))) SomeType Obj1;
76+
__attribute__((init_priority(101))) SomeType Obj2;
77+
78+
``Obj1`` will be initialized *before* ``Obj2`` despite the usual order of
79+
initialization being the opposite.
80+
81+
This attribute is only supported for C++ and Objective-C++ and is ignored in
82+
other language modes.
83+
}];
84+
}
85+
6086
def InitSegDocs : Documentation {
6187
let Category = DocCatVariable;
6288
let Content = [{

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,11 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
33133313
return;
33143314
}
33153315

3316-
if (prioritynum < 101 || prioritynum > 65535) {
3316+
// Only perform the priority check if the attribute is outside of a system
3317+
// header. Values <= 100 are reserved for the implementation, and libc++
3318+
// benefits from being able to specify values in that range.
3319+
if ((prioritynum < 101 || prioritynum > 65535) &&
3320+
!S.getSourceManager().isInSystemHeader(AL.getLoc())) {
33173321
S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
33183322
<< E->getSourceRange() << AL << 101 << 65535;
33193323
AL.setInvalid();

clang/test/SemaCXX/init-priority-attr.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -DSYSTEM -verify %s
3+
4+
#if defined(SYSTEM)
5+
#5 "init-priority-attr.cpp" 3 // system header
6+
#endif
27

38
class Two {
49
private:
@@ -21,7 +26,15 @@ Two foo __attribute__((init_priority(101))) ( 5, 6 );
2126

2227
Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}}
2328

24-
Two coo[2] __attribute__((init_priority(3))); // expected-error {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
29+
Two coo[2] __attribute__((init_priority(100)));
30+
#if !defined(SYSTEM)
31+
// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
32+
#endif
33+
34+
Two boo[2] __attribute__((init_priority(65536)));
35+
#if !defined(SYSTEM)
36+
// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
37+
#endif
2538

2639
Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
2740

@@ -30,6 +43,5 @@ Two func() __attribute__((init_priority(1001))); // expected-error {{'init_prio
3043
int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
3144

3245
int main() {
33-
Two foo __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
46+
Two foo __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
3447
}
35-

0 commit comments

Comments
 (0)