]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-cfg.c (verify_gimple_switch): Tighten checks.
authorSteven Bosscher <steven@gcc.gnu.org>
Mon, 7 May 2012 13:47:11 +0000 (13:47 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Mon, 7 May 2012 13:47:11 +0000 (13:47 +0000)
* tree-cfg.c (verify_gimple_switch): Tighten checks.

From-SVN: r187242

gcc/ChangeLog
gcc/tree-cfg.c

index 664bd50d7be7eb487cb8d6834f30d1107e102c30..47ede162d5c57df8b311ca119a3f25c745c5cfdb 100644 (file)
@@ -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
index c9f02f3d3332d74a5723d583b2a0dc9a9b9640d3..f8e1fb5d3253293a6e1ba2f1995cca2a392a8139 100644 (file)
@@ -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;
 }