if-to-switch: fix memory leak in case merging
authorMartin Liska <mliska@suse.cz>
Wed, 10 Feb 2021 08:39:54 +0000 (09:39 +0100)
committerMartin Liska <mliska@suse.cz>
Wed, 10 Feb 2021 12:20:51 +0000 (13:20 +0100)
gcc/ChangeLog:

PR tree-optimization/99002
PR tree-optimization/99026
* gimple-if-to-switch.cc (if_chain::is_beneficial): Fix memory
leak when adjacent cases are merged.
* tree-switch-conversion.c (switch_decision_tree::analyze_switch_statement): Use
release_clusters.
(make_pass_lower_switch): Remove trailing whitespace.
* tree-switch-conversion.h (release_clusters): New.

gcc/gimple-if-to-switch.cc
gcc/tree-switch-conversion.c
gcc/tree-switch-conversion.h

index f39662be3e698f96a11f1e59e1bfee212c959640..16fabef7ca0cd8baa7f6d1a2c4dd28aa9d436869 100644 (file)
@@ -227,6 +227,7 @@ if_chain::is_beneficial ()
                        (left->get_high ()), wi::one (TYPE_PRECISION (type))))
            {
              left->set_high (right->get_high ());
+             delete right;
              continue;
            }
        }
@@ -241,20 +242,20 @@ if_chain::is_beneficial ()
     = jump_table_cluster::find_jump_tables (filtered_clusters);
   bool r = output.length () < filtered_clusters.length ();
   if (r)
-    dump_clusters (&output, "JT can be built");
-  output.release ();
-  if (r)
-    return true;
+    {
+      dump_clusters (&output, "JT can be built");
+      release_clusters (output);
+      return true;
+    }
+  else
+    output.release ();
 
   output = bit_test_cluster::find_bit_tests (filtered_clusters);
   r = output.length () < filtered_clusters.length ();
   if (r)
     dump_clusters (&output, "BT can be built");
 
-  for (unsigned i = 0; i < output.length (); i++)
-    delete output[i];
-
-  output.release ();
+  release_clusters (output);
   return r;
 }
 
index a4798812dbf0cd3523a0d51768ffda37476ccf2e..7f65c4ce839fbcbf740a46f0466bb2869c7d393f 100644 (file)
@@ -1824,12 +1824,7 @@ switch_decision_tree::analyze_switch_statement ()
   output.release ();
 
   bool expanded = try_switch_expansion (output2);
-
-  for (unsigned i = 0; i < output2.length (); i++)
-    delete output2[i];
-
-  output2.release ();
-
+  release_clusters (output2);
   return expanded;
 }
 
@@ -2597,5 +2592,3 @@ make_pass_lower_switch (gcc::context *ctxt)
 {
   return new pass_lower_switch<false> (ctxt);
 }
-
-
index d3d568e84cc74e5689047019a371594a82953f7e..d76f19b57f6d78f0d60479b47fa566a261cb59e6 100644 (file)
@@ -893,6 +893,16 @@ switch_decision_tree::reset_out_edges_aux (gswitch *swtch)
     e->aux = (void *) 0;
 }
 
+/* Release CLUSTERS vector and destruct all dynamically allocated items.  */
+
+static inline void
+release_clusters (vec<cluster *> &clusters)
+{
+  for (unsigned i = 0; i < clusters.length (); i++)
+    delete clusters[i];
+  clusters.release ();
+}
+
 } // tree_switch_conversion namespace
 
 #endif // TREE_SWITCH_CONVERSION_H