From 933c4cde0cc93ea0b8ed576293d641428cc544df Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Fri, 17 Nov 2017 17:50:26 +0100 Subject: [PATCH] couvreur99_new: fix two memory leaks found by ASAN This only occurs when doing the emptiness check of twa with allocated states. * spot/twaalgos/couvreurnew.cc: Here. * NEWS: Mention the bug. --- NEWS | 5 +++++ spot/twaalgos/couvreurnew.cc | 27 ++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 0320a6884..0c8b8238a 100644 --- a/NEWS +++ b/NEWS @@ -204,6 +204,11 @@ New in spot 2.4.2.dev (not yet released) been removed. It's a low-level function was not used anywhere in Spot anymore, since it's better to use spot::twa::copy_ap_of(). + Bug fixes: + + - couvreur99_new() leaked memory when processing TωA that allocate + states. + New in spot 2.4.2 (2017-11-07) Tools: diff --git a/spot/twaalgos/couvreurnew.cc b/spot/twaalgos/couvreurnew.cc index 4f90d9b2d..3f9fcc780 100644 --- a/spot/twaalgos/couvreurnew.cc +++ b/spot/twaalgos/couvreurnew.cc @@ -94,7 +94,7 @@ namespace spot using state_t = const state*; using iterator_t = twa_succ_iterator*; template - using state_map = state_map; + using state_map = spot::state_map; template static @@ -290,6 +290,11 @@ namespace spot init(); } + ~couvreur99_new_status() + { + uninit(); + } + automaton_ptr aut; std::stack root; typename T::template state_map h; @@ -304,10 +309,26 @@ namespace spot h.resize(aut->num_states(), 0); } + template + typename std::enable_if::type + uninit() + { + } + template typename std::enable_if::type init() - {} + { + } + + template + typename std::enable_if::type + uninit() + { + auto i = h.begin(); + while (i != h.end()) + i++->first->destroy(); + } }; template @@ -723,7 +744,6 @@ namespace spot // We have a successor to look at. inc_transitions(); // Fetch the values we are interested in... - state_t dest = succ->dst(); auto acc = succ->acc(); if (!need_accepting_run) if (strength == TERMINAL && ecs_->aut->acc().accepting(acc)) @@ -739,6 +759,7 @@ namespace spot // We do not need an accepting run. return true; } + state_t dest = succ->dst(); // ... and point the iterator to the next successor, for // the next iteration. todo.top().second->next();