diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-08-15 22:59:28 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-08-15 22:59:28 +0000 |
| commit | 48c15319f7db4349c8da663145a223db915a7452 (patch) | |
| tree | 34236ca9f86cc348ba3ad024ce85fb0c1ac33fa2 | |
| parent | 19c722d61df804a31aa093cff3ebf89ce9c9c0da (diff) | |
| download | bcm5719-llvm-48c15319f7db4349c8da663145a223db915a7452.tar.gz bcm5719-llvm-48c15319f7db4349c8da663145a223db915a7452.zip | |
Devirtualize calls on glvalues produced by class member access expressions.
Based on a patch by Yin Ma!
llvm-svn: 161998
| -rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 9 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp | 17 |
2 files changed, 25 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 7c2c9f1ecb4..31ea1b5448a 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -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; diff --git a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp index c5a4094a53c..7ef4864c836 100644 --- a/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp +++ b/clang/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp @@ -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(); + } +} |

