Skip to content

Commit a711c64

Browse files
committed
Introduce mechanism for renumbering an individual GOTO program
goto_programt::compute_location_numbers numbers it from zero, but of course these numbers may clash with other programs; this adds the ability to renumber a program, at the cost of wasting some "address" space.
1 parent 933d635 commit a711c64

8 files changed

+105
-20
lines changed

src/goto-programs/goto_functions_template.h

+26-4
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,26 @@ class goto_functions_templatet
103103
typedef std::map<irep_idt, goto_functiont> function_mapt;
104104
function_mapt function_map;
105105

106-
goto_functions_templatet()
106+
private:
107+
/// A location number such that numbers in the interval
108+
/// [unused_location_number, MAX_UINT] are all unused. There might still be
109+
/// unused numbers below this.
110+
/// If numbering a new function or renumbering a function, starting from this
111+
/// number is safe.
112+
unsigned unused_location_number;
113+
114+
public:
115+
goto_functions_templatet():
116+
unused_location_number(0)
107117
{
108118
}
109119

110120
goto_functions_templatet(const goto_functions_templatet &)=delete;
111121
goto_functions_templatet &operator=(const goto_functions_templatet &)=delete;
112122

113123
goto_functions_templatet(goto_functions_templatet &&other):
114-
function_map(std::move(other.function_map))
124+
function_map(std::move(other.function_map)),
125+
unused_location_number(other.unused_location_number)
115126
{
116127
}
117128

@@ -133,6 +144,7 @@ class goto_functions_templatet
133144
std::ostream &out) const;
134145

135146
void compute_location_numbers();
147+
void compute_location_numbers(goto_programt &);
136148
void compute_loop_numbers();
137149
void compute_target_numbers();
138150
void compute_incoming_edges();
@@ -186,13 +198,23 @@ void goto_functions_templatet<bodyT>::output(
186198
template <class bodyT>
187199
void goto_functions_templatet<bodyT>::compute_location_numbers()
188200
{
189-
unsigned nr=0;
201+
unused_location_number = 0;
190202
for(auto &func : function_map)
191203
{
192-
func.second.body.compute_location_numbers(nr);
204+
// Side-effect: bumps unused_location_number.
205+
func.second.body.compute_location_numbers(unused_location_number);
193206
}
194207
}
195208

209+
template <class bodyT>
210+
void goto_functions_templatet<bodyT>::compute_location_numbers(
211+
goto_programt &program)
212+
{
213+
// Renumber just this single function. Use fresh numbers in case it has
214+
// grown since it was last numbered.
215+
program.compute_location_numbers(unused_location_number);
216+
}
217+
196218
template <class bodyT>
197219
void goto_functions_templatet<bodyT>::compute_incoming_edges()
198220
{

src/goto-programs/goto_model.h

+58
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,62 @@ class goto_modelt
6767
void unload(const irep_idt &name) { goto_functions.unload(name); }
6868
};
6969

70+
/// Interface providing access to a single function in a GOTO model, plus its
71+
/// associated symbol table.
72+
/// Its purpose is to permit GOTO program renumbering (a non-const operation on
73+
/// goto_functionst) without providing a non-const reference to the entire
74+
/// function map. For example, incremental function loading uses this, as in
75+
/// that situation functions other than the one currently being loaded should
76+
/// not be altered.
77+
class goto_model_functiont
78+
{
79+
public:
80+
/// Construct a function wrapper
81+
/// \param goto_model: will be used to ensure unique numbering of
82+
/// goto programs, specifically incrementing its unused_location_number
83+
/// member each time a program is re-numbered.
84+
/// \param goto_function: function to wrap.
85+
explicit goto_model_functiont(
86+
goto_modelt &goto_model, goto_functionst::goto_functiont &goto_function):
87+
goto_model(goto_model),
88+
goto_function(goto_function)
89+
{
90+
}
91+
92+
/// Re-number our goto_function. After this method returns all instructions'
93+
/// location numbers may have changed, but will be globally unique and in
94+
/// program order within the program.
95+
void compute_location_numbers()
96+
{
97+
goto_model.goto_functions.compute_location_numbers(goto_function.body);
98+
}
99+
100+
/// Get symbol table
101+
/// \return symbol table from the associated GOTO model
102+
symbol_tablet &get_symbol_table()
103+
{
104+
return goto_model.symbol_table;
105+
}
106+
107+
/// Get GOTO function
108+
/// \return the wrapped GOTO function
109+
goto_functionst::goto_functiont &get_goto_function()
110+
{
111+
return goto_function;
112+
}
113+
114+
/// Get GOTO model. This returns a const reference because this interface is
115+
/// intended for use where non-const access to the whole model should not be
116+
/// allowed.
117+
/// \return const view of the whole GOTO model.
118+
const goto_modelt &get_goto_model()
119+
{
120+
return goto_model;
121+
}
122+
123+
private:
124+
goto_modelt &goto_model;
125+
goto_functionst::goto_functiont &goto_function;
126+
};
127+
70128
#endif // CPROVER_GOTO_PROGRAMS_GOTO_MODEL_H

src/goto-programs/goto_program_template.h

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Author: Daniel Kroening, [email protected]
1919
#include <sstream>
2020
#include <string>
2121

22+
#include <util/invariant.h>
2223
#include <util/namespace.h>
2324
#include <util/symbol_table.h>
2425
#include <util/source_location.h>
@@ -512,7 +513,12 @@ class goto_program_templatet
512513
void compute_location_numbers(unsigned &nr)
513514
{
514515
for(auto &i : instructions)
516+
{
517+
INVARIANT(
518+
nr != std::numeric_limits<unsigned>::max(),
519+
"Too many location numbers assigned");
515520
i.location_number=nr++;
521+
}
516522
}
517523

518524
/// Compute location numbers

src/goto-programs/lazy_goto_model.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ lazy_goto_modelt::lazy_goto_modelt(
3030
symbol_table,
3131
[this] (goto_functionst::goto_functiont &function) -> void
3232
{
33-
this->post_process_function(function, symbol_table);
33+
goto_model_functiont model_function(*goto_model, function);
34+
this->post_process_function(model_function);
3435
},
3536
message_handler),
3637
post_process_function(std::move(post_process_function)),
@@ -49,7 +50,8 @@ lazy_goto_modelt::lazy_goto_modelt(lazy_goto_modelt &&other)
4950
symbol_table,
5051
[this] (goto_functionst::goto_functiont &function) -> void
5152
{
52-
this->post_process_function(function, symbol_table);
53+
goto_model_functiont model_function(*goto_model, function);
54+
this->post_process_function(model_function);
5355
},
5456
other.message_handler),
5557
language_files(std::move(other.language_files)),

src/goto-programs/lazy_goto_model.h

+4-8
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@
1515
class cmdlinet;
1616
class optionst;
1717

18-
1918
/// Model that holds partially loaded map of functions
2019
class lazy_goto_modelt
2120
{
2221
public:
23-
typedef std::function<void(
24-
goto_functionst::goto_functiont &function,
25-
symbol_tablet &symbol_table)> post_process_functiont;
22+
typedef std::function<void(goto_model_functiont &function)>
23+
post_process_functiont;
2624
typedef std::function<bool(goto_modelt &goto_model)> post_process_functionst;
2725

2826
explicit lazy_goto_modelt(
@@ -53,11 +51,9 @@ class lazy_goto_modelt
5351
message_handlert &message_handler)
5452
{
5553
return lazy_goto_modelt(
56-
[&handler] (
57-
goto_functionst::goto_functiont &function,
58-
symbol_tablet &symbol_table) -> void
54+
[&handler] (goto_model_functiont &function)
5955
{
60-
handler.process_goto_function(function, symbol_table);
56+
handler.process_goto_function(function);
6157
},
6258
[&handler, &options] (goto_modelt &goto_model) -> bool
6359
{

src/jbmc/jbmc_parse_options.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -637,15 +637,17 @@ int jbmc_parse_optionst::get_goto_program(
637637
}
638638

639639
void jbmc_parse_optionst::process_goto_function(
640-
goto_functionst::goto_functiont &function, symbol_tablet &symbol_table)
640+
goto_model_functiont &function)
641641
{
642+
symbol_tablet &symbol_table = function.get_symbol_table();
643+
goto_functionst::goto_functiont &goto_function = function.get_goto_function();
642644
try
643645
{
644646
// Remove inline assembler; this needs to happen before
645647
// adding the library.
646-
remove_asm(function, symbol_table);
648+
remove_asm(goto_function, symbol_table);
647649
// Removal of RTTI inspection:
648-
remove_instanceof(function, symbol_table);
650+
remove_instanceof(goto_function, symbol_table);
649651
}
650652

651653
catch(const char *e)

src/jbmc/jbmc_parse_options.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ class jbmc_parse_optionst:
8181
const char **argv,
8282
const std::string &extra_options);
8383

84-
void process_goto_function(
85-
goto_functionst::goto_functiont &function, symbol_tablet &symbol_table);
84+
void process_goto_function(goto_model_functiont &function);
8685
bool process_goto_functions(goto_modelt &goto_model, const optionst &options);
8786

8887
protected:

unit/testing-utils/load_java_class.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ symbol_tablet load_java_class(
6262
// Construct a lazy_goto_modelt
6363
null_message_handlert message_handler;
6464
lazy_goto_modelt lazy_goto_model(
65-
[] (goto_functionst::goto_functiont &function, symbol_tablet &symbol_table)
65+
[] (goto_model_functiont &function)
6666
{ },
6767
[] (goto_modelt &goto_model)
6868
{ return false; },

0 commit comments

Comments
 (0)