diff options
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 7 | ||||
-rw-r--r-- | test/SemaCXX/conditional-expr.cpp | 13 |
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index dc5fc284dc..4dca91db13 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4149,6 +4149,9 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &NonVoid = LVoid ? RHS : LHS; if (NonVoid.get()->getType()->isRecordType() && NonVoid.get()->isGLValue()) { + if (RequireNonAbstractType(QuestionLoc, NonVoid.get()->getType(), + diag::err_allocation_of_abstract_type)) + return QualType(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(NonVoid.get()->getType()); NonVoid = PerformCopyInitialization(Entity, SourceLocation(), NonVoid); @@ -4291,7 +4294,11 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { if (LTy->isRecordType()) { // The operands have class type. Make a temporary copy. + if (RequireNonAbstractType(QuestionLoc, LTy, + diag::err_allocation_of_abstract_type)) + return QualType(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); + ExprResult LHSCopy = PerformCopyInitialization(Entity, SourceLocation(), LHS); diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index a80eda416f..7595f1dfa1 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -57,6 +57,16 @@ struct Ambig { operator signed char(); // expected-note 2 {{candidate function}} }; +struct Abstract { + virtual ~Abstract() = 0; // expected-note {{unimplemented pure virtual method '~Abstract' in 'Abstract'}} +}; + +struct Derived1: Abstract { +}; + +struct Derived2: Abstract { +}; + void test() { // This function tests C++0x 5.16 @@ -206,6 +216,9 @@ void test() // Note the thing that this does not test: since DR446, various situations // *must* create a separate temporary copy of class objects. This can only // be properly tested at runtime, though. + + const Abstract &a = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}} + true ? static_cast<const Abstract&>(Derived1()) : throw 3; // expected-error {{allocating an object of abstract class type 'const Abstract'}} } namespace PR6595 { |