[cfe-commits] r161998 - in /cfe/trunk: lib/CodeGen/CGExprCXX.cpp test/CodeGenCXX/devirtualize-virtual-function-calls.cpp

Richard Smith richard-llvm at metafoo.co.uk
Wed Aug 15 15:59:28 PDT 2012


Author: rsmith
Date: Wed Aug 15 17:59:28 2012
New Revision: 161998

URL: http://llvm.org/viewvc/llvm-project?rev=161998&view=rev
Log:
Devirtualize calls on glvalues produced by class member access expressions.
Based on a patch by Yin Ma!

Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=161998&r1=161997&r2=161998&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Aug 15 17:59:28 2012
@@ -123,7 +123,14 @@
     
     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;

Modified: cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp?rev=161998&r1=161997&r2=161998&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp Wed Aug 15 17:59:28 2012
@@ -83,3 +83,20 @@
     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();
+  }
+}





More information about the cfe-commits mailing list