Commit 56632b27 by Jason Merrill Committed by Jason Merrill

Handle C++14 constexpr flow control.

	* constexpr.c (cxx_eval_loop_expr, cxx_eval_switch_expr): New.
	(cxx_eval_statement_list): New.
	(cxx_eval_constant_expression): Handle LABEL_EXPR,
	CASE_LABEL_EXPR, GOTO_EXPR, LOOP_EXPR, SWITCH_EXPR.  Handle jump
	semantics of RETURN_EXPR.
	(many functions): Add jump_target parameter.
	(returns, breaks, continues, switches, label_matches): New.
	* cp-tree.h (LABEL_DECL_BREAK, LABEL_DECL_CONTINUE): New.
	* cp-gimplify.c (begin_bc_block): Set them.

From-SVN: r217670
parent 27d93d2c
2014-11-17 Jason Merrill <jason@redhat.com>
Handle C++14 constexpr flow control.
* constexpr.c (cxx_eval_loop_expr, cxx_eval_switch_expr): New.
(cxx_eval_statement_list): New.
(cxx_eval_constant_expression): Handle LABEL_EXPR,
CASE_LABEL_EXPR, GOTO_EXPR, LOOP_EXPR, SWITCH_EXPR. Handle jump
semantics of RETURN_EXPR.
(many functions): Add jump_target parameter.
(returns, breaks, continues, switches, label_matches): New.
* cp-tree.h (LABEL_DECL_BREAK, LABEL_DECL_CONTINUE): New.
* cp-gimplify.c (begin_bc_block): Set them.
* cp-gimplify.c (genericize_cp_loop): Use LOOP_EXPR.
(genericize_for_stmt): Handle null statement-list.
......
......@@ -74,6 +74,10 @@ begin_bc_block (enum bc_t bc, location_t location)
tree label = create_artificial_label (location);
DECL_CHAIN (label) = bc_label[bc];
bc_label[bc] = label;
if (bc == bc_break)
LABEL_DECL_BREAK (label) = true;
else
LABEL_DECL_CONTINUE (label) = true;
return label;
}
......
......@@ -148,12 +148,14 @@ c-common.h, not after.
DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL)
DECL_MUTABLE_P (in FIELD_DECL)
DECL_DEPENDENT_P (in USING_DECL)
LABEL_DECL_BREAK (in LABEL_DECL)
1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
USING_DECL_TYPENAME_P (in USING_DECL)
DECL_VLA_CAPTURE_P (in FIELD_DECL)
DECL_ARRAY_PARAMETER_P (in PARM_DECL)
LABEL_DECL_CONTINUE (in LABEL_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
3: DECL_IN_AGGR_P.
......@@ -3243,6 +3245,14 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define DECL_LOCAL_FUNCTION_P(NODE) \
DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE))
/* Nonzero if NODE is the target for genericization of 'break' stmts. */
#define LABEL_DECL_BREAK(NODE) \
DECL_LANG_FLAG_0 (LABEL_DECL_CHECK (NODE))
/* Nonzero if NODE is the target for genericization of 'continue' stmts. */
#define LABEL_DECL_CONTINUE(NODE) \
DECL_LANG_FLAG_1 (LABEL_DECL_CHECK (NODE))
/* True if NODE was declared with auto in its return type, but it has
started compilation and so the return type might have been changed by
return type deduction; its declared return type should be found in
......
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
int j = 0;
for (; i > 0; --i)
++j;
return j;
}
constexpr int i = f(42);
#define SA(X) static_assert((X),#X)
SA(i==42);
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
return 24;
return 36;
}
constexpr int i = f(42);
#define SA(X) static_assert((X),#X)
SA(i==24);
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
}
constexpr int i = f(42); // { dg-error "flows off the end" }
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
switch (i)
{
case 1:
return 42;
default:
return 0;
}
}
constexpr int i = f(1);
#define SA(X) static_assert((X),#X)
SA(i==42);
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
int j = 0;
switch (i)
{
case 1:
j = 42;
break;
default:
j = 24;
break;
}
return j;
}
constexpr int i = f(1);
#define SA(X) static_assert((X),#X)
SA(i==42);
// { dg-do compile { target c++14 } }
constexpr int f (int i)
{
int j = 0;
switch (i)
{
case 1:
j = 42;
break;
default:
j = 24;
break;
}
return j;
}
constexpr int i = f(2);
#define SA(X) static_assert((X),#X)
SA(i==24);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment