cprover
lazy_goto_model.cpp
Go to the documentation of this file.
1 
5 
6 #include "lazy_goto_model.h"
7 
9 
12 
13 #include <langapi/mode.h>
14 
15 #include <util/config.h>
16 #include <util/exception_utils.h>
18 #include <util/options.h>
19 #include <util/unicode.h>
20 
21 #include <langapi/language.h>
22 
23 #include <fstream>
24 
27  post_process_functiont post_process_function,
28  post_process_functionst post_process_functions,
29  can_generate_function_bodyt driver_program_can_generate_function_body,
30  generate_function_bodyt driver_program_generate_function_body,
31  message_handlert &message_handler)
32  : goto_model(new goto_modelt()),
33  symbol_table(goto_model->symbol_table),
34  goto_functions(
35  goto_model->goto_functions.function_map,
36  language_files,
37  symbol_table,
38  [this](
39  const irep_idt &function_name,
41  journalling_symbol_tablet &journalling_symbol_table) -> void {
42  goto_model_functiont model_function(
43  journalling_symbol_table,
44  goto_model->goto_functions,
45  function_name,
46  function);
47  this->post_process_function(model_function, *this);
48  },
49  driver_program_can_generate_function_body,
50  driver_program_generate_function_body,
51  message_handler),
52  post_process_function(post_process_function),
53  post_process_functions(post_process_functions),
54  driver_program_can_generate_function_body(
55  driver_program_can_generate_function_body),
56  driver_program_generate_function_body(
57  driver_program_generate_function_body),
58  message_handler(message_handler)
59 {
60  language_files.set_message_handler(message_handler);
61 }
62 
64  : goto_model(std::move(other.goto_model)),
65  symbol_table(goto_model->symbol_table),
66  goto_functions(
67  goto_model->goto_functions.function_map,
68  language_files,
69  symbol_table,
70  [this](
71  const irep_idt &function_name,
73  journalling_symbol_tablet &journalling_symbol_table) -> void {
74  goto_model_functiont model_function(
75  journalling_symbol_table,
76  goto_model->goto_functions,
77  function_name,
78  function);
79  this->post_process_function(model_function, *this);
80  },
81  other.driver_program_can_generate_function_body,
82  other.driver_program_generate_function_body,
83  other.message_handler),
84  language_files(std::move(other.language_files)),
85  post_process_function(other.post_process_function),
86  post_process_functions(other.post_process_functions),
87  message_handler(other.message_handler)
88 {
89 }
91 
112  const std::vector<std::string> &files,
113  const optionst &options)
114 {
116 
117  if(files.empty() && config.java.main_class.empty())
118  {
120  "no program provided",
121  "source file names",
122  "one or more paths to a goto binary or a source file in a supported "
123  "language");
124  }
125 
126  std::vector<std::string> binaries, sources;
127  binaries.reserve(files.size());
128  sources.reserve(files.size());
129 
130  for(const auto &file : files)
131  {
133  binaries.push_back(file);
134  else
135  sources.push_back(file);
136  }
137 
138  if(sources.empty() && !config.java.main_class.empty())
139  {
140  // We assume it's Java.
141  const std::string filename = "";
142  language_filet &lf = add_language_file(filename);
143  lf.language = get_language_from_mode(ID_java);
144  CHECK_RETURN(lf.language != nullptr);
145 
146  languaget &language = *lf.language;
148  language.set_language_options(options);
149 
150  msg.status() << "Parsing ..." << messaget::eom;
151 
152  if(dynamic_cast<java_bytecode_languaget &>(language).parse())
153  {
154  throw invalid_source_file_exceptiont("PARSING ERROR");
155  }
156 
157  msg.status() << "Converting" << messaget::eom;
158 
160  {
161  throw invalid_source_file_exceptiont("CONVERSION ERROR");
162  }
163  }
164  else
165  {
166  for(const auto &filename : sources)
167  {
168 #ifdef _MSC_VER
169  std::ifstream infile(widen(filename));
170 #else
171  std::ifstream infile(filename);
172 #endif
173 
174  if(!infile)
175  {
176  throw system_exceptiont(
177  "failed to open input file '" + filename + '\'');
178  }
179 
180  language_filet &lf = add_language_file(filename);
181  lf.language = get_language_from_filename(filename);
182 
183  if(lf.language == nullptr)
184  {
186  "failed to figure out type of file '" + filename + '\'');
187  }
188 
189  languaget &language = *lf.language;
191  language.set_language_options(options);
192 
193  msg.status() << "Parsing " << filename << messaget::eom;
194 
195  if(language.parse(infile, filename))
196  {
197  throw invalid_source_file_exceptiont("PARSING ERROR");
198  }
199 
200  lf.get_modules();
201  }
202 
203  msg.status() << "Converting" << messaget::eom;
204 
206  {
207  throw invalid_source_file_exceptiont("CONVERSION ERROR");
208  }
209  }
210 
211  for(const std::string &file : binaries)
212  {
213  msg.status() << "Reading GOTO program from file" << messaget::eom;
214 
216  {
217  source_locationt source_location;
218  source_location.set_file(file);
220  "failed to read/link goto model", source_location);
221  }
222  }
223 
224  bool binaries_provided_start =
226 
227  bool entry_point_generation_failed = false;
228 
229  if(binaries_provided_start && options.is_set("function"))
230  {
231  // The goto binaries provided already contain a __CPROVER_start
232  // function that may be tied to a different entry point `function`.
233  // Hence, we will rebuild the __CPROVER_start function.
234 
235  // Get the language annotation of the existing __CPROVER_start function.
236  std::unique_ptr<languaget> language =
238 
239  // To create a new entry point we must first remove the old one
241 
242  // Create the new entry-point
243  entry_point_generation_failed =
245 
246  // Remove the function from the goto functions so it is copied back in
247  // from the symbol table during goto_convert
248  if(!entry_point_generation_failed)
250  }
251  else if(!binaries_provided_start)
252  {
253  // Allow all language front-ends to try to provide the user-specified
254  // (--function) entry-point, or some language-specific default:
255  entry_point_generation_failed =
257  }
258 
259  if(entry_point_generation_failed)
260  {
261  throw invalid_source_file_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
262  }
263 
264  // stupid hack
266 }
267 
270 {
272  symbol_tablet::symbolst::size_type new_table_size =
273  symbol_table.symbols.size();
274  do
275  {
276  table_size = new_table_size;
277 
278  // Find symbols that correspond to functions
279  std::vector<irep_idt> fn_ids_to_convert;
280  for(const auto &named_symbol : symbol_table.symbols)
281  {
282  if(named_symbol.second.is_function())
283  fn_ids_to_convert.push_back(named_symbol.first);
284  }
285 
286  for(const irep_idt &symbol_name : fn_ids_to_convert)
288 
289  // Repeat while new symbols are being added in case any of those are
290  // stubbed functions. Even stubs can create new stubs while being
291  // converted if they are special stubs (e.g. string functions)
292  new_table_size = symbol_table.symbols.size();
293  } while(new_table_size != table_size);
294 
295  goto_model->goto_functions.compute_location_numbers();
296 }
297 
299 {
301  journalling_symbol_tablet j_symbol_table =
303  if(language_files.final(j_symbol_table))
304  {
305  msg.error() << "CONVERSION ERROR" << messaget::eom;
306  return true;
307  }
308  for(const irep_idt &updated_symbol_id : j_symbol_table.get_updated())
309  {
310  if(j_symbol_table.lookup_ref(updated_symbol_id).is_function())
311  {
312  // Re-convert any that already exist
313  goto_functions.unload(updated_symbol_id);
314  goto_functions.ensure_function_loaded(updated_symbol_id);
315  }
316  }
317 
319 
321 }
322 
324 {
326 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:155
symbol_table_baset::has_symbol
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
Definition: symbol_table_base.h:87
exception_utils.h
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
lazy_goto_functions_mapt::can_produce_function
bool can_produce_function(const key_type &name) const
Determines if this lazy GOTO functions map can produce a body for the given function.
Definition: lazy_goto_functions_map.h:123
lazy_goto_modelt::symbol_table
symbol_tablet & symbol_table
Reference to symbol_table in the internal goto_model.
Definition: lazy_goto_model.h:265
symbol_table_baset::lookup_ref
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Definition: symbol_table_base.h:104
configt::javat::main_class
irep_idt main_class
Definition: config.h:168
language_filet::get_modules
void get_modules()
Definition: language_file.cpp:35
java_bytecode_language.h
journalling_symbol_tablet::wrap
static journalling_symbol_tablet wrap(symbol_table_baset &base_symbol_table)
Definition: journalling_symbol_table.h:80
lazy_goto_functions_mapt::post_process_function
const post_process_functiont post_process_function
Definition: lazy_goto_functions_map.h:75
get_entry_point_language
std::unique_ptr< languaget > get_entry_point_language(const symbol_table_baset &symbol_table, const optionst &options, message_handlert &message_handler)
Find the language corresponding to the __CPROVER_start function.
Definition: rebuild_goto_start_function.cpp:26
optionst
Definition: options.h:23
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:496
language_filest::typecheck
bool typecheck(symbol_tablet &symbol_table, const bool keep_file_local=false)
Definition: language_file.cpp:85
lazy_goto_modelt::goto_functions
const lazy_goto_functions_mapt goto_functions
Definition: lazy_goto_model.h:268
messaget::status
mstreamt & status() const
Definition: message.h:414
lazy_goto_modelt::add_language_file
language_filet & add_language_file(const std::string &filename)
Definition: lazy_goto_model.h:191
lazy_goto_modelt::language_files
language_filest language_files
Definition: lazy_goto_model.h:269
language_filet
Definition: language_file.h:41
get_language_from_mode
std::unique_ptr< languaget > get_language_from_mode(const irep_idt &mode)
Get the language corresponding to the given mode.
Definition: mode.cpp:50
file
Definition: kdev_t.h:19
journalling_symbol_tablet::get_updated
const changesett & get_updated() const
Definition: journalling_symbol_table.h:150
goto_modelt
Definition: goto_model.h:26
journalling_symbol_table.h
Author: Diffblue Ltd.
lazy_goto_functions_mapt::unload
void unload(const key_type &name) const
Definition: lazy_goto_functions_map.h:129
mode.h
invalid_source_file_exceptiont
Thrown when we can't handle something in an input source file.
Definition: exception_utils.h:171
options.h
Options.
messaget::eom
static eomt eom
Definition: message.h:297
language_filest::generate_support_functions
bool generate_support_functions(symbol_tablet &symbol_table)
Definition: language_file.cpp:165
lazy_goto_modelt::can_produce_function
bool can_produce_function(const irep_idt &id) const override
Determines if this model can produce a body for the given function.
Definition: lazy_goto_model.cpp:323
lazy_goto_modelt::message_handler
message_handlert & message_handler
Logging helper field.
Definition: lazy_goto_model.h:278
lazy_goto_model.h
Author: Diffblue Ltd.
languaget::set_language_options
virtual void set_language_options(const optionst &)
Set language-specific options.
Definition: language.h:43
incorrect_goto_program_exceptiont
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
Definition: exception_utils.h:90
lazy_goto_modelt::finalize
bool finalize()
Definition: lazy_goto_model.cpp:298
get_language_from_filename
std::unique_ptr< languaget > get_language_from_filename(const std::string &filename)
Get the language corresponding to the registered file name extensions.
Definition: mode.cpp:101
messaget::error
mstreamt & error() const
Definition: message.h:399
rebuild_goto_start_function.h
Goto Programs Author: Thomas Kiley, thomas@diffblue.com.
remove_existing_entry_point
void remove_existing_entry_point(symbol_table_baset &symbol_table)
Eliminate the existing entry point function symbol and any symbols created in that scope from the sym...
Definition: rebuild_goto_start_function.cpp:49
languaget::generate_support_functions
virtual bool generate_support_functions(symbol_tablet &symbol_table)=0
Create language-specific support functions, such as __CPROVER_start, __CPROVER_initialize and languag...
lazy_goto_modelt
A GOTO model that produces function bodies on demand.
Definition: lazy_goto_model.h:43
symbolt::is_function
bool is_function() const
Definition: symbol.h:100
optionst::is_set
bool is_set(const std::string &option) const
N.B. opts.is_set("foo") does not imply opts.get_bool_option("foo")
Definition: options.cpp:62
source_locationt::set_file
void set_file(const irep_idt &file)
Definition: source_location.h:96
system_exceptiont
Thrown when some external system fails unexpectedly.
Definition: exception_utils.h:61
languaget::parse
virtual bool parse(std::istream &instream, const std::string &path)=0
language.h
Abstract interface to support a programming language.
messaget::set_message_handler
virtual void set_message_handler(message_handlert &_message_handler)
Definition: message.h:179
lazy_goto_modelt::goto_model
std::unique_ptr< goto_modelt > goto_model
Definition: lazy_goto_model.h:261
lazy_goto_modelt::unload
void unload(const irep_idt &name) const
Definition: lazy_goto_model.h:186
message_handlert
Definition: message.h:28
goto_functiont
A goto function, consisting of function type (see type), function body (see body),...
Definition: goto_function.h:28
lazy_goto_modelt::initialize
void initialize(const std::vector< std::string > &files, const optionst &options)
Performs initial symbol table and language_filest initialization from a given commandline and parsed ...
Definition: lazy_goto_model.cpp:111
dstringt::empty
bool empty() const
Definition: dstring.h:88
language_filet::language
std::unique_ptr< languaget > language
Definition: language_file.h:46
widen
std::wstring widen(const char *s)
Definition: unicode.cpp:50
read_goto_binary.h
Read Goto Programs.
lazy_goto_modelt::post_process_functions
const post_process_functionst post_process_functions
Definition: lazy_goto_model.h:273
config
configt config
Definition: config.cpp:24
source_locationt
Definition: source_location.h:20
language_filest::final
bool final(symbol_table_baset &symbol_table)
Definition: language_file.cpp:180
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:23
language_filest::clear
void clear()
Definition: language_file.h:135
symbol_table_baset::symbols
const symbolst & symbols
Read-only field, used to look up symbols given their names.
Definition: symbol_table_base.h:30
lazy_goto_functions_mapt::ensure_function_loaded
void ensure_function_loaded(const key_type &name) const
Definition: lazy_goto_functions_map.h:134
configt::java
struct configt::javat java
read_object_and_link
bool read_object_and_link(const std::string &file_name, goto_modelt &dest, message_handlert &message_handler)
reads an object file, and also updates config
Definition: read_goto_binary.cpp:273
unicode.h
languaget
Definition: language.h:40
is_goto_binary
bool is_goto_binary(const std::string &filename, message_handlert &message_handler)
Definition: read_goto_binary.cpp:190
config.h
lazy_goto_modelt::load_all_functions
void load_all_functions() const
Eagerly loads all functions from the symbol table.
Definition: lazy_goto_model.cpp:269
goto_functionst::entry_point
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Definition: goto_functions.h:90
size_type
unsignedbv_typet size_type()
Definition: c_types.cpp:58
java_bytecode_languaget
Definition: java_bytecode_language.h:275
invalid_command_line_argument_exceptiont
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Definition: exception_utils.h:38
configt::set_object_bits_from_symbol_table
void set_object_bits_from_symbol_table(const symbol_tablet &)
Sets the number of bits used for object addresses.
Definition: config.cpp:1266
journalling_symbol_tablet
A symbol table wrapper that records which entries have been updated/removedA caller can pass a journa...
Definition: journalling_symbol_table.h:36
goto_model_functiont
Interface providing access to a single function in a GOTO model, plus its associated symbol table.
Definition: goto_model.h:183
lazy_goto_modelt::lazy_goto_modelt
lazy_goto_modelt(post_process_functiont post_process_function, post_process_functionst post_process_functions, can_generate_function_bodyt driver_program_can_generate_function_body, generate_function_bodyt driver_program_generate_function_body, message_handlert &message_handler)
Construct a lazy GOTO model, supplying callbacks that customise its behaviour.