r212551 - PR20227: materialize a temporary when dynamic_casting a class prvalue to a

Richard Smith richard-llvm at metafoo.co.uk
Tue Jul 8 10:25:15 PDT 2014


Author: rsmith
Date: Tue Jul  8 12:25:14 2014
New Revision: 212551

URL: http://llvm.org/viewvc/llvm-project?rev=212551&view=rev
Log:
PR20227: materialize a temporary when dynamic_casting a class prvalue to a
reference type.

Modified:
    cfe/trunk/lib/Sema/SemaCast.cpp
    cfe/trunk/test/CodeGenCXX/temporaries.cpp

Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=212551&r1=212550&r2=212551&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Tue Jul  8 12:25:14 2014
@@ -600,6 +600,11 @@ void CastOperation::CheckDynamicCast() {
     }
     SrcPointee = SrcType;
   } else {
+    // If we're dynamic_casting from a prvalue to an rvalue reference, we need
+    // to materialize the prvalue before we bind the reference to it.
+    if (SrcExpr.get()->isRValue())
+      SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+          SrcType, SrcExpr.get(), /*IsLValueReference*/false);
     SrcPointee = SrcType;
   }
 
@@ -648,7 +653,7 @@ void CastOperation::CheckDynamicCast() {
       SrcExpr = ExprError();
       return;
     }
-        
+
     Kind = CK_DerivedToBase;
 
     // If we are casting to or through a virtual base class, we need a
@@ -1156,6 +1161,9 @@ TryStaticReferenceDowncast(Sema &Self, E
 
   QualType DestPointee = DestReference->getPointeeType();
 
+  // FIXME: If the source is a prvalue, we should issue a warning (because the
+  // cast always has undefined behavior), and for AST consistency, we should
+  // materialize a temporary.
   return TryStaticDowncast(Self, 
                            Self.Context.getCanonicalType(SrcExpr->getType()), 
                            Self.Context.getCanonicalType(DestPointee), CStyle,

Modified: cfe/trunk/test/CodeGenCXX/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/temporaries.cpp?rev=212551&r1=212550&r2=212551&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/temporaries.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/temporaries.cpp Tue Jul  8 12:25:14 2014
@@ -27,6 +27,21 @@ namespace PR16263 {
   // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
 }
 
+namespace PR20227 {
+  struct A { ~A(); };
+  struct B { virtual ~B(); };
+  struct C : B {};
+
+  A &&a = dynamic_cast<A&&>(A{});
+  // CHECK: @_ZGRN7PR202271aE_ = private global
+
+  B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271bE_ = private global
+
+  B &&c = static_cast<C&&>(static_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271cE_ = private global
+}
+
 struct A {
   A();
   ~A();





More information about the cfe-commits mailing list