diff options
author | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-12 12:05:18 +0000 |
---|---|---|
committer | torvald <torvald@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-12-12 12:05:18 +0000 |
commit | f9069149bc72f85750425dc89b7075cb1572b438 (patch) | |
tree | ac7dd9b4a8d33d3c0e997a93a36a45d93fac060b | |
parent | 273d05b3ed91fa47a5fb9ef16592f3d7eeb527b2 (diff) | |
download | gcc-f9069149bc72f85750425dc89b7075cb1572b438.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182233 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/dump.c | 1 | ||||
-rw-r--r-- | gcc/cp/except.c | 30 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 |
6 files changed, 52 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1ba9f347a17..d553dce240e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 5fc5496ef9e..83e0b5baab6 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 955d0eb3668..c28b2297486 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index d1631fc35cd..a461094f504 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -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: diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 670a66f1611..c56dc2c734b 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bb5aa0c1484..f5a31752506 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; |