<div dir="ltr">I think it comes down to a question of whether we want to guarantee that these traits are treated as not being identifiers. In some sense, it's an implementation detail that we model them as keywords -- and as it happens, there are some circumstances in which we *don't* model them as keywords. For example:<div><br></div><div><div>// Starts off as a keyword</div><div>const bool a = __is_trivial(int);            </div><div>#if __is_identifier(__is_trivial)            </div><div>#error not an identifier</div><div>#endif</div><div><br></div><div>// Downgraded to a simple identifier</div><div>template<typename> struct __is_trivial {};            </div><div>#if !__is_identifier(__is_trivial)            </div><div>#error is an identifier</div><div>#endif</div><div><br></div><div>// Can still be used as a trait, though</div><div>const bool b = __is_trivial(int);</div></div><div><br></div><div>The implementation of the above would be simpler if we *never* treated these traits as keywords, but that would break libc++ if it relies on __is_identifier to check this.</div><div><br></div><div>Ultimately, though if people are already relying on using __is_identifier for this, then maybe we should just say that's the supported way to check for these things (and keep it working that way if we ever do change the internal representation to something else).</div><div><br></div><div><div class="gmail_extra"><div class="gmail_quote">On 2 June 2017 at 13:44, Eric Fiselier <span dir="ltr"><<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-im gmail-HOEnZb"><div dir="ltr"><div dir="auto" style="font-size:12.8px">I've been using !__is_identifier to test for things like that. It seems to be the most consistent way.</div><div style="font-size:12.8px">Is there some problem with this?</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">/Eric</div></div></span><div class="gmail-HOEnZb"><div class="gmail-h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 1, 2017 at 6:46 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On 31 May 2017 at 17:41, Eric Fiselier <span dir="ltr"><<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I'm assuming libc++ should move to this trait instead?</div></blockquote><div><br></div></span><div>Yes, that'd be a good idea. Though now that you mention it, I'm not sure we have a good feature detection story for these builtins. Looks like a bunch of the existing ones are (oddly) covered by __has_feature, and they can all be discovered through !__is_identifier, but __has_extension or __has_builtin seem like the right detection mechanism and neither of them works here. ;-(</div><div><br></div><div>Thoughts?</div><div><div class="gmail-m_5971774617261078748h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span class="gmail-m_5971774617261078748m_3167167546294419994HOEnZb"><font color="#888888"><div>/Eric</div></font></span></div><div class="gmail-m_5971774617261078748m_3167167546294419994HOEnZb"><div class="gmail-m_5971774617261078748m_3167167546294419994h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 31, 2017 at 6:28 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: rsmith<br>
Date: Wed May 31 19:28:16 2017<br>
New Revision: 304376<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=304376&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=304376&view=rev</a><br>
Log:<br>
PR33232: implement support for MSVC's __is_trivially_destructible trait.<br>
<br>
Unlike the GCC-compatible __has_trivial_destructor trait, this one computes the<br>
right answer rather than performing the quirky set of checks described in GCC's<br>
documentation (<a href="https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html" rel="noreferrer" target="_blank">https://gcc.gnu.org/onlinedoc<wbr>s/gcc/Type-Traits.html</a>).<br>
<br>
MSVC also has a __has_trivial_destructor trait which is the same as its (and<br>
now Clang's) __is_trivially_destructible trait; we might want to consider<br>
changing the behavior of __has_trivial_destructor if we're targeting an MSVC<br>
platform, but I'm not doing so for now.<br>
<br>
While implementing this I found that we were incorrectly rejecting<br>
__is_destructible queries on arrays of unknown bound of incomplete types; that<br>
too is fixed, and I've added similar tests for other traits for good measure.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>TokenKinds.def<br>
    cfe/trunk/include/clang/Basic/<wbr>TypeTraits.h<br>
    cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp<br>
    cfe/trunk/test/SemaCXX/type-tr<wbr>aits.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>TokenKinds.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=304376&r1=304375&r2=304376&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/TokenKinds.def?rev=30437<wbr>6&r1=304375&r2=304376&view=dif<wbr>f</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>TokenKinds.def (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>TokenKinds.def Wed May 31 19:28:16 2017<br>
@@ -411,6 +411,7 @@ TYPE_TRAIT_1(__is_sealed, IsSealed, KEYM<br>
<br>
 // MSVC12.0 / VS2013 Type Traits<br>
 TYPE_TRAIT_1(__is_destructibl<wbr>e, IsDestructible, KEYMS)<br>
+TYPE_TRAIT_1(__is_trivially_d<wbr>estructible, IsTriviallyDestructible, KEYCXX)<br>
 TYPE_TRAIT_1(__is_nothrow_des<wbr>tructible, IsNothrowDestructible, KEYMS)<br>
 TYPE_TRAIT_2(__is_nothrow_ass<wbr>ignable, IsNothrowAssignable, KEYCXX)<br>
 TYPE_TRAIT_N(__is_constructib<wbr>le, IsConstructible, KEYCXX)<br>
@@ -439,7 +440,6 @@ TYPE_TRAIT_2(__is_convertible_<wbr>to, IsConv<br>
 TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)<br>
 TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)<br>
 TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)<br>
-// Tentative name - there's no implementation of std::is_literal_type yet.<br>
 TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)<br>
 // Name for GCC 4.6 compatibility - people have already written libraries using<br>
 // this name unfortunately.<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>TypeTraits.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=304376&r1=304375&r2=304376&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/TypeTraits.h?rev=304376&<wbr>r1=304375&r2=304376&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>TypeTraits.h (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>TypeTraits.h Wed May 31 19:28:16 2017<br>
@@ -65,6 +65,7 @@ namespace clang {<br>
     UTT_IsStandardLayout,<br>
     UTT_IsTrivial,<br>
     UTT_IsTriviallyCopyable,<br>
+    UTT_IsTriviallyDestructible,<br>
     UTT_IsUnion,<br>
     UTT_IsUnsigned,<br>
     UTT_IsVoid,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=304376&r1=304375&r2=304376&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Sema/SemaE<wbr>xprCXX.cpp?rev=304376&r1=30437<wbr>5&r2=304376&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX<wbr>.cpp Wed May 31 19:28:16 2017<br>
@@ -4080,24 +4080,23 @@ static bool CheckUnaryTypeTraitTypeCompl<br>
           Loc, ArgTy, diag::err_incomplete_type_used<wbr>_in_type_trait_expr);<br>
     return true;<br>
<br>
-  // C++0x [meta.unary.prop] Table 49 requires the following traits to be<br>
-  // applied to a complete type.<br>
+  // C++1z [meta.unary.prop]:<br>
+  //   remove_all_extents_t<T> shall be a complete type or cv void.<br>
   case UTT_IsAggregate:<br>
   case UTT_IsTrivial:<br>
   case UTT_IsTriviallyCopyable:<br>
   case UTT_IsStandardLayout:<br>
   case UTT_IsPOD:<br>
   case UTT_IsLiteral:<br>
+    ArgTy = QualType(ArgTy->getBaseElement<wbr>TypeUnsafe(), 0);<br>
+    LLVM_FALLTHROUGH;<br>
<br>
+  // C++1z [meta.unary.prop]:<br>
+  //   T shall be a complete type, cv void, or an array of unknown bound.<br>
   case UTT_IsDestructible:<br>
   case UTT_IsNothrowDestructible:<br>
-    // Fall-through<br>
-<br>
-    // These trait expressions are designed to help implement predicates in<br>
-    // [meta.unary.prop] despite not being named the same. They are specified<br>
-    // by both GCC and the Embarcadero C++ compiler, and require the complete<br>
-    // type due to the overarching C++0x type predicates being implemented<br>
-    // requiring the complete type.<br>
+  case UTT_IsTriviallyDestructible:<br>
+  // Per the GCC type traits documentation, the same constraints apply to these.<br>
   case UTT_HasNothrowAssign:<br>
   case UTT_HasNothrowMoveAssign:<br>
   case UTT_HasNothrowConstructor:<br>
@@ -4109,17 +4108,11 @@ static bool CheckUnaryTypeTraitTypeCompl<br>
   case UTT_HasTrivialCopy:<br>
   case UTT_HasTrivialDestructor:<br>
   case UTT_HasVirtualDestructor:<br>
-    // Arrays of unknown bound are expressly allowed.<br>
-    QualType ElTy = ArgTy;<br>
-    if (ArgTy->isIncompleteArrayType(<wbr>))<br>
-      ElTy = S.Context.getAsArrayType(ArgTy<wbr>)->getElementType();<br>
-<br>
-    // The void type is expressly allowed.<br>
-    if (ElTy->isVoidType())<br>
+    if (ArgTy->isIncompleteArrayType(<wbr>) || ArgTy->isVoidType())<br>
       return true;<br>
<br>
     return !S.RequireCompleteType(<br>
-      Loc, ElTy, diag::err_incomplete_type_used<wbr>_in_type_trait_expr);<br>
+        Loc, ArgTy, diag::err_incomplete_type_used<wbr>_in_type_trait_expr);<br>
   }<br>
 }<br>
<br>
@@ -4356,6 +4349,7 @@ static bool EvaluateUnaryTypeTrait(Sema<br>
              !RD->hasNonTrivialCopyAssignme<wbr>nt();<br>
     return false;<br>
   case UTT_IsDestructible:<br>
+  case UTT_IsTriviallyDestructible:<br>
   case UTT_IsNothrowDestructible:<br>
     // C++14 [meta.unary.prop]:<br>
     //   For reference types, is_destructible<T>::value is true.<br>
@@ -4373,6 +4367,11 @@ static bool EvaluateUnaryTypeTrait(Sema<br>
     if (T->isIncompleteType() || T->isFunctionType())<br>
       return false;<br>
<br>
+    // A type that requires destruction (via a non-trivial destructor or ARC<br>
+    // lifetime semantics) is not trivially-destructible.<br>
+    if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())<br>
+      return false;<br>
+<br>
     // C++14 [meta.unary.prop]:<br>
     //   For object types and given U equal to remove_all_extents_t<T>, if the<br>
     //   expression std::declval<U&>().~U() is well-formed when treated as an<br>
<br>
Modified: cfe/trunk/test/SemaCXX/type-tr<wbr>aits.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=304376&r1=304375&r2=304376&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/SemaCXX/t<wbr>ype-traits.cpp?rev=304376&r1=3<wbr>04375&r2=304376&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/type-tr<wbr>aits.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/type-tr<wbr>aits.cpp Wed May 31 19:28:16 2017<br>
@@ -252,6 +252,11 @@ void is_pod()<br>
   { int arr[F(__is_pod(void))]; }<br>
   { int arr[F(__is_pod(cvoid))]; }<br>
 // { int arr[F(__is_pod(NonPODUnion))]; }<br>
+<br>
+  { int arr[T(__is_pod(ACompleteType))<wbr>]; }<br>
+  { int arr[F(__is_pod(AnIncompleteTyp<wbr>e))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_pod(AnIncompleteTyp<wbr>e[]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_pod(AnIncompleteTyp<wbr>e[1]))]; } // expected-error {{incomplete type}}<br>
 }<br>
<br>
 typedef Empty EmptyAr[10];<br>
@@ -287,6 +292,11 @@ void is_empty()<br>
   { int arr[F(__is_empty(IntArNB))]; }<br>
   { int arr[F(__is_empty(HasAnonymousU<wbr>nion))]; }<br>
 //  { int arr[F(__is_empty(DerivesVirt))<wbr>]; }<br>
+<br>
+  { int arr[T(__is_empty(ACompleteType<wbr>))]; }<br>
+  { int arr[F(__is_empty(AnIncompleteT<wbr>ype))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_empty(AnIncompleteT<wbr>ype[]))]; }<br>
+  { int arr[F(__is_empty(AnIncompleteT<wbr>ype[1]))]; }<br>
 }<br>
<br>
 typedef Derives ClassType;<br>
@@ -511,6 +521,8 @@ void is_aggregate()<br>
   constexpr bool TrueAfterCpp14 = __cplusplus > 201402L;<br>
<br>
   __is_aggregate(AnIncompleteTy<wbr>pe); // expected-error {{incomplete type}}<br>
+  __is_aggregate(AnIncompleteTyp<wbr>e[]); // expected-error {{incomplete type}}<br>
+  __is_aggregate(AnIncompleteTyp<wbr>e[1]); // expected-error {{incomplete type}}<br>
   __is_aggregate(AnIncompleteTy<wbr>peAr); // expected-error {{incomplete type}}<br>
   __is_aggregate(AnIncompleteTy<wbr>peArNB); // expected-error {{incomplete type}}<br>
   __is_aggregate(AnIncompleteTy<wbr>peArMB); // expected-error {{incomplete type}}<br>
@@ -1220,6 +1232,13 @@ void is_trivial2()<br>
   int t32[F(__is_trivial(SuperNonTri<wbr>vialStruct))];<br>
   int t33[F(__is_trivial(NonTCStruct<wbr>))];<br>
   int t34[F(__is_trivial(ExtDefaulte<wbr>d))];<br>
+<br>
+  int t40[T(__is_trivial(ACompleteTy<wbr>pe))];<br>
+  int t41[F(__is_trivial(AnIncomplet<wbr>eType))]; // expected-error {{incomplete type}}<br>
+  int t42[F(__is_trivial(AnIncomplet<wbr>eType[]))]; // expected-error {{incomplete type}}<br>
+  int t43[F(__is_trivial(AnIncomplet<wbr>eType[1]))]; // expected-error {{incomplete type}}<br>
+  int t44[F(__is_trivial(void))];<br>
+  int t45[F(__is_trivial(const volatile void))];<br>
 }<br>
<br>
 void is_trivially_copyable2()<br>
@@ -1257,6 +1276,13 @@ void is_trivially_copyable2()<br>
<br>
   int t34[T(__is_trivially_copyable(<wbr>const int))];<br>
   int t35[T(__is_trivially_copyable(<wbr>volatile int))];<br>
+<br>
+  int t40[T(__is_trivially_copyable(<wbr>ACompleteType))];<br>
+  int t41[F(__is_trivially_copyable(<wbr>AnIncompleteType))]; // expected-error {{incomplete type}}<br>
+  int t42[F(__is_trivially_copyable(<wbr>AnIncompleteType[]))]; // expected-error {{incomplete type}}<br>
+  int t43[F(__is_trivially_copyable(<wbr>AnIncompleteType[1]))]; // expected-error {{incomplete type}}<br>
+  int t44[F(__is_trivially_copyable(<wbr>void))];<br>
+  int t45[F(__is_trivially_copyable(<wbr>const volatile void))];<br>
 }<br>
<br>
 struct CStruct {<br>
@@ -1320,6 +1346,13 @@ void is_standard_layout()<br>
   int t15[F(__is_standard_layout(Cpp<wbr>StructNonStandardByBaseAr))];<br>
   int t16[F(__is_standard_layout(Cpp<wbr>StructNonStandardBySameBase))]<wbr>;<br>
   int t17[F(__is_standard_layout(Cpp<wbr>StructNonStandardBy2ndVirtBase<wbr>))];<br>
+<br>
+  int t40[T(__is_standard_layout(ACo<wbr>mpleteType))];<br>
+  int t41[F(__is_standard_layout(AnI<wbr>ncompleteType))]; // expected-error {{incomplete type}}<br>
+  int t42[F(__is_standard_layout(AnI<wbr>ncompleteType[]))]; // expected-error {{incomplete type}}<br>
+  int t43[F(__is_standard_layout(AnI<wbr>ncompleteType[1]))]; // expected-error {{incomplete type}}<br>
+  int t44[F(__is_standard_layout(voi<wbr>d))];<br>
+  int t45[F(__is_standard_layout(con<wbr>st volatile void))];<br>
 }<br>
<br>
 void is_signed()<br>
@@ -2133,6 +2166,13 @@ void trivial_checks()<br>
                                TrivialMoveButNotCopy)))]; }<br>
   { int arr[T((__is_assignable(Trivial<wbr>MoveButNotCopy &,<br>
                                TrivialMoveButNotCopy &&)))]; }<br>
+<br>
+  { int arr[T(__is_assignable(AComplet<wbr>eType, ACompleteType))]; }<br>
+  { int arr[F(__is_assignable(AnIncomp<wbr>leteType, AnIncompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_assignable(AnIncomp<wbr>leteType[], AnIncompleteType[]))]; }<br>
+  { int arr[F(__is_assignable(AnIncomp<wbr>leteType[1], AnIncompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_assignable(void, void))]; }<br>
+  { int arr[F(__is_assignable(const volatile void, const volatile void))]; }<br>
 }<br>
<br>
 void constructible_checks() {<br>
@@ -2164,6 +2204,19 @@ void constructible_checks() {<br>
<br>
   // PR25513<br>
   { int arr[F(__is_constructible(int(i<wbr>nt)))]; }<br>
+<br>
+  { int arr[T(__is_constructible(AComp<wbr>leteType))]; }<br>
+  { int arr[T(__is_nothrow_constructib<wbr>le(ACompleteType))]; }<br>
+  { int arr[F(__is_constructible(AnInc<wbr>ompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_nothrow_constructib<wbr>le(AnIncompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_constructible(AnInc<wbr>ompleteType[]))]; }<br>
+  { int arr[F(__is_nothrow_constructib<wbr>le(AnIncompleteType[]))]; }<br>
+  { int arr[F(__is_constructible(AnInc<wbr>ompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_nothrow_constructib<wbr>le(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_constructible(void)<wbr>)]; }<br>
+  { int arr[F(__is_nothrow_constructib<wbr>le(void))]; }<br>
+  { int arr[F(__is_constructible(const volatile void))]; }<br>
+  { int arr[F(__is_nothrow_constructib<wbr>le(const volatile void))]; }<br>
 }<br>
<br>
 // Instantiation of __is_trivially_constructible<br>
@@ -2192,6 +2245,13 @@ void is_trivially_constructible_tes<wbr>t() {<br>
   { int arr[F((is_trivially_constructi<wbr>ble<NonTrivialDefault>::value)<wbr>)]; }<br>
   { int arr[F((is_trivially_constructi<wbr>ble<ThreeArgCtor, int*, char*, int&>::value))]; }<br>
   { int arr[F((is_trivially_constructi<wbr>ble<Abstract>::value))]; } // PR19178<br>
+<br>
+  { int arr[T(__is_trivially_construct<wbr>ible(ACompleteType))]; }<br>
+  { int arr[F(__is_trivially_construct<wbr>ible(AnIncompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_trivially_construct<wbr>ible(AnIncompleteType[]))]; }<br>
+  { int arr[F(__is_trivially_construct<wbr>ible(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_trivially_construct<wbr>ible(void))]; }<br>
+  { int arr[F(__is_trivially_construct<wbr>ible(const volatile void))]; }<br>
 }<br>
<br>
 void array_rank() {<br>
@@ -2218,6 +2278,13 @@ void is_destructible_test() {<br>
   { int arr[F(__is_destructible(AllDel<wbr>eted))]; }<br>
   { int arr[T(__is_destructible(Throwi<wbr>ngDtor))]; }<br>
   { int arr[T(__is_destructible(NoThro<wbr>wDtor))]; }<br>
+<br>
+  { int arr[T(__is_destructible(ACompl<wbr>eteType))]; }<br>
+  { int arr[F(__is_destructible(AnInco<wbr>mpleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_destructible(AnInco<wbr>mpleteType[]))]; }<br>
+  { int arr[F(__is_destructible(AnInco<wbr>mpleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_destructible(void))<wbr>]; }<br>
+  { int arr[F(__is_destructible(const volatile void))]; }<br>
 }<br>
<br>
 void is_nothrow_destructible_test() {<br>
@@ -2234,4 +2301,33 @@ void is_nothrow_destructible_test() {<br>
   { int arr[F(__is_nothrow_destructibl<wbr>e(ThrowingDtor))]; }<br>
   { int arr[T(__is_nothrow_destructibl<wbr>e(NoExceptDtor))]; }<br>
   { int arr[T(__is_nothrow_destructibl<wbr>e(NoThrowDtor))]; }<br>
+<br>
+  { int arr[T(__is_nothrow_destructibl<wbr>e(ACompleteType))]; }<br>
+  { int arr[F(__is_nothrow_destructibl<wbr>e(AnIncompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_nothrow_destructibl<wbr>e(AnIncompleteType[]))]; }<br>
+  { int arr[F(__is_nothrow_destructibl<wbr>e(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_nothrow_destructibl<wbr>e(void))]; }<br>
+  { int arr[F(__is_nothrow_destructibl<wbr>e(const volatile void))]; }<br>
+}<br>
+<br>
+void is_trivially_destructible_test<wbr>() {<br>
+  { int arr[T(__is_trivially_destructi<wbr>ble(int))]; }<br>
+  { int arr[T(__is_trivially_destructi<wbr>ble(int[2]))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(int[]))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(void))]; }<br>
+  { int arr[T(__is_trivially_destructi<wbr>ble(int &))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(HasDest))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(AllPrivate))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(SuperNonTrivialStruct))]; }<br>
+  { int arr[T(__is_trivially_destructi<wbr>ble(AllDefaulted))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(AllDeleted))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(ThrowingDtor))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(NoThrowDtor))]; }<br>
+<br>
+  { int arr[T(__is_trivially_destructi<wbr>ble(ACompleteType))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(AnIncompleteType))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(AnIncompleteType[]))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(AnIncompleteType[1]))]; } // expected-error {{incomplete type}}<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(void))]; }<br>
+  { int arr[F(__is_trivially_destructi<wbr>ble(const volatile void))]; }<br>
 }<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div></div></div>