summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp1
-rw-r--r--clang/lib/Parse/Parser.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp8
-rw-r--r--clang/test/Parser/DelayedTemplateParsing.cpp7
4 files changed, 14 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 6bab7988cf0..863a09e89d3 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -115,6 +115,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
// the tokens and store them for parsing at the end of the translation unit.
if (getLangOpts().DelayedTemplateParsing &&
DefinitionKind == FDK_Definition &&
+ !D.getDeclSpec().isConstexprSpecified() &&
((Actions.CurContext->isDependentContext() ||
(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) &&
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 9b6c97ac195..d95546af8ab 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -990,9 +990,9 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// In delayed template parsing mode, for function template we consume the
// tokens and store them for late parsing at the end of the translation unit.
- if (getLangOpts().DelayedTemplateParsing &&
- Tok.isNot(tok::equal) &&
- TemplateInfo.Kind == ParsedTemplateInfo::Template) {
+ if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
+ TemplateInfo.Kind == ParsedTemplateInfo::Template &&
+ !D.getDeclSpec().isConstexprSpecified()) {
MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams);
ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 56eeab3bea3..c842ed035d8 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11088,8 +11088,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
// However, they cannot be referenced if they are deleted, and they are
// deleted whenever the implicit definition of the special member would
// fail.
- if (!(Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing) ||
- Func->getBody())
+ if (!Func->isConstexpr() || Func->getBody())
return;
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func);
if (!Func->isImplicitlyInstantiable() && (!MD || MD->isUserProvided()))
@@ -11180,14 +11179,13 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
}
}
- if (!AlreadyInstantiated ||
- (Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing)) {
+ if (!AlreadyInstantiated || Func->isConstexpr()) {
if (isa<CXXRecordDecl>(Func->getDeclContext()) &&
cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass() &&
ActiveTemplateInstantiations.size())
PendingLocalImplicitInstantiations.push_back(
std::make_pair(Func, PointOfInstantiation));
- else if (Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing)
+ else if (Func->isConstexpr())
// Do not defer instantiations of constexpr functions, to avoid the
// expression evaluator needing to call back into Sema if it sees a
// call to such a function.
diff --git a/clang/test/Parser/DelayedTemplateParsing.cpp b/clang/test/Parser/DelayedTemplateParsing.cpp
index 201fe1b466d..73128c49f24 100644
--- a/clang/test/Parser/DelayedTemplateParsing.cpp
+++ b/clang/test/Parser/DelayedTemplateParsing.cpp
@@ -114,3 +114,10 @@ void LLVMBuildStructGEP() { CreateConstInBoundsGEP2_32(); }
}
+namespace PR17661 {
+template <typename T>
+constexpr T Fun(T A) { return T(0); }
+
+constexpr int Var = Fun(20);
+}
+
OpenPOWER on IntegriCloud