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> llvm-svn: 190482
This commit is contained in:
parent
8b4e379de3
commit
9ea1e16747
|
@ -3523,21 +3523,21 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
|
||||||
return false;
|
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) {
|
for (unsigned I = 0, N = Args.size(); I != N; ++I) {
|
||||||
if (Args[I]->getType()->isVoidType()) {
|
QualType ArgTy = Args[I]->getType();
|
||||||
SawVoid = true;
|
if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!Args[I]->getType()->isIncompleteType() &&
|
if (S.RequireCompleteType(KWLoc, ArgTy,
|
||||||
S.RequireCompleteType(KWLoc, Args[I]->getType(),
|
|
||||||
diag::err_incomplete_type_used_in_type_trait_expr))
|
diag::err_incomplete_type_used_in_type_trait_expr))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If any argument was 'void', of course it won't type-check.
|
// Make sure the first argument is a complete type.
|
||||||
if (SawVoid)
|
if (Args[0]->getType()->isIncompleteType())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs;
|
SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs;
|
||||||
|
|
|
@ -1571,7 +1571,7 @@ template<typename T> struct DerivedB : BaseA<T> { };
|
||||||
template<typename T> struct CrazyDerived : T { };
|
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>
|
template <typename Base, typename Derived>
|
||||||
void isBaseOfT() {
|
void isBaseOfT() {
|
||||||
|
@ -1770,6 +1770,8 @@ void is_trivial()
|
||||||
{ int arr[F(__is_trivial(cvoid))]; }
|
{ int arr[F(__is_trivial(cvoid))]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> struct TriviallyConstructibleTemplate {};
|
||||||
|
|
||||||
void trivial_checks()
|
void trivial_checks()
|
||||||
{
|
{
|
||||||
{ int arr[T(__is_trivially_copyable(int))]; }
|
{ int arr[T(__is_trivially_copyable(int))]; }
|
||||||
|
@ -1848,6 +1850,11 @@ void trivial_checks()
|
||||||
{ int arr[F((__is_trivially_constructible(ExtDefaulted,
|
{ int arr[F((__is_trivially_constructible(ExtDefaulted,
|
||||||
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&)))]; }
|
{ int arr[T((__is_trivially_assignable(int&, int&)))]; }
|
||||||
{ int arr[T((__is_trivially_assignable(int&, int&&)))]; }
|
{ int arr[T((__is_trivially_assignable(int&, int&&)))]; }
|
||||||
|
|
Loading…
Reference in New Issue