Emit an lvalue dynamic_cast even if the result is not used. Another
part (or possibly all) of PR7132.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103810 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index ce9ad48..5a1516c 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -178,7 +178,7 @@
//===----------------------------------------------------------------------===//
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
- if (!DestPtr) {
+ if (!DestPtr && E->getCastKind() != CastExpr::CK_Dynamic) {
Visit(E->getSubExpr());
return;
}
@@ -186,6 +186,20 @@
switch (E->getCastKind()) {
default: assert(0 && "Unhandled cast kind!");
+ case CastExpr::CK_Dynamic: {
+ assert(isa<CXXDynamicCastExpr>(E) && "CK_Dynamic without a dynamic_cast?");
+ LValue LV = CGF.EmitCheckedLValue(E->getSubExpr());
+ // FIXME: Do we also need to handle property references here?
+ if (LV.isSimple())
+ CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
+ else
+ CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
+
+ if (DestPtr)
+ CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
+ break;
+ }
+
case CastExpr::CK_ToUnion: {
// GCC union extension
QualType PtrTy =
diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp
index 572b521..2bf1aee 100644
--- a/test/CodeGenCXX/dynamic-cast.cpp
+++ b/test/CodeGenCXX/dynamic-cast.cpp
@@ -10,7 +10,7 @@
// CHECK: call i8* @__dynamic_cast
// CHECK: br i1
// CHECK: invoke void @__cxa_bad_cast() noreturn
- return dynamic_cast<const B&>(*a);
+ dynamic_cast<const B&>(*a);
} catch (std::bad_cast&) {
// CHECK: call i8* @llvm.eh.exception
// CHECK: {{call.*llvm.eh.selector.*_ZTISt8bad_cast}}