diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1403,8 +1403,7 @@ * ``__is_convertible`` (C++, Embarcadero) * ``__is_convertible_to`` (Microsoft): Synonym for ``__is_convertible``. -* ``__is_destructible`` (C++, MSVC 2013): - Only available in ``-fms-extensions`` mode. +* ``__is_destructible`` (C++, MSVC 2013) * ``__is_empty`` (C++, GNU, Microsoft, Embarcadero) * ``__is_enum`` (C++, GNU, Microsoft, Embarcadero) * ``__is_final`` (C++, GNU, Microsoft) @@ -1426,7 +1425,6 @@ * ``__is_nothrow_assignable`` (C++, MSVC 2013) * ``__is_nothrow_constructible`` (C++, MSVC 2013) * ``__is_nothrow_destructible`` (C++, MSVC 2013) - Only available in ``-fms-extensions`` mode. * ``__is_object`` (C++, Embarcadero) * ``__is_pod`` (C++, GNU, Microsoft, Embarcadero): Note, the corresponding standard trait was deprecated in C++20. @@ -4245,7 +4243,7 @@ #pragma clang attribute pop -A single push directive can contain multiple attributes, however, +A single push directive can contain multiple attributes, however, only one syntax style can be used within a single directive: .. code-block:: c++ @@ -4255,7 +4253,7 @@ void function1(); // The function now has the [[noreturn]] and [[noinline]] attributes #pragma clang attribute pop - + #pragma clang attribute push (__attribute((noreturn, noinline)), apply_to = function) void function2(); // The function now has the __attribute((noreturn)) and __attribute((noinline)) attributes diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -466,9 +466,9 @@ TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS) // MSVC12.0 / VS2013 Type Traits -TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS) +TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYCXX) TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX) -TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS) +TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYCXX) TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX) TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX) TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX) diff --git a/clang/test/SemaCXX/type-traits-ms-extensions.cpp b/clang/test/SemaCXX/type-traits-ms-extensions.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/type-traits-ms-extensions.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s -Wno-c++17-extensions +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s -Wno-c++17-extensions +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s + +// expected-no-diagnostics + +using Int = int; + +struct NonPOD { NonPOD(int); }; +enum Enum { EV }; +struct POD { Enum e; int i; float f; NonPOD* p; }; +struct Derives : POD {}; +using ClassType = Derives; + +union Union { int i; float f; }; + +struct HasAnonymousUnion { + union { + int i; + float f; + }; +}; + +struct FinalClass final { +}; + +template +struct PotentiallyFinal { }; + +template +struct PotentiallyFinal final { }; + +template<> +struct PotentiallyFinal final { }; + +struct SealedClass sealed { +}; + +template +struct PotentiallySealed { }; + +template +struct PotentiallySealed sealed { }; + +template<> +struct PotentiallySealed sealed { }; + +void is_final() { + static_assert(__is_final(SealedClass)); + static_assert(__is_final(PotentiallySealed)); + static_assert(__is_final(PotentiallySealed)); + + static_assert(!__is_final(PotentiallyFinal)); + static_assert(!__is_final(PotentiallySealed)); +} + +void is_sealed() +{ + static_assert(__is_sealed(SealedClass)); + static_assert(__is_sealed(PotentiallySealed)); + static_assert(__is_sealed(PotentiallySealed)); + static_assert(__is_sealed(FinalClass)); + static_assert(__is_sealed(PotentiallyFinal)); + static_assert(__is_sealed(PotentiallyFinal)); + + static_assert(!__is_sealed(int)); + static_assert(!__is_sealed(Union)); + static_assert(!__is_sealed(Int)); + static_assert(!__is_sealed(Int[10])); + static_assert(!__is_sealed(Union[10])); + static_assert(!__is_sealed(Derives)); + static_assert(!__is_sealed(ClassType)); + static_assert(!__is_sealed(const void)); + static_assert(!__is_sealed(Int[])); + static_assert(!__is_sealed(HasAnonymousUnion)); + static_assert(!__is_sealed(PotentiallyFinal)); + static_assert(!__is_sealed(PotentiallySealed)); +} diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fblocks -Wno-deprecated-builtins %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fblocks -Wno-deprecated-builtins %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fblocks -Wno-deprecated-builtins %s #define T(b) (b) ? 1 : -1 #define F(b) (b) ? -1 : 1 @@ -406,23 +406,12 @@ template<> struct PotentiallyFinal final { }; -struct SealedClass sealed { -}; -template -struct PotentiallySealed { }; -template -struct PotentiallySealed sealed { }; -template<> -struct PotentiallySealed sealed { }; void is_final() { - { int arr[T(__is_final(SealedClass))]; } - { int arr[T(__is_final(PotentiallySealed))]; } - { int arr[T(__is_final(PotentiallySealed))]; } { int arr[T(__is_final(FinalClass))]; } { int arr[T(__is_final(PotentiallyFinal))]; } { int arr[T(__is_final(PotentiallyFinal))]; } @@ -437,32 +426,8 @@ { int arr[F(__is_final(cvoid))]; } { int arr[F(__is_final(IntArNB))]; } { int arr[F(__is_final(HasAnonymousUnion))]; } - { int arr[F(__is_final(PotentiallyFinal))]; } - { int arr[F(__is_final(PotentiallySealed))]; } } -void is_sealed() -{ - { int arr[T(__is_sealed(SealedClass))]; } - { int arr[T(__is_sealed(PotentiallySealed))]; } - { int arr[T(__is_sealed(PotentiallySealed))]; } - { int arr[T(__is_sealed(FinalClass))]; } - { int arr[T(__is_sealed(PotentiallyFinal))]; } - { int arr[T(__is_sealed(PotentiallyFinal))]; } - - { int arr[F(__is_sealed(int))]; } - { int arr[F(__is_sealed(Union))]; } - { int arr[F(__is_sealed(Int))]; } - { int arr[F(__is_sealed(IntAr))]; } - { int arr[F(__is_sealed(UnionAr))]; } - { int arr[F(__is_sealed(Derives))]; } - { int arr[F(__is_sealed(ClassType))]; } - { int arr[F(__is_sealed(cvoid))]; } - { int arr[F(__is_sealed(IntArNB))]; } - { int arr[F(__is_sealed(HasAnonymousUnion))]; } - { int arr[F(__is_sealed(PotentiallyFinal))]; } - { int arr[F(__is_sealed(PotentiallySealed))]; } -} typedef HasVirt Polymorph; struct InheritPolymorph : Polymorph {};