From: Rafael Espindola Date: Thu, 28 Jun 2012 15:11:39 +0000 (+0000) Subject: Disable devirtualization when we have covariant returns. I will open a bug X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a889e47bd5a8d08a705a87962a35a504728d7f6;p=clang Disable devirtualization when we have covariant returns. I will open a bug for tracking this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159351 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 100ef02af1..4b0bff0ad0 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -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; diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp index d1deb77fa8..634bf84b41 100644 --- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp +++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp @@ -152,3 +152,37 @@ namespace Test8 { return static_cast(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(x)->f(); + } +}