diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -381,6 +381,9 @@ let ObjectFormats = ["ELF"]; } +def TargetSupportsInitPriority : TargetSpec { + let CustomCode = [{ !Target.getTriple().isOSzOS() }]; +} // Attribute subject match rules that are used for #pragma clang attribute. // // A instance of AttrSubjectMatcherRule represents an individual match rule. @@ -2221,7 +2224,7 @@ let Documentation = [Undocumented]; } -def InitPriority : InheritableAttr { +def InitPriority : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"init_priority", /*AllowInC*/0>]; let Args = [UnsignedArgument<"Priority">]; let Subjects = SubjectList<[Var], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -79,7 +79,7 @@ initialization being the opposite. This attribute is only supported for C++ and Objective-C++ and is ignored in -other language modes. +other language modes. Currently, this attribute is not implemented on z/OS. }]; } diff --git a/clang/test/SemaCXX/init-priority-attr.cpp b/clang/test/SemaCXX/init-priority-attr.cpp --- a/clang/test/SemaCXX/init-priority-attr.cpp +++ b/clang/test/SemaCXX/init-priority-attr.cpp @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -DSYSTEM -verify %s +// 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=s390x-none-zos -fsyntax-only -verify=unknown %s +// RUN: %clang_cc1 -triple=s390x-none-zos -fsyntax-only -DSYSTEM -verify=unknown-system %s #if defined(SYSTEM) #5 "init-priority-attr.cpp" 3 // system header @@ -23,25 +25,35 @@ extern Two koo[]; Two foo __attribute__((init_priority(101))) ( 5, 6 ); + // unknown-system-no-diagnostics + // unknown-warning@-2 {{unknown attribute 'init_priority' ignored}} Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}} +// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}} Two coo[2] __attribute__((init_priority(100))); #if !defined(SYSTEM) -// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + // expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + // unknown-warning@-3 {{unknown attribute 'init_priority' ignored}} #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}} + // expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + // unknown-warning@-3 {{unknown attribute 'init_priority' ignored}} #endif Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}} +// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}} Two func() __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}} +// unknown-warning@-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@-1 {{unknown attribute 'init_priority' ignored}} 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}} +// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}} } diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1421,6 +1421,12 @@ #define _LIBCPP_HAS_NO_FGETPOS_FSETPOS #endif +#if __has_attribute(init_priority) +# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101))) +#else +# define _LIBCPP_INIT_PRIORITY_MAX +#endif + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/libcxx/src/experimental/memory_resource.cpp b/libcxx/src/experimental/memory_resource.cpp --- a/libcxx/src/experimental/memory_resource.cpp +++ b/libcxx/src/experimental/memory_resource.cpp @@ -76,16 +76,6 @@ ~ResourceInitHelper() {} }; -// Detect if the init_priority attribute is supported. -#if (defined(_LIBCPP_COMPILER_GCC) && defined(__APPLE__)) \ - || defined(_LIBCPP_COMPILER_MSVC) -// GCC on Apple doesn't support the init priority attribute, -// and MSVC doesn't support any GCC attributes. -# define _LIBCPP_INIT_PRIORITY_MAX -#else -# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101))) -#endif - // When compiled in C++14 this initialization should be a constant expression. // Only in C++11 is "init_priority" needed to ensure initialization order. #if _LIBCPP_STD_VER > 11 diff --git a/libcxx/src/iostream.cpp b/libcxx/src/iostream.cpp --- a/libcxx/src/iostream.cpp +++ b/libcxx/src/iostream.cpp @@ -77,7 +77,7 @@ #endif ; -_LIBCPP_HIDDEN ios_base::Init __start_std_streams __attribute__((init_priority(101))); +_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX; // On Windows the TLS storage for locales needs to be initialized before we create // the standard streams, otherwise it may not be alive during program termination