diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2012-05-07 13:47:11 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2012-05-07 13:47:11 +0000 |
commit | 198fc9f199b905c51873bf17a0a3f05afe11c2c5 (patch) | |
tree | a5ea1811c388a475bd3ceecb61e1e0e756176bcc /gcc | |
parent | 7a04f01cb7752b4c9fab847cbb6775e4b020f6d9 (diff) | |
download | gcc-198fc9f199b905c51873bf17a0a3f05afe11c2c5.zip gcc-198fc9f199b905c51873bf17a0a3f05afe11c2c5.tar.gz gcc-198fc9f199b905c51873bf17a0a3f05afe11c2c5.tar.bz2 |
tree-cfg.c (verify_gimple_switch): Tighten checks.
* tree-cfg.c (verify_gimple_switch): Tighten checks.
From-SVN: r187242
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 73 |
2 files changed, 77 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 664bd50..47ede16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2012-05-07 Steven Bosscher <steven@gcc.gnu.org> + + * tree-cfg.c (verify_gimple_switch): Tighten checks. + 2012-05-07 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/53239 diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index c9f02f3..f8e1fb5 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4122,6 +4122,10 @@ verify_gimple_goto (gimple stmt) static bool verify_gimple_switch (gimple stmt) { + unsigned int i, n; + tree elt, prev_upper_bound = NULL_TREE; + tree index_type, elt_type = NULL_TREE; + if (!is_gimple_val (gimple_switch_index (stmt))) { error ("invalid operand to switch statement"); @@ -4129,6 +4133,75 @@ verify_gimple_switch (gimple stmt) return true; } + index_type = TREE_TYPE (gimple_switch_index (stmt)); + if (! INTEGRAL_TYPE_P (index_type)) + { + error ("non-integral type switch statement"); + debug_generic_expr (index_type); + return true; + } + + elt = gimple_switch_default_label (stmt); + if (CASE_LOW (elt) != NULL_TREE || CASE_HIGH (elt) != NULL_TREE) + { + error ("invalid default case label in switch statement"); + debug_generic_expr (elt); + return true; + } + + n = gimple_switch_num_labels (stmt); + for (i = 1; i < n; i++) + { + elt = gimple_switch_label (stmt, i); + + if (! CASE_LOW (elt)) + { + error ("invalid case label in switch statement"); + debug_generic_expr (elt); + return true; + } + if (CASE_HIGH (elt) + && ! tree_int_cst_lt (CASE_LOW (elt), CASE_HIGH (elt))) + { + error ("invalid case range in switch statement"); + debug_generic_expr (elt); + return true; + } + + if (elt_type) + { + if (TREE_TYPE (CASE_LOW (elt)) != elt_type + || (CASE_HIGH (elt) && TREE_TYPE (CASE_HIGH (elt)) != elt_type)) + { + error ("type mismatch for case label in switch statement"); + debug_generic_expr (elt); + return true; + } + } + else + { + elt_type = TREE_TYPE (CASE_LOW (elt)); + if (TYPE_PRECISION (index_type) < TYPE_PRECISION (elt_type)) + { + error ("type precision mismatch in switch statement"); + return true; + } + } + + if (prev_upper_bound) + { + if (! tree_int_cst_lt (prev_upper_bound, CASE_LOW (elt))) + { + error ("case labels not sorted in switch statement"); + return true; + } + } + + prev_upper_bound = CASE_HIGH (elt); + if (! prev_upper_bound) + prev_upper_bound = CASE_LOW (elt); + } + return false; } |