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 @@ -23,25 +23,67 @@ extern Two koo[]; Two foo __attribute__((init_priority(101))) ( 5, 6 ); +#if defined(__MVS__) + #if defined(SYSTEM) + // expected-no-diagnostics + #else + // expected-warning@-5 {{unknown attribute 'init_priority' ignored}} + #endif +#endif -Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}} +Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); +#if !defined(__MVS__) +// expected-error@-2 {{'init_priority' attribute takes one argument}} +#elif !defined(SYSTEM) +// expected-warning@-4 {{unknown attribute 'init_priority' ignored}} +#endif Two coo[2] __attribute__((init_priority(100))); #if !defined(SYSTEM) -// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + #if !defined(__MVS__) + // expected-error@-3 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + #else + // expected-warning@-5 {{unknown attribute 'init_priority' ignored}} + #endif #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}} + #if !defined(__MVS__) + // expected-error@-3 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}} + #else + // expected-warning@-5 {{unknown attribute 'init_priority' ignored}} + #endif +#endif + +Two koo[4] __attribute__((init_priority(1.13))); +#if !defined(__MVS__) +// expected-error@-2 {{'init_priority' attribute requires an integer constant}} +#elif !defined(SYSTEM) +// expected-warning@-4 {{unknown attribute 'init_priority' ignored}} #endif -Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}} +Two func() __attribute__((init_priority(1001))); +#if !defined(__MVS__) +// expected-error@-2 {{'init_priority' attribute only applies to variables}} +#elif !defined(SYSTEM) +// expected-warning@-4 {{unknown attribute 'init_priority' ignored}} +#endif -Two func() __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}} -int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}} +int i __attribute__((init_priority(1001))); +#if !defined(__MVS__) +// expected-error@-2 {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}} +#elif !defined(SYSTEM) +// expected-warning@-4 {{unknown attribute 'init_priority' ignored}} +#endif 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))); +#if !defined(__MVS__) +// expected-error@-2 {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}} +#elif !defined(SYSTEM) +// expected-warning@-4 {{unknown attribute 'init_priority' ignored}} +#endif + } diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1435,6 +1435,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