diff options
author | Sunil Srivastava <sunil_srivastava@playstation.sony.com> | 2017-06-20 22:08:44 +0000 |
---|---|---|
committer | Sunil Srivastava <sunil_srivastava@playstation.sony.com> | 2017-06-20 22:08:44 +0000 |
commit | 15ed29290643d2ee25e6b2368cda8c594abc6d7b (patch) | |
tree | 70a01234f48c026c7d922fff5990c1419490b081 /clang/lib/CodeGen/CGClass.cpp | |
parent | 0d93185b2c9eb4339750ec4d4197da2743295606 (diff) | |
download | bcm5719-llvm-15ed29290643d2ee25e6b2368cda8c594abc6d7b.tar.gz bcm5719-llvm-15ed29290643d2ee25e6b2368cda8c594abc6d7b.zip |
Prevent devirtualization of calls to un-instantiated functions.
PR 27895
Differential Revision: https://reviews.llvm.org/D22057
llvm-svn: 305862
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 5b4dc5ff0ab..127d7df348e 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2770,10 +2770,19 @@ CodeGenFunction::CanDevirtualizeMemberFunctionCall(const Expr *Base, // 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. + // a derived class object constructed in the same location. However, we avoid + // devirtualizing a call to a template function that we could instantiate + // implicitly, but have not decided to do so. This is needed because if this + // function does not get instantiated, the devirtualization will create a + // direct call to a function whose body may not exist. In contrast, calls to + // template functions that are not defined in this TU are allowed to be + // devirtualized under assumption that it is user responsibility to + // instantiate them in some other TU. if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl())) - return VD->getType()->isRecordType(); + return VD->getType()->isRecordType() && + (MD->instantiationIsPending() || MD->isDefined() || + !MD->isImplicitlyInstantiable()); // Likewise for calls on an object accessed by a (non-reference) pointer to // member access. |