Author: abataev Date: Mon Sep 29 05:32:21 2014 New Revision: 218602 URL: http://llvm.org/viewvc/llvm-project?rev=218602&view=rev Log: Fix bug 20116 - http://llvm.org/bugs/show_bug.cgi?id=20116
Fixes incorrect codegen when devirtualization is aborted due to covariant return types. Differential Revision: http://reviews.llvm.org/D5321 Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=218602&r1=218601&r2=218602&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon Sep 29 05:32:21 2014 @@ -110,7 +110,15 @@ RValue CodeGenFunction::EmitCXXMemberCal assert(DevirtualizedMethod); const CXXRecordDecl *DevirtualizedClass = DevirtualizedMethod->getParent(); const Expr *Inner = Base->ignoreParenBaseCasts(); - if (getCXXRecord(Inner) == DevirtualizedClass) + if (DevirtualizedMethod->getReturnType().getCanonicalType() != + MD->getReturnType().getCanonicalType()) + // If the return types are not the same, this might be a case where more + // code needs to run to compensate for it. For example, the derived + // method might return a type that inherits form from the return + // type of MD and has a prefix. + // For now we just avoid devirtualizing these covariant cases. + DevirtualizedMethod = nullptr; + else if (getCXXRecord(Inner) == DevirtualizedClass) // If the class of the Inner expression is where the dynamic method // is defined, build the this pointer from it. Base = Inner; @@ -121,15 +129,6 @@ RValue CodeGenFunction::EmitCXXMemberCal // we don't have support for that yet, so do a virtual call. DevirtualizedMethod = nullptr; } - // If the return types are not the same, this might be a case where more - // code needs to run to compensate for it. For example, the derived - // method might return a type that inherits form from the return - // type of MD and has a prefix. - // For now we just avoid devirtualizing these covariant cases. - if (DevirtualizedMethod && - DevirtualizedMethod->getReturnType().getCanonicalType() != - MD->getReturnType().getCanonicalType()) - DevirtualizedMethod = nullptr; } llvm::Value *This; Modified: cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp?rev=218602&r1=218601&r2=218602&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp (original) +++ cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp Mon Sep 29 05:32:21 2014 @@ -178,9 +178,12 @@ namespace Test9 { 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: load + // CHECK: bitcast + // CHECK: [[F_PTR_RA:%.+]] = bitcast + // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]] + // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0 + // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]] // CHECK-NEXT: = call {{.*}} %[[FUNC]] return static_cast<RA*>(x)->f(); } _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
