]> granicus.if.org Git - clang/commitdiff
Sema: Respect -fdelayed-template-parsing when parsing constexpr functions
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 27 Sep 2013 04:14:12 +0000 (04:14 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 27 Sep 2013 04:14:12 +0000 (04:14 +0000)
Functions declared as constexpr must have their parsing delayed in
-fdelayed-template-parsing mode so as not to upset later template
instantiation.

N.B. My reading of the standard makes it seem like delayed template
parsing is at odds with constexpr.  We may want to make refinements in
other places in clang to make constexpr play nicer with this feature.

This fixes PR17334.

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

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

index 10ed15a290372a213588bd4b696a137cde288f9b..a52ebf6e2f61c5622e73de9e5b7c3b44ff52266b 100644 (file)
@@ -11010,7 +11010,8 @@ 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() || Func->getBody())
+    if (!(Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing) ||
+        Func->getBody())
       return;
     CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Func);
     if (!Func->isImplicitlyInstantiable() && (!MD || MD->isUserProvided()))
@@ -11101,13 +11102,14 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
       }
     }
 
-    if (!AlreadyInstantiated || Func->isConstexpr()) {
+    if (!AlreadyInstantiated ||
+        (Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing)) {
       if (isa<CXXRecordDecl>(Func->getDeclContext()) &&
           cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass() &&
           ActiveTemplateInstantiations.size())
         PendingLocalImplicitInstantiations.push_back(
             std::make_pair(Func, PointOfInstantiation));
-      else if (Func->isConstexpr())
+      else if (Func->isConstexpr() && !getLangOpts().DelayedTemplateParsing)
         // 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 3e429d411621b8ed16bbc3975e8c6586a4ecf986..201fe1b466dbec54596967b3cb72d3b3532021a9 100644 (file)
@@ -102,3 +102,15 @@ namespace rdar11700604 {
   };
 }
 
+namespace PR17334 {
+
+template <typename = void> struct ArrayRef {
+  constexpr ArrayRef() {}
+};
+template <typename = void> void CreateConstInBoundsGEP2_32() {
+  ArrayRef<> IdxList;
+}
+void LLVMBuildStructGEP() { CreateConstInBoundsGEP2_32(); }
+
+}
+