}
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;
}
SrcExpr = ExprError();
return;
}
-
+
Kind = CK_DerivedToBase;
// If we are casting to or through a virtual base class, we need a
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,
// 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();