r218602 - Fix bug 20116 - http://llvm.org/bugs/show_bug.cgi?id=20116

Alexey Bataev a.bataev at hotmail.com
Mon Sep 29 03:32:21 PDT 2014


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();
   }





More information about the cfe-commits mailing list