Add condition to MUST_NOT_THROW_EXPR.
gcc/cp/ * cp-tree.def (MUST_NOT_THROW_EXPR): Add condition parameter. * cp-tree.h (MUST_NOT_THROW_COND): New. (build_must_not_throw_expr): Declare. * dump.c (cp_dump_tree): Dump MUST_NOT_THROW_EXPR condition. * except.c (build_must_not_throw_expr): New. (initialize_handler_parm): Use it. (begin_eh_spec_block, wrap_cleanups_r): Adapt to condition. * pt.c (tsubst_expr): Handle MUST_NOT_THROW_EXPR. From-SVN: r182233
This commit is contained in:
parent
5f23640f57
commit
f2162c3daa
|
@ -1,3 +1,14 @@
|
|||
2011-12-12 Torvald Riegel <triegel@redhat.com>
|
||||
|
||||
* cp-tree.def (MUST_NOT_THROW_EXPR): Add condition parameter.
|
||||
* cp-tree.h (MUST_NOT_THROW_COND): New.
|
||||
(build_must_not_throw_expr): Declare.
|
||||
* dump.c (cp_dump_tree): Dump MUST_NOT_THROW_EXPR condition.
|
||||
* except.c (build_must_not_throw_expr): New.
|
||||
(initialize_handler_parm): Use it.
|
||||
(begin_eh_spec_block, wrap_cleanups_r): Adapt to condition.
|
||||
* pt.c (tsubst_expr): Handle MUST_NOT_THROW_EXPR.
|
||||
|
||||
2011-12-12 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR lto/51262
|
||||
|
|
|
@ -281,8 +281,9 @@ DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2)
|
|||
DEFTREECODE (HANDLER, "handler", tcc_statement, 2)
|
||||
|
||||
/* A MUST_NOT_THROW_EXPR wraps an expression that may not
|
||||
throw, and must call terminate if it does. */
|
||||
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 1)
|
||||
throw, and must call terminate if it does. The second argument
|
||||
is a condition, used in templates to express noexcept (condition). */
|
||||
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2)
|
||||
|
||||
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
||||
constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
|
||||
|
|
|
@ -3016,6 +3016,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
#define VEC_INIT_EXPR_VALUE_INIT(NODE) \
|
||||
TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE))
|
||||
|
||||
/* The condition under which this MUST_NOT_THROW_EXPR actually blocks
|
||||
exceptions. NULL_TREE means 'true'. */
|
||||
#define MUST_NOT_THROW_COND(NODE) \
|
||||
TREE_OPERAND (MUST_NOT_THROW_EXPR_CHECK (NODE), 1)
|
||||
|
||||
/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
|
||||
TEMPLATE_DECL. This macro determines whether or not a given class
|
||||
type is really a template type, as opposed to an instantiation or
|
||||
|
@ -5148,6 +5153,7 @@ extern bool type_noexcept_p (const_tree);
|
|||
extern bool type_throw_all_p (const_tree);
|
||||
extern tree build_noexcept_spec (tree, int);
|
||||
extern void choose_personality_routine (enum languages);
|
||||
extern tree build_must_not_throw_expr (tree,tree);
|
||||
extern tree eh_type_info (tree);
|
||||
extern tree begin_eh_spec_block (void);
|
||||
extern void finish_eh_spec_block (tree, tree);
|
||||
|
|
|
@ -413,6 +413,7 @@ cp_dump_tree (void* dump_info, tree t)
|
|||
case MUST_NOT_THROW_EXPR:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("body", TREE_OPERAND (t, 0));
|
||||
dump_child ("cond", MUST_NOT_THROW_COND (t));
|
||||
break;
|
||||
|
||||
case USING_STMT:
|
||||
|
|
|
@ -374,6 +374,28 @@ choose_personality_routine (enum languages lang)
|
|||
state = gave_error;
|
||||
}
|
||||
|
||||
/* Wrap EXPR in a MUST_NOT_THROW_EXPR expressing that EXPR must
|
||||
not throw any exceptions if COND is true. A condition of
|
||||
NULL_TREE is treated as 'true'. */
|
||||
|
||||
tree
|
||||
build_must_not_throw_expr (tree body, tree cond)
|
||||
{
|
||||
tree type = body ? TREE_TYPE (body) : void_type_node;
|
||||
|
||||
if (cond && !value_dependent_expression_p (cond))
|
||||
{
|
||||
cond = cxx_constant_value (cond);
|
||||
if (integer_zerop (cond))
|
||||
return body;
|
||||
else if (integer_onep (cond))
|
||||
cond = NULL_TREE;
|
||||
}
|
||||
|
||||
return build2 (MUST_NOT_THROW_EXPR, type, body, cond);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the catch parameter DECL. */
|
||||
|
||||
static void
|
||||
|
@ -418,7 +440,7 @@ initialize_handler_parm (tree decl, tree exp)
|
|||
/* Force cleanups now to avoid nesting problems with the
|
||||
MUST_NOT_THROW_EXPR. */
|
||||
init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
|
||||
init = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (init), init);
|
||||
init = build_must_not_throw_expr (init, NULL_TREE);
|
||||
}
|
||||
|
||||
decl = pushdecl (decl);
|
||||
|
@ -560,7 +582,8 @@ begin_eh_spec_block (void)
|
|||
MUST_NOT_THROW_EXPR. */
|
||||
if (TYPE_NOEXCEPT_P (TREE_TYPE (current_function_decl)))
|
||||
{
|
||||
r = build_stmt (spec_location, MUST_NOT_THROW_EXPR, NULL_TREE);
|
||||
r = build_stmt (spec_location, MUST_NOT_THROW_EXPR,
|
||||
NULL_TREE, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (r) = 1;
|
||||
}
|
||||
else
|
||||
|
@ -664,7 +687,8 @@ wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|||
cleanup = TARGET_EXPR_CLEANUP (exp);
|
||||
if (cleanup)
|
||||
{
|
||||
cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
|
||||
cleanup = build2 (MUST_NOT_THROW_EXPR, void_type_node, cleanup,
|
||||
NULL_TREE);
|
||||
TARGET_EXPR_CLEANUP (exp) = cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -13260,6 +13260,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
|
|||
}
|
||||
break;
|
||||
|
||||
case MUST_NOT_THROW_EXPR:
|
||||
return build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)),
|
||||
RECUR (MUST_NOT_THROW_COND (t)));
|
||||
|
||||
case EXPR_PACK_EXPANSION:
|
||||
error ("invalid use of pack expansion expression");
|
||||
return error_mark_node;
|
||||
|
|
Loading…
Reference in New Issue