aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-05-08 23:58:07 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-05-08 23:58:07 -0400
commit785b887ee8ef5c48ffe99f2a9c5bb9612f98423f (patch)
tree06c055f14e319afdc2ae32be2e5769e4ba286913
parent7d5e76c8de1b6c4b2ae5576ab909dc9e580b216b (diff)
downloadgcc-785b887ee8ef5c48ffe99f2a9c5bb9612f98423f.zip
gcc-785b887ee8ef5c48ffe99f2a9c5bb9612f98423f.tar.gz
gcc-785b887ee8ef5c48ffe99f2a9c5bb9612f98423f.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/error.c24
-rw-r--r--gcc/cp/except.c11
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/g++.dg/ext/vla4.C2
5 files changed, 36 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c2ce5d9..7a1484f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2013-05-08 Jason Merrill <jason@redhat.com>
+ * 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 bd463ea..a75fc4e 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 b762a51..be003d2 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 a06a23a..2165649 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 ecec908..90e4160 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" }
}
}