]> granicus.if.org Git - clang/commitdiff
Disable devirtualization when we have covariant returns. I will open a bug
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 28 Jun 2012 15:11:39 +0000 (15:11 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 28 Jun 2012 15:11:39 +0000 (15:11 +0000)
for tracking this.

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

lib/CodeGen/CGExprCXX.cpp
test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp

index 100ef02af13be8f614b246916c472a74ec61288b..4b0bff0ad0db7f30298533195131672a3d673451 100644 (file)
@@ -202,6 +202,9 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
       // we don't have support for that yet, so do a virtual call.
       DevirtualizedMethod = NULL;
     }
+    if (DevirtualizedMethod && DevirtualizedMethod->getResultType() !=
+        MD->getResultType())
+      DevirtualizedMethod = NULL;
   }
 
   llvm::Value *This;
index d1deb77fa807e1eacdeb4725e06894cdee384b45..634bf84b416d02b757d3417b79a0a03530128a38 100644 (file)
@@ -152,3 +152,37 @@ namespace Test8 {
     return static_cast<B*>(c)->foo();
   }
 }
+
+namespace Test9 {
+  struct A {
+    int a;
+  };
+  struct B {
+    int b;
+  };
+  struct C : public B, public A {
+  };
+  struct RA {
+    virtual A *f() {
+      return 0;
+    }
+  };
+  struct RC final : public RA {
+    virtual C *f() {
+      C *x = new C();
+      x->a = 1;
+      x->b = 2;
+      return x;
+    }
+  };
+  // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
+  A *f(RC *x) {
+    // FIXME: It should be possible to devirtualize this case, but that is
+    // not implemented yet.
+    // CHECK: getelementptr
+    // CHECK-NEXT: %[[FUNC:.*]] = load
+    // CHECK-NEXT: bitcast
+    // CHECK-NEXT: = call {{.*}} %[[FUNC]]
+    return static_cast<RA*>(x)->f();
+  }
+}