@@ -1293,6 +1293,27 @@ cxx_eval_call_expression (const constexp
if (!DECL_INITIAL (fun)
&& DECL_TEMPLOID_INSTANTIATION (fun))
{
+ tree d = fun;
+ if (DECL_CLONED_FUNCTION_P (d))
+ d = DECL_CLONED_FUNCTION (d);
+ d = template_for_substitution (d);
+ if (DECL_TEMPLATE_RESULT (d) == current_function_decl)
+ {
+ /* A call to the current function template, i.e.
+ template <typename T>
+ constexpr int f (int i) {
+ constexpr int j = f<T>(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;
+ }
+
++function_depth;
instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
--function_depth;
@@ -0,0 +1,26 @@
+// 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;
+}
+
+template <int N>
+constexpr int f2 ()
+{
+ enum E { a = f2<0> () };
+ 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;
+}
+
+constexpr int c = f1<0> ();
+constexpr int d = f3 ();