diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1404,8 +1404,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) @@ -1427,7 +1426,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_nullptr`` (C++, GNU, Microsoft, Embarcadero): Returns true for ``std::nullptr_t`` and false for everything else. The corresponding standard library feature is ``std::is_null_pointer``, but 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, KEYALL) TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX) -TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS) +TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYALL) 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,92 @@ +// 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 +// RUN: %clang_cc1 -x c -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu11 -fblocks -Wno-deprecated-builtins -fms-extensions -Wno-microsoft %s + +#ifdef __cplusplus + +// 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)); +} +#else +struct s1 {}; + +void is_destructible() +{ + (void)__is_destructible(int); + (void)__is_destructible(struct s1); + (void)__is_destructible(struct s2); // expected-error{{incomplete type 'struct s2' used in type trait expression}} + // expected-note@-1{{}} +} +#endif 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 @@ -414,23 +414,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))]; } @@ -445,32 +434,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 {};