]> granicus.if.org Git - clang/commitdiff
When trying to get the most derived class, don't assume that we can ignore all casts...
authorAnders Carlsson <andersca@mac.com>
Sat, 29 Jan 2011 05:04:11 +0000 (05:04 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 29 Jan 2011 05:04:11 +0000 (05:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124528 91177308-0d34-0410-b5e6-96231b3b80d8

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

index fa6ac5469f8c49957e34c5331db69d7be7c5c401..99c54f0456b8830e31d6d40c697a08405e7fd70f 100644 (file)
@@ -54,7 +54,23 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
 }
 
 static const CXXRecordDecl *getMostDerivedClassDecl(const Expr *Base) {
-  QualType DerivedType = Base->IgnoreParenCasts()->getType();
+  const Expr *E = Base;
+  
+  while (true) {
+    E = E->IgnoreParens();
+    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+      if (CE->getCastKind() == CK_DerivedToBase || 
+          CE->getCastKind() == CK_UncheckedDerivedToBase ||
+          CE->getCastKind() == CK_NoOp) {
+        E = CE->getSubExpr();
+        continue;
+      }
+    }
+
+    break;
+  }
+
+  QualType DerivedType = E->getType();
   if (const PointerType *PTy = DerivedType->getAs<PointerType>())
     DerivedType = PTy->getPointeeType();
 
index 08a94903d5261046899f45769097bdf10ee4f52b..3de75ed3db541b6b17ec67148a7b9c238a6267fb 100644 (file)
@@ -36,4 +36,16 @@ namespace Test3 {
     // CHECK: call i32 @_ZN5Test31A1fEv
     return b->f();
   }
+
+  // CHECK: define i32 @_ZN5Test31fERNS_1BE
+  int f(B &b) {
+    // CHECK: call i32 @_ZN5Test31A1fEv
+    return b.f();
+  }
+
+  // CHECK: define i32 @_ZN5Test31fEPv
+  int f(void *v) {
+    // CHECK: call i32 @_ZN5Test31A1fEv
+    return static_cast<B*>(v)->f();
+  }
 }