Skip to content

Commit b69a629

Browse files
authored
Merge pull request #6208 from diffblue/fix_unordered_map_iterators
Fix for iterators into unordered_maps
2 parents 845343e + c920010 commit b69a629

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

src/solvers/flattening/boolbv.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,29 @@ boolbvt::convert_bv(const exprt &expr, optionalt<std::size_t> expected_width)
4242
// check cache first
4343
std::pair<bv_cachet::iterator, bool> cache_result=
4444
bv_cache.insert(std::make_pair(expr, bvt()));
45+
46+
// get a reference to the cache entry
47+
auto &cache_entry = cache_result.first->second;
48+
4549
if(!cache_result.second)
4650
{
47-
return cache_result.first->second;
51+
// Found in cache
52+
return cache_entry;
4853
}
4954

50-
// Iterators into hash_maps supposedly stay stable
51-
// even though we are inserting more elements recursively.
52-
53-
cache_result.first->second = convert_bitvector(expr);
55+
// Iterators into hash_maps do not remain valid when inserting
56+
// more elements recursively. C++11 §23.2.5/13
57+
// However, the _reference_ to the entry does!
58+
cache_entry = convert_bitvector(expr);
5459

5560
INVARIANT_WITH_DIAGNOSTICS(
56-
!expected_width || cache_result.first->second.size() == *expected_width,
61+
!expected_width || cache_entry.size() == *expected_width,
5762
"bitvector width shall match the indicated expected width",
5863
expr.find_source_location(),
5964
irep_pretty_diagnosticst(expr));
6065

6166
// check
62-
for(const auto &literal : cache_result.first->second)
67+
for(const auto &literal : cache_entry)
6368
{
6469
if(freeze_all && !literal.is_constant())
6570
prop.set_frozen(literal);
@@ -71,7 +76,7 @@ boolbvt::convert_bv(const exprt &expr, optionalt<std::size_t> expected_width)
7176
irep_pretty_diagnosticst(expr));
7277
}
7378

74-
return cache_result.first->second;
79+
return cache_entry;
7580
}
7681

7782
/// Print that the expression of x has failed conversion,

src/solvers/prop/prop_conv_solver.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,18 @@ literalt prop_conv_solvert::convert(const exprt &expr)
166166
// check cache first
167167
auto result = cache.insert({expr, literalt()});
168168

169-
if(!result.second)
170-
return result.first->second;
169+
// get a reference to the cache entry
170+
auto &cache_entry = result.first->second;
171171

172+
if(!result.second) // found in cache
173+
return cache_entry;
174+
175+
// The following may invalidate the iterator result.first,
176+
// but note that the _reference_ is guaranteed to remain valid.
172177
literalt literal = convert_bool(expr);
173178

174-
// insert into cache
175-
result.first->second = literal;
179+
// store the literal in the cache using the reference
180+
cache_entry = literal;
176181

177182
if(freeze_all && !literal.is_constant())
178183
prop.set_frozen(literal);

0 commit comments

Comments
 (0)