]> granicus.if.org Git - clang/commitdiff
Emit an lvalue dynamic_cast even if the result is not used. Another
authorDouglas Gregor <dgregor@apple.com>
Fri, 14 May 2010 21:31:02 +0000 (21:31 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 14 May 2010 21:31:02 +0000 (21:31 +0000)
part (or possibly all) of PR7132.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103810 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprAgg.cpp
test/CodeGenCXX/dynamic-cast.cpp

index ce9ad4886ff82e8a175302969464fd3db043bbba..5a1516cf32afe2f0c6192c5696f8ef6765082098 100644 (file)
@@ -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 =
index 572b521c9254f55e12a60a62d0497fcf6ef6d99e..2bf1aeed4921c598af4e6fb6fc50f7d851474042 100644 (file)
@@ -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}}