re PR c++/70449 (ICE with -Wall on valid code on x86_64-linux-gnu in pp_string, at...
authorJason Merrill <jason@redhat.com>
Sat, 2 Apr 2016 01:35:45 +0000 (21:35 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 2 Apr 2016 01:35:45 +0000 (21:35 -0400)
PR c++/70449

PR c++/70344
* pt.c (instantiate_decl): A function isn't fully defined if
DECL_INITIAL is error_mark_node.
* constexpr.c (cxx_eval_call_expression): Likewise.

From-SVN: r234695

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/constexpr-recursion1.C [new file with mode: 0644]

index 24528300fce5545ee886e2fd96743576501f7bb4..a755e37d00265f1a8a2b4040fce2072f37ca742b 100644 (file)
@@ -1,3 +1,11 @@
+2016-04-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/70449
+       PR c++/70344
+       * pt.c (instantiate_decl): A function isn't fully defined if
+       DECL_INITIAL is error_mark_node.
+       * constexpr.c (cxx_eval_call_expression): Likewise.
+
 2016-04-01  Jakub Jelinek  <jakub@redhat.com>
            Marek Polacek  <polacek@redhat.com>
 
index ea605dc641b43192bf731216cd37598b41a0869a..979f01fbbb3d0adcd305945f69ca82279712834e 100644 (file)
@@ -1239,21 +1239,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       return t;
     }
 
-  if (fun == current_function_decl)
-    {
-      /* A call to the current function, i.e.
-        constexpr int f (int i) {
-          constexpr int j = f(i-1);
-          return j;
-        }
-        This would be OK without the constexpr on the declaration of j.  */
-      if (!ctx->quiet)
-       error_at (loc, "%qD called in a constant expression before its "
-                 "definition is complete", fun);
-      *non_constant_p = true;
-      return t;
-    }
-
   constexpr_ctx new_ctx = *ctx;
   if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
       && TREE_CODE (t) == AGGR_INIT_EXPR)
@@ -1308,7 +1293,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
         {
          if (!ctx->quiet)
            {
-             if (DECL_INITIAL (fun))
+             if (DECL_INITIAL (fun) == error_mark_node)
+               error_at (loc, "%qD called in a constant expression before its "
+                         "definition is complete", fun);
+             else if (DECL_INITIAL (fun))
                {
                  /* The definition of fun was somehow unsuitable.  */
                  error_at (loc, "%qD called in a constant expression", fun);
index a6398c04f85e0cdf9e187be6554276402d222c2e..2d93a5c9169e00fc5047e15a069fe1fcef23f8a6 100644 (file)
@@ -21741,7 +21741,8 @@ instantiate_decl (tree d, int defer_ok,
   if (TREE_CODE (d) == FUNCTION_DECL)
     {
       deleted_p = DECL_DELETED_FN (code_pattern);
-      pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
+      pattern_defined = ((DECL_SAVED_TREE (code_pattern) != NULL_TREE
+                         && DECL_INITIAL (code_pattern) != error_mark_node)
                         || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern)
                         || deleted_p);
     }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-recursion1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-recursion1.C
new file mode 100644 (file)
index 0000000..79e0b5a
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/70449
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wall" }
+
+template <int N>
+constexpr int f1 ()
+{
+  enum E { a = f1<0> () }; // { dg-error "called in a constant expression before its definition is complete|is not an integer constant" }
+  return 0;
+}
+
+constexpr int f3 ()
+{
+  enum E { a = f3 () };        // { dg-error "called in a constant expression before its definition is complete|is not an integer constant" }
+  return 0;
+}