diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-05-13 23:35:21 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-05-13 23:35:21 +0000 |
commit | 3413400f823bef1658c557cfb0c0a115db64be44 (patch) | |
tree | 1e3afe7a1d4d8d9ea73bceb42877863d65efc49d /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 826065ea2b47b6ecbb2b735735d7793686b95dc2 (diff) | |
download | clang-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.cpp | 12 |
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(); |