summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-05-13 23:35:21 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-05-13 23:35:21 +0000
commit3413400f823bef1658c557cfb0c0a115db64be44 (patch)
tree1e3afe7a1d4d8d9ea73bceb42877863d65efc49d /lib/Sema/SemaTemplateInstantiate.cpp
parent826065ea2b47b6ecbb2b735735d7793686b95dc2 (diff)
downloadclang-3413400f823bef1658c557cfb0c0a115db64be44.tar.gz
[c++20] P1064R0: Allow virtual function calls in constant expression
evaluation. This reinstates r360559, reverted in r360580, with a fix to avoid crashing if evaluation-for-overflow mode encounters a virtual call on an object of a class with a virtual base class, and to generally not try to resolve virtual function calls to objects whose (notional) vptrs are not readable. (The standard rules are unclear here, but this seems like a reasonable approach.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index edc281cad6..55d1d94bd8 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2082,6 +2082,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
LateInstantiatedAttrVec LateAttrs;
Instantiator.enableLateAttributeInstantiation(&LateAttrs);
+ bool MightHaveConstexprVirtualFunctions = false;
for (auto *Member : Pattern->decls()) {
// Don't instantiate members not belonging in this semantic context.
// e.g. for:
@@ -2128,6 +2129,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiation->setInvalidDecl();
break;
}
+ } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewMember)) {
+ if (MD->isConstexpr() && !MD->getFriendObjectKind() &&
+ (MD->isVirtualAsWritten() || Instantiation->getNumBases()))
+ MightHaveConstexprVirtualFunctions = true;
}
if (NewMember->isInvalidDecl())
@@ -2220,9 +2225,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Consumer.HandleTagDeclDefinition(Instantiation);
// Always emit the vtable for an explicit instantiation definition
- // of a polymorphic class template specialization.
+ // of a polymorphic class template specialization. Otherwise, eagerly
+ // instantiate only constexpr virtual functions in preparation for their use
+ // in constant evaluation.
if (TSK == TSK_ExplicitInstantiationDefinition)
MarkVTableUsed(PointOfInstantiation, Instantiation, true);
+ else if (MightHaveConstexprVirtualFunctions)
+ MarkVirtualMembersReferenced(PointOfInstantiation, Instantiation,
+ /*ConstexprOnly*/ true);
}
return Instantiation->isInvalidDecl();