r190482 - Fix is_trivially_constructible preconditions.

Eli Friedman eli.friedman at gmail.com
Tue Sep 10 19:53:02 PDT 2013


Author: efriedma
Date: Tue Sep 10 21:53:02 2013
New Revision: 190482

URL: http://llvm.org/viewvc/llvm-project?rev=190482&view=rev
Log:
Fix is_trivially_constructible preconditions.

Fixes a crash in cases where the first argument was an incomplete type
or an uninstantiated template type.

<rdar://problem/14938471>

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/type-traits.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=190482&r1=190481&r2=190482&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Sep 10 21:53:02 2013
@@ -3522,24 +3522,24 @@ static bool evaluateTypeTrait(Sema &S, T
         << 1 << 1 << 1 << (int)Args.size();
       return false;
     }
-    
-    bool SawVoid = false;
+
+    // Precondition: T and all types in the parameter pack Args shall be
+    // complete types, (possibly cv-qualified) void, or arrays of
+    // unknown bound.
     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
-      if (Args[I]->getType()->isVoidType()) {
-        SawVoid = true;
+      QualType ArgTy = Args[I]->getType();
+      if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
         continue;
-      }
-      
-      if (!Args[I]->getType()->isIncompleteType() &&
-        S.RequireCompleteType(KWLoc, Args[I]->getType(), 
+
+      if (S.RequireCompleteType(KWLoc, ArgTy, 
           diag::err_incomplete_type_used_in_type_trait_expr))
         return false;
     }
-    
-    // If any argument was 'void', of course it won't type-check.
-    if (SawVoid)
+
+    // Make sure the first argument is a complete type.
+    if (Args[0]->getType()->isIncompleteType())
       return false;
-    
+
     SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs;
     SmallVector<Expr *, 2> ArgExprs;
     ArgExprs.reserve(Args.size() - 1);

Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=190482&r1=190481&r2=190482&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Tue Sep 10 21:53:02 2013
@@ -1571,7 +1571,7 @@ template<typename T> struct DerivedB : B
 template<typename T> struct CrazyDerived : T { };
 
 
-class class_forward; // expected-note {{forward declaration of 'class_forward'}}
+class class_forward; // expected-note 2 {{forward declaration of 'class_forward'}}
 
 template <typename Base, typename Derived>
 void isBaseOfT() {
@@ -1770,6 +1770,8 @@ void is_trivial()
   { int arr[F(__is_trivial(cvoid))]; }
 }
 
+template<typename T> struct TriviallyConstructibleTemplate {};
+
 void trivial_checks()
 {
   { int arr[T(__is_trivially_copyable(int))]; }
@@ -1848,6 +1850,11 @@ void trivial_checks()
   { int arr[F((__is_trivially_constructible(ExtDefaulted,
                                             ExtDefaulted &&)))]; }
 
+  { int arr[T((__is_trivially_constructible(TriviallyConstructibleTemplate<int>)))]; }
+  { int arr[F((__is_trivially_constructible(class_forward)))]; } // expected-error {{incomplete type 'class_forward' used in type trait expression}}
+  { int arr[F((__is_trivially_constructible(class_forward[])))]; }
+  { int arr[F((__is_trivially_constructible(void)))]; }
+
   { int arr[T((__is_trivially_assignable(int&, int)))]; }
   { int arr[T((__is_trivially_assignable(int&, int&)))]; }
   { int arr[T((__is_trivially_assignable(int&, int&&)))]; }





More information about the cfe-commits mailing list