aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--lib/Sema/SemaExprCXX.cpp18
-rw-r--r--test/SemaCXX/type-traits.cpp3
3 files changed, 21 insertions, 1 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 539ed0eac5..1d45a6823d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3478,6 +3478,7 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
: TypeDiagnoser(DiagID == 0), DiagID(DiagID), SelID(SelID) { }
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+ if (Suppressed) return;
if (SelID == -1)
S.Diag(Loc, DiagID) << T;
else
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 1a3cff5bd7..27402599a4 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -3542,9 +3542,25 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
// We model the initialization as a copy-initialization of a temporary
// of the appropriate type, which for this expression is identical to the
// return statement (since NRVO doesn't apply).
+
+ // Functions aren't allowed to return function or array types.
+ if (RhsT->isFunctionType() || RhsT->isArrayType())
+ return false;
+
+ // A return statement in a void function must have void type.
+ if (RhsT->isVoidType())
+ return LhsT->isVoidType();
+
+ // A function definition requires a complete, non-abstract return type.
+ if (Self.RequireCompleteType(KeyLoc, RhsT, 0) ||
+ Self.RequireNonAbstractType(KeyLoc, RhsT, 0))
+ return false;
+
+ // Compute the result of add_rvalue_reference.
if (LhsT->isObjectType() || LhsT->isFunctionType())
LhsT = Self.Context.getRValueReferenceType(LhsT);
-
+
+ // Build a fake source and destination for initialization.
InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
Expr::getValueKindForType(LhsT));
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index bf590f9c72..54294bcbb8 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -1574,6 +1574,8 @@ struct X0 {
template<typename U> X0(const X0<U>&);
};
+struct Abstract { virtual void f() = 0; };
+
void is_convertible_to() {
{ int arr[T(__is_convertible_to(Int, Int))]; }
{ int arr[F(__is_convertible_to(Int, IntAr))]; }
@@ -1598,6 +1600,7 @@ void is_convertible_to() {
{ int arr[F(__is_convertible_to(Function, Function))]; }
{ int arr[F(__is_convertible_to(PrivateCopy, PrivateCopy))]; }
{ int arr[T(__is_convertible_to(X0<int>, X0<float>))]; }
+ { int arr[F(__is_convertible_to(Abstract, Abstract))]; }
}
namespace is_convertible_to_instantiate {