Skip to content

Commit c280693

Browse files
committed
L1 renaming at each declaration
This was done up until c8f0f7b.
1 parent 2ff58a9 commit c280693

File tree

10 files changed

+94
-79
lines changed

10 files changed

+94
-79
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
int g;
2+
3+
int main()
4+
{
5+
for(int i = 0; i < 4; ++i)
6+
{
7+
int *x;
8+
*&x = &g;
9+
}
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--pointer-check
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/goto-programs/goto_clean_expr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ symbol_exprt goto_convertt::make_compound_literal(
4545

4646
// The lifetime of compound literals is really that of
4747
// the block they are in.
48-
copy(code_declt(result), DECL, dest);
48+
if(!new_symbol.is_static_lifetime)
49+
copy(code_declt(result), DECL, dest);
4950

5051
code_assignt code_assign(result, expr);
5152
code_assign.add_source_location()=source_location;

src/goto-symex/goto_symex_state.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,3 +785,34 @@ void goto_symex_statet::output_propagation_map(std::ostream &out)
785785
out << name_value.first << " <- " << format(name_value.second) << "\n";
786786
}
787787
}
788+
789+
void goto_symex_statet::add_object(
790+
ssa_exprt &ssa,
791+
std::size_t l1_index,
792+
const namespacet &ns)
793+
{
794+
framet &frame = top();
795+
796+
const irep_idt l0_name = ssa.get_identifier();
797+
798+
// save old L1 name, if any
799+
auto c_it = level1.current_names.find(l0_name);
800+
801+
if(c_it != level1.current_names.end())
802+
{
803+
frame.old_level1[l0_name] = c_it->second;
804+
c_it->second = std::make_pair(ssa, l1_index);
805+
}
806+
else
807+
{
808+
c_it = level1.current_names.emplace(l0_name, std::make_pair(ssa, l1_index))
809+
.first;
810+
}
811+
812+
rename(ssa, ns, goto_symex_statet::L1);
813+
const irep_idt &l1_name = ssa.get_identifier();
814+
815+
// unique -- store
816+
if(!frame.local_objects.insert(l1_name).second)
817+
PRECONDITION(false);
818+
}

src/goto-symex/goto_symex_state.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,6 @@ class goto_symex_statet final
5858
symex_targett::sourcet source;
5959
symex_target_equationt *symex_target;
6060

61-
// we remember all L1 renamings
62-
std::set<irep_idt> l1_history;
63-
6461
symex_level0t level0;
6562
symex_level1t level1;
6663
symex_level2t level2;
@@ -239,6 +236,10 @@ class goto_symex_statet final
239236

240237
const framet &previous_frame() { return *(--(--call_stack().end())); }
241238

239+
/// Turn L0-renamed \p ssa into an L1-renamed SSA expression with an L1 index
240+
/// \p l1_index that must not have previously been used.
241+
void add_object(ssa_exprt &ssa, std::size_t l1_index, const namespacet &ns);
242+
242243
void print_backtrace(std::ostream &) const;
243244

244245
// threads

src/goto-symex/path_storage.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,24 @@ class path_storaget
8585
return size() == 0;
8686
};
8787

88+
/// Provide a unique index for a given \p id, starting from \p minimum_index.
89+
std::size_t get_unique_index(const irep_idt &id, std::size_t minimum_index)
90+
{
91+
auto entry = unique_index_map.emplace(id, minimum_index);
92+
93+
if(!entry.second)
94+
entry.first->second = std::max(entry.first->second + 1, minimum_index);
95+
96+
return entry.first->second;
97+
}
98+
8899
private:
89100
// Derived classes should override these methods, allowing the base class to
90101
// enforce preconditions.
91102
virtual patht &private_peek() = 0;
92103
virtual void private_pop() = 0;
104+
105+
std::unordered_map<irep_idt, std::size_t> unique_index_map;
93106
};
94107

95108
/// \brief LIFO save queue: depth-first search, try to finish paths

src/goto-symex/symex_dead.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ Author: Daniel Kroening, [email protected]
1111

1212
#include "goto_symex.h"
1313

14-
#include <cassert>
15-
1614
#include <util/std_expr.h>
1715

1816
#include <pointer-analysis/add_failed_symbols.h>
@@ -23,9 +21,6 @@ void goto_symext::symex_dead(statet &state)
2321

2422
const code_deadt &code = to_code_dead(instruction.code);
2523

26-
// We increase the L2 renaming to make these non-deterministic.
27-
// We also prevent propagation of old values.
28-
2924
ssa_exprt ssa(code.symbol());
3025
state.rename(ssa, ns, goto_symex_statet::L1);
3126

@@ -45,14 +40,13 @@ void goto_symext::symex_dead(statet &state)
4540
state.value_set.assign(ssa, rhs, ns, true, false);
4641
}
4742

48-
ssa_exprt ssa_lhs=to_ssa_expr(ssa);
49-
const irep_idt &l1_identifier=ssa_lhs.get_identifier();
50-
51-
// prevent propagation
52-
state.propagation.erase(l1_identifier);
53-
54-
// L2 renaming
55-
auto level2_it = state.level2.current_names.find(l1_identifier);
43+
// would be nicer to do
44+
// state.remove_object(ssa, ns);
45+
// but the l1 renaming information is not local to a path
46+
state.propagation.erase(ssa.get_identifier());
47+
// increment the L2 index to ensure a merge on join points will propagate the
48+
// value for branches that are still live
49+
auto level2_it = state.level2.current_names.find(ssa.get_identifier());
5650
if(level2_it != state.level2.current_names.end())
5751
symex_renaming_levelt::increase_counter(level2_it);
5852
}

src/goto-symex/symex_decl.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@ void goto_symext::symex_decl(statet &state)
3434

3535
void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
3636
{
37-
// We increase the L2 renaming to make these non-deterministic.
38-
// We also prevent propagation of old values.
37+
// each declaration introduces a new object, which we record as a fresh L1
38+
// index
3939

4040
ssa_exprt ssa(expr);
41-
state.rename(ssa, ns, goto_symex_statet::L1);
41+
state.rename(ssa, ns, goto_symex_statet::L0);
42+
const std::size_t fresh_l1_index =
43+
path_storage.get_unique_index(ssa.get_identifier(), 1);
44+
state.add_object(ssa, fresh_l1_index, ns);
4245
const irep_idt &l1_identifier=ssa.get_identifier();
4346

4447
// rename type to L2
@@ -62,16 +65,10 @@ void goto_symext::symex_decl(statet &state, const symbol_exprt &expr)
6265
state.value_set.assign(ssa, rhs, ns, true, false);
6366
}
6467

65-
// prevent propagation
66-
state.propagation.erase(l1_identifier);
67-
6868
// L2 renaming
69-
// inlining may yield multiple declarations of the same identifier
70-
// within the same L1 context
71-
const auto level2_it =
72-
state.level2.current_names.emplace(l1_identifier, std::make_pair(ssa, 0))
73-
.first;
74-
symex_renaming_levelt::increase_counter(level2_it);
69+
if(!state.level2.current_names.emplace(l1_identifier, std::make_pair(ssa, 1))
70+
.second)
71+
CHECK_RETURN(false);
7572
const bool record_events=state.record_events;
7673
state.record_events=false;
7774
state.rename(ssa, ns);

src/goto-symex/symex_function_call.cpp

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,8 @@ void goto_symext::symex_end_of_function(statet &state)
376376
pop_frame(state);
377377
}
378378

379-
/// preserves locality of local variables of a given function by applying L1
380-
/// renaming to the local identifiers
379+
/// preserves locality of parameters of a given function by applying L1
380+
/// renaming to them
381381
void goto_symext::locality(
382382
const irep_idt &function_identifier,
383383
statet &state,
@@ -387,57 +387,15 @@ void goto_symext::locality(
387387
state.threads[state.source.thread_nr].function_frame[function_identifier];
388388
frame_nr++;
389389

390-
std::set<irep_idt> local_identifiers;
391-
392-
get_local_identifiers(goto_function, local_identifiers);
393-
394-
statet::framet &frame=state.top();
395-
396-
for(std::set<irep_idt>::const_iterator
397-
it=local_identifiers.begin();
398-
it!=local_identifiers.end();
399-
it++)
390+
for(const auto &param : goto_function.type.parameters())
400391
{
401392
// get L0 name
402-
ssa_exprt ssa(ns.lookup(*it).symbol_expr());
393+
ssa_exprt ssa(ns.lookup(param.get_identifier()).symbol_expr());
403394
state.rename(ssa, ns, goto_symex_statet::L0);
404-
const irep_idt l0_name=ssa.get_identifier();
405-
406-
// save old L1 name for popping the frame
407-
auto c_it = state.level1.current_names.find(l0_name);
408-
409-
if(c_it != state.level1.current_names.end())
410-
{
411-
frame.old_level1[l0_name]=c_it->second;
412-
c_it->second = std::make_pair(ssa, frame_nr);
413-
}
414-
else
415-
{
416-
c_it = state.level1.current_names
417-
.emplace(l0_name, std::make_pair(ssa, frame_nr))
418-
.first;
419-
}
420-
421-
// do L1 renaming -- these need not be unique, as
422-
// identifiers may be shared among functions
423-
// (e.g., due to inlining or other code restructuring)
424-
425-
state.rename(ssa, ns, goto_symex_statet::L1);
426-
427-
irep_idt l1_name=ssa.get_identifier();
428-
unsigned offset=0;
429-
430-
while(state.l1_history.find(l1_name)!=state.l1_history.end())
431-
{
432-
symex_renaming_levelt::increase_counter(c_it);
433-
++offset;
434-
ssa.set_level_1(frame_nr+offset);
435-
l1_name=ssa.get_identifier();
436-
}
437395

438-
// now unique -- store
439-
frame.local_objects.insert(l1_name);
440-
state.l1_history.insert(l1_name);
396+
const std::size_t fresh_l1_index =
397+
path_storage.get_unique_index(ssa.get_identifier(), frame_nr);
398+
state.add_object(ssa, fresh_l1_index, ns);
441399
}
442400
}
443401

src/goto-symex/symex_start_thread.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ void goto_symext::symex_start_thread(statet &state)
6666

6767
// get L0 name for current thread
6868
lhs.set_level_0(t);
69+
const irep_idt &l0_name = lhs.get_identifier();
70+
std::size_t l1_index = path_storage.get_unique_index(l0_name, 0);
71+
CHECK_RETURN(l1_index == 0);
6972

7073
// set up L1 name
7174
if(!state.level1.current_names.insert(
@@ -75,7 +78,6 @@ void goto_symext::symex_start_thread(statet &state)
7578
state.rename(lhs, ns, goto_symex_statet::L1);
7679
const irep_idt l1_name=lhs.get_l1_object_identifier();
7780
// store it
78-
state.l1_history.insert(l1_name);
7981
new_thread.call_stack.back().local_objects.insert(l1_name);
8082

8183
// make copy

0 commit comments

Comments
 (0)