From: Jason Merrill Date: Thu, 9 May 2013 03:58:07 +0000 (-0400) Subject: except.c (is_admissible_throw_operand_or_catch_parameter): Check variably_modified_ty... X-Git-Tag: releases/gcc-4.9.0~5979 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=785b887ee8ef5c48ffe99f2a9c5bb9612f98423f;p=thirdparty%2Fgcc.git except.c (is_admissible_throw_operand_or_catch_parameter): Check variably_modified_type_p. * except.c (is_admissible_throw_operand_or_catch_parameter): Check variably_modified_type_p. (expand_start_catch_block): Mark the typeinfo used here. * semantics.c (finish_handler_parms): Not here. * error.c (dump_type_suffix): Try harder on VLA length. From-SVN: r198732 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2ce5d930870..7a1484fa43f2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2013-05-08 Jason Merrill + * except.c (is_admissible_throw_operand_or_catch_parameter): Check + variably_modified_type_p. + (expand_start_catch_block): Mark the typeinfo used here. + * semantics.c (finish_handler_parms): Not here. + + * error.c (dump_type_suffix): Try harder on VLA length. + Core 624/N2932 * init.c (throw_bad_array_new_length): New. (build_new_1): Use it. Don't warn about braced-init-list. diff --git a/gcc/cp/error.c b/gcc/cp/error.c index bd463eaa80f2..a75fc4e7b33b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -848,14 +848,24 @@ dump_type_suffix (tree t, int flags) pp_character (cxx_pp, '0'); else if (host_integerp (max, 0)) pp_wide_integer (cxx_pp, tree_low_cst (max, 0) + 1); - else if (TREE_CODE (max) == MINUS_EXPR) - dump_expr (TREE_OPERAND (max, 0), - flags & ~TFF_EXPR_IN_PARENS); else - dump_expr (fold_build2_loc (input_location, - PLUS_EXPR, dtype, max, - build_int_cst (dtype, 1)), - flags & ~TFF_EXPR_IN_PARENS); + { + STRIP_NOPS (max); + if (TREE_CODE (max) == SAVE_EXPR) + max = TREE_OPERAND (max, 0); + if (TREE_CODE (max) == MINUS_EXPR + || TREE_CODE (max) == PLUS_EXPR) + { + max = TREE_OPERAND (max, 0); + while (CONVERT_EXPR_P (max)) + max = TREE_OPERAND (max, 0); + } + else + max = fold_build2_loc (input_location, + PLUS_EXPR, dtype, max, + build_int_cst (dtype, 1)); + dump_expr (max, flags & ~TFF_EXPR_IN_PARENS); + } } pp_cxx_right_bracket (cxx_pp); dump_type_suffix (TREE_TYPE (t), flags); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index b762a51c67a0..be003d2994bf 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -490,6 +490,7 @@ expand_start_catch_block (tree decl) decl = error_mark_node; type = prepare_eh_type (TREE_TYPE (decl)); + mark_used (eh_type_info (type)); } else type = NULL_TREE; @@ -982,6 +983,16 @@ is_admissible_throw_operand_or_catch_parameter (tree t, bool is_throw) "reference type %qT", type); return false; } + else if (variably_modified_type_p (type, NULL_TREE)) + { + if (is_throw) + error ("cannot throw expression of type %qT because it involves " + "types of variable size", type); + else + error ("cannot catch type %qT because it involves types of " + "variable size", type); + return false; + } return true; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index a06a23a13ac7..2165649313d4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1199,8 +1199,6 @@ finish_handler_parms (tree decl, tree handler) else type = expand_start_catch_block (decl); HANDLER_TYPE (handler) = type; - if (!processing_template_decl && type) - mark_used (eh_type_info (type)); } /* Finish a handler, which may be given by HANDLER. The BLOCKs are diff --git a/gcc/testsuite/g++.dg/ext/vla4.C b/gcc/testsuite/g++.dg/ext/vla4.C index ecec908074d5..90e4160679a9 100644 --- a/gcc/testsuite/g++.dg/ext/vla4.C +++ b/gcc/testsuite/g++.dg/ext/vla4.C @@ -6,7 +6,7 @@ void f(int i) { try { int a[i]; - throw &a; // { dg-error "variable size" } + throw &a; // { dg-error "int \\(\\*\\)\\\[i\\\]" } } catch (int (*)[i]) { // { dg-error "variable size" } } }