diff options
author | Marek Polacek <polacek@redhat.com> | 2015-06-29 13:12:44 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2015-06-29 13:12:44 +0000 |
commit | b155cfd9288996f3a1044fb2463c7ac7e757a0df (patch) | |
tree | 8bc44969367937690b20314e2432d485c707678f /gcc/cp | |
parent | 99e943a2be4bb7ec0d51b5a68e44d0d42dd9347a (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 13 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 5 |
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. */ |