aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2015-06-29 13:12:44 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2015-06-29 13:12:44 +0000
commitb155cfd9288996f3a1044fb2463c7ac7e757a0df (patch)
tree8bc44969367937690b20314e2432d485c707678f /gcc/cp
parent99e943a2be4bb7ec0d51b5a68e44d0d42dd9347a (diff)
downloadgcc-b155cfd9288996f3a1044fb2463c7ac7e757a0df.zip
gcc-b155cfd9288996f3a1044fb2463c7ac7e757a0df.tar.gz
gcc-b155cfd9288996f3a1044fb2463c7ac7e757a0df.tar.bz2
re PR c/66322 (Linus Torvalds: -Wswitch-bool produces dubious warnings, fails to notice really bad things)
PR c/66322 * c-common.c (check_case_bounds): Add bool * parameter. Set OUTSIDE_RANGE_P. (c_add_case_label): Add bool * parameter. Pass it down to check_case_bounds. (c_do_switch_warnings): Add bool parameters. Implement -Wswitch-bool warning here. * c-common.h (c_add_case_label, c_do_switch_warnings): Update declarations. * c-typeck.c (struct c_switch): Add BOOL_COND_P and OUTSIDE_RANGE_P. (c_start_case): Set BOOL_COND_P and OUTSIDE_RANGE_P. Don't warn about -Wswitch-bool here. (do_case): Update c_add_case_label call. (c_finish_case): Update c_do_switch_warnings call. * decl.c (struct cp_switch): Add OUTSIDE_RANGE_P. (push_switch): Set OUTSIDE_RANGE_P. (pop_switch): Update c_do_switch_warnings call. (finish_case_label): Update c_add_case_label call. * semantics.c (finish_switch_cond): Don't warn about -Wswitch-bool here. * function.c (stack_protect_epilogue): Remove a cast to int. * doc/invoke.texi: Update -Wswitch-bool description. * c-c++-common/pr60439.c: Add dg-prune-output and add switch cases. * c-c++-common/pr66322.c: New test. * g++.dg/eh/scope1.C: Remove dg-warning. From-SVN: r225116
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/cp/semantics.c5
3 files changed, 21 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4a3b2d8..c16b068 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2015-06-29 Marek Polacek <polacek@redhat.com>
+
+ PR c/66322
+ * decl.c (struct cp_switch): Add OUTSIDE_RANGE_P.
+ (push_switch): Set OUTSIDE_RANGE_P.
+ (pop_switch): Update c_do_switch_warnings call.
+ (finish_case_label): Update c_add_case_label call.
+ * semantics.c (finish_switch_cond): Don't warn about -Wswitch-bool
+ here.
+
2015-06-27 Marek Polacek <polacek@redhat.com>
* call.c: Use VECTOR_TYPE_P.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0683f26..498ed71 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3208,6 +3208,9 @@ struct cp_switch
label. We need a tree, rather than simply a hash table, because
of the GNU case range extension. */
splay_tree cases;
+ /* Remember whether there was a case value that is outside the
+ range of the original type of the controlling expression. */
+ bool outside_range_p;
};
/* A stack of the currently active switch statements. The innermost
@@ -3229,6 +3232,7 @@ push_switch (tree switch_stmt)
p->next = switch_stack;
p->switch_stmt = switch_stmt;
p->cases = splay_tree_new (case_compare, NULL, NULL);
+ p->outside_range_p = false;
switch_stack = p;
}
@@ -3240,10 +3244,14 @@ pop_switch (void)
/* Emit warnings as needed. */
switch_location = EXPR_LOC_OR_LOC (cs->switch_stmt, input_location);
+ const bool bool_cond_p
+ = (SWITCH_STMT_TYPE (cs->switch_stmt)
+ && TREE_CODE (SWITCH_STMT_TYPE (cs->switch_stmt)) == BOOLEAN_TYPE);
if (!processing_template_decl)
c_do_switch_warnings (cs->cases, switch_location,
SWITCH_STMT_TYPE (cs->switch_stmt),
- SWITCH_STMT_COND (cs->switch_stmt));
+ SWITCH_STMT_COND (cs->switch_stmt),
+ bool_cond_p, cs->outside_range_p);
splay_tree_delete (cs->cases);
switch_stack = switch_stack->next;
@@ -3308,7 +3316,8 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
high_value = case_conversion (type, high_value);
r = c_add_case_label (loc, switch_stack->cases, cond, type,
- low_value, high_value);
+ low_value, high_value,
+ &switch_stack->outside_range_p);
/* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4b8ce3b..c23d9be 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1156,11 +1156,6 @@ finish_switch_cond (tree cond, tree switch_stmt)
orig_type = TREE_TYPE (cond);
if (cond != error_mark_node)
{
- /* Warn if the condition has boolean value. */
- if (TREE_CODE (orig_type) == BOOLEAN_TYPE)
- warning_at (input_location, OPT_Wswitch_bool,
- "switch condition has type bool");
-
/* [stmt.switch]
Integral promotions are performed. */