diff options
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 16 | ||||
-rw-r--r-- | test/CodeGenCXX/dynamic-cast.cpp | 2 |
2 files changed, 16 insertions, 2 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index ce9ad4886f..5a1516cf32 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -178,7 +178,7 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) { //===----------------------------------------------------------------------===// void AggExprEmitter::VisitCastExpr(CastExpr *E) { - if (!DestPtr) { + if (!DestPtr && E->getCastKind() != CastExpr::CK_Dynamic) { Visit(E->getSubExpr()); return; } @@ -186,6 +186,20 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { 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 572b521c92..2bf1aeed49 100644 --- a/test/CodeGenCXX/dynamic-cast.cpp +++ b/test/CodeGenCXX/dynamic-cast.cpp @@ -10,7 +10,7 @@ const B& f(A *a) { // 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}} |