]> granicus.if.org Git - clang/commitdiff
Parse: Disable delayed template parsing for constexpr functions
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 23 Oct 2013 21:31:20 +0000 (21:31 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 23 Oct 2013 21:31:20 +0000 (21:31 +0000)
Commit r191484 treated constexpr function templates as normal function
templates with respect to delaying their parsing.  However, this is
unnecessarily restrictive because there is no compatibility concern with
constexpr, MSVC doesn't support it.

Instead, simply disable delayed template parsing for constexpr function
templates.  This largely reverts the changes made in r191484 but keeps
it's unit test.

This fixes PR17661.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193274 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseCXXInlineMethods.cpp
lib/Parse/Parser.cpp
lib/Sema/SemaExpr.cpp
test/Parser/DelayedTemplateParsing.cpp

index 6bab7988cf0bf92e5c17dfaf96f5da92231c781f..863a09e89d34c3586eef488b3882143273029b1d 100644 (file)
@@ -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)) &&
index 9b6c97ac195fb06071b8a83d20dd757edadb67db..d95546af8ab56b9be6de82851c65300614ac552a 100644 (file)
@@ -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);
index 56eeab3bea3725af3dab738d1d4e5560df8211db..c842ed035d8884e7bb9ef349b0bc96c6fac2f797 100644 (file)
@@ -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.
index 201fe1b466dbec54596967b3cb72d3b3532021a9..73128c49f247ee9bfc9d8b5edfc2580cf2d70f4b 100644 (file)
@@ -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);
+}
+