diff --git a/search/Sta.cc b/search/Sta.cc index bdbf6e93..320e0178 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -4291,8 +4291,15 @@ Parasitics * Sta::makeConcreteParasitics(std::string_view name, std::string_view filename) { + // Free the prior entry to avoid leaking it on overwrite. + std::string key(name); + auto it = parasitics_name_map_.find(key); + if (it != parasitics_name_map_.end()) { + delete it->second; + parasitics_name_map_.erase(it); + } Parasitics *parasitics = new ConcreteParasitics(name, filename, this); - parasitics_name_map_[std::string(name)] = parasitics; + parasitics_name_map_[key] = parasitics; return parasitics; } diff --git a/test/make_concrete_parasitics_leak.ok b/test/make_concrete_parasitics_leak.ok new file mode 100644 index 00000000..e69de29b diff --git a/test/make_concrete_parasitics_leak.tcl b/test/make_concrete_parasitics_leak.tcl new file mode 100644 index 00000000..51629d45 --- /dev/null +++ b/test/make_concrete_parasitics_leak.tcl @@ -0,0 +1,9 @@ +# Sta::makeConcreteParasitics map-overwrite leak repro. +# Run under -fsanitize=address to verify no leak after the fix. +read_liberty asap7_small.lib.gz +read_verilog reg1_asap7.v +link_design top +# 1st read_spef +read_spef -min reg1_asap7.spef +# 2nd read_spef +read_spef -min reg1_asap7.spef diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index b0cab790..ce037eff 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -154,6 +154,7 @@ record_public_tests { liberty_ccsn liberty_float_as_str liberty_latch3 + make_concrete_parasitics_leak package_require path_group_names power_json