]> granicus.if.org Git - clang/commitdiff
Devirtualize calls on glvalues produced by class member access expressions.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Aug 2012 22:59:28 +0000 (22:59 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Aug 2012 22:59:28 +0000 (22:59 +0000)
Based on a patch by Yin Ma!

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

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

index 7c2c9f1ecb4845141c7bf3e8dcbf1106cf4eff4f..31ea1b5448a7f27cc63c7e1f3760f7fcec82e159 100644 (file)
@@ -123,7 +123,14 @@ static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context,
     
     return false;
   }
-  
+
+  // We can devirtualize calls on an object accessed by a class member access
+  // expression, since by C++11 [basic.life]p6 we know that it can't refer to
+  // a derived class object constructed in the same location.
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base))
+    if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl()))
+      return VD->getType()->isRecordType();
+
   // We can always devirtualize calls on temporary object expressions.
   if (isa<CXXConstructExpr>(Base))
     return true;
index c5a4094a53c3001f43391b179b381ec95b525cdf..7ef4864c8367e7b54fd2acdb84c15ae917c6ec76 100644 (file)
@@ -83,3 +83,20 @@ namespace test3 {
     d.B::~B();
   }
 }
+
+namespace test4 {
+  struct Animal {
+    virtual void eat();
+  };
+  struct Fish : Animal {
+    virtual void eat();
+  };
+  struct Wrapper {
+    Fish fish;
+  };
+  extern Wrapper *p;
+  void test() {
+    // CHECK: call void @_ZN5test44Fish3eatEv
+    p->fish.eat();
+  }
+}