[cfe-commits] r163555 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/SemaCXX/conditional-expr.cpp

David Blaikie dblaikie at gmail.com
Mon Sep 10 15:05:41 PDT 2012


Author: dblaikie
Date: Mon Sep 10 17:05:41 2012
New Revision: 163555

URL: http://llvm.org/viewvc/llvm-project?rev=163555&view=rev
Log:
Fix PR13784: instantiation of an abstract class in a conditional operator.

A couple of missing "RequireNonAbstractType" calls in conditional operator
handling. I looked for opportunities to tie this check in to all relevant
callers of PerformCopyInitialization (couldn't be all callers since this is
called for base subobject copying too, where it's acceptable to copy abstract
types) but the callers varied too much & in many cases had substantial code
or conditionals on the RequireNonAbstractType call, the
PerformCopyInitialization call, or the code between the two calls.

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaCXX/conditional-expr.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=163555&r1=163554&r2=163555&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Sep 10 17:05:41 2012
@@ -4149,6 +4149,9 @@
     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 @@
   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);

Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=163555&r1=163554&r2=163555&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Mon Sep 10 17:05:41 2012
@@ -57,6 +57,16 @@
   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 @@
   // 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 {





More information about the cfe-commits mailing list