commit 522aeea737412d552c78b58466280cf9e6c38924
Author: Jason Merrill <jason@redhat.com>
Date: Fri Apr 1 20:30:09 2016 -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.
@@ -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);
@@ -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);
}
new file mode 100644
@@ -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;
+}