diff options
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | clang/test/Parser/DelayedTemplateParsing.cpp | 7 |
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); +} + |