From 57d1b68d6582efec5a7ca63ea56a1cedbfe6e874 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 10 Feb 2021 09:39:54 +0100 Subject: [PATCH] if-to-switch: fix memory leak in case merging 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 | 17 +++++++++-------- gcc/tree-switch-conversion.c | 9 +-------- gcc/tree-switch-conversion.h | 10 ++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/gcc/gimple-if-to-switch.cc b/gcc/gimple-if-to-switch.cc index f39662be3e6..16fabef7ca0 100644 --- a/gcc/gimple-if-to-switch.cc +++ b/gcc/gimple-if-to-switch.cc @@ -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; } diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index a4798812dbf..7f65c4ce839 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -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 (ctxt); } - - diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h index d3d568e84cc..d76f19b57f6 100644 --- a/gcc/tree-switch-conversion.h +++ b/gcc/tree-switch-conversion.h @@ -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 &clusters) +{ + for (unsigned i = 0; i < clusters.length (); i++) + delete clusters[i]; + clusters.release (); +} + } // tree_switch_conversion namespace #endif // TREE_SWITCH_CONVERSION_H -- 2.30.2