summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorSunil Srivastava <sunil_srivastava@playstation.sony.com>2017-06-20 22:08:44 +0000
committerSunil Srivastava <sunil_srivastava@playstation.sony.com>2017-06-20 22:08:44 +0000
commit15ed29290643d2ee25e6b2368cda8c594abc6d7b (patch)
tree70a01234f48c026c7d922fff5990c1419490b081 /clang/lib/CodeGen/CGClass.cpp
parent0d93185b2c9eb4339750ec4d4197da2743295606 (diff)
downloadbcm5719-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.cpp13
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.
OpenPOWER on IntegriCloud