Skip to content

Commit 05f2f3c

Browse files
committed
Split the entry-point-generation phase into two parts
The new generate_support_functions phase creates __CPROVER_start and __CPROVER_initialize and runs before lazy loading; the final phase will run *after* lazy loading, and is therefore used to patch up changes that require functions' bodies to have been loaded already.
1 parent 6888dd2 commit 05f2f3c

18 files changed

+149
-187
lines changed

src/ansi-c/ansi_c_language.cpp

+11-21
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,6 @@ void ansi_c_languaget::modules_provided(std::set<std::string> &modules)
3636
modules.insert(get_base_name(parse_path, true));
3737
}
3838

39-
/// Generate a _start function for a specific function
40-
/// \param entry_function_symbol_id: The symbol for the function that should be
41-
/// used as the entry point
42-
/// \param symbol_table: The symbol table for the program. The new _start
43-
/// function symbol will be added to this table
44-
/// \return Returns false if the _start method was generated correctly
45-
bool ansi_c_languaget::generate_start_function(
46-
const irep_idt &entry_function_symbol_id,
47-
symbol_tablet &symbol_table)
48-
{
49-
return generate_ansi_c_start_function(
50-
symbol_table.symbols.at(entry_function_symbol_id),
51-
symbol_table,
52-
*message_handler);
53-
}
54-
5539
/// ANSI-C preprocessing
5640
bool ansi_c_languaget::preprocess(
5741
std::istream &instream,
@@ -140,13 +124,19 @@ bool ansi_c_languaget::typecheck(
140124
return false;
141125
}
142126

143-
bool ansi_c_languaget::final(symbol_tablet &symbol_table)
127+
bool ansi_c_languaget::generate_support_functions(
128+
symbol_tablet &symbol_table)
144129
{
130+
// Note this can happen here because C doesn't currently
131+
// support lazy loading at the symbol-table level, and therefore
132+
// function bodies have already been populated and external stub
133+
// symbols created during the typecheck() phase. If it gains lazy
134+
// loading support then stubs will need to be created during
135+
// function body parsing, or else generate-stubs moved to the
136+
// final phase.
145137
generate_opaque_method_stubs(symbol_table);
146-
if(ansi_c_entry_point(symbol_table, get_message_handler()))
147-
return true;
148-
149-
return false;
138+
// This creates __CPROVER_start and __CPROVER_initialize:
139+
return ansi_c_entry_point(symbol_table, get_message_handler());
150140
}
151141

152142
void ansi_c_languaget::show_parse(std::ostream &out)

src/ansi-c/ansi_c_language.h

+3-7
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ class ansi_c_languaget:public languaget
3131
std::istream &instream,
3232
const std::string &path) override;
3333

34+
bool generate_support_functions(
35+
symbol_tablet &symbol_table) override;
36+
3437
bool typecheck(
3538
symbol_tablet &symbol_table,
3639
const std::string &module) override;
3740

38-
bool final(
39-
symbol_tablet &symbol_table) override;
40-
4141
void show_parse(std::ostream &out) override;
4242

4343
~ansi_c_languaget() override;
@@ -73,10 +73,6 @@ class ansi_c_languaget:public languaget
7373

7474
void modules_provided(std::set<std::string> &modules) override;
7575

76-
virtual bool generate_start_function(
77-
const irep_idt &entry_function_symbol_id,
78-
class symbol_tablet &symbol_table) override;
79-
8076
protected:
8177
ansi_c_parse_treet parse_tree;
8278
std::string parse_path;

src/cbmc/cbmc_parse_options.cpp

-16
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ Author: Daniel Kroening, [email protected]
5252
#include <goto-programs/show_properties.h>
5353
#include <goto-programs/string_abstraction.h>
5454
#include <goto-programs/string_instrumentation.h>
55-
#include <goto-programs/rebuild_goto_start_function.h>
5655

5756
#include <goto-symex/rewrite_union.h>
5857
#include <goto-symex/adjust_float_expressions.h>
@@ -630,21 +629,6 @@ int cbmc_parse_optionst::get_goto_program(
630629
// are already compiled
631630
return 6;
632631

633-
if(cmdline.isset("function"))
634-
{
635-
const std::string &function_id=cmdline.get_value("function");
636-
rebuild_goto_start_functiont start_function_rebuilder(
637-
get_message_handler(),
638-
cmdline,
639-
goto_model.symbol_table,
640-
goto_model.goto_functions);
641-
642-
if(start_function_rebuilder(function_id))
643-
{
644-
return 6;
645-
}
646-
}
647-
648632
if(cmdline.isset("show-symbol-table"))
649633
{
650634
show_symbol_table(goto_model, ui_message_handler.get_ui());

src/cbmc/cbmc_parse_options.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Author: Daniel Kroening, [email protected]
1414

1515
#include <util/ui_message.h>
1616
#include <util/parse_options.h>
17-
#include <goto-programs/rebuild_goto_start_function.h>
17+
#include <util/language.h>
1818

1919
#include <analyses/goto_check.h>
2020

src/cpp/cpp_language.cpp

+3-21
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,6 @@ void cpp_languaget::modules_provided(std::set<std::string> &modules)
5353
modules.insert(get_base_name(parse_path, true));
5454
}
5555

56-
/// Generate a _start function for a specific function
57-
/// \param entry_function_symbol_id: The symbol for the function that should be
58-
/// used as the entry point
59-
/// \param symbol_table: The symbol table for the program. The new _start
60-
/// function symbol will be added to this table
61-
/// \return Returns false if the _start method was generated correctly
62-
bool cpp_languaget::generate_start_function(
63-
const irep_idt &entry_function_symbol_id,
64-
symbol_tablet &symbol_table)
65-
{
66-
return generate_ansi_c_start_function(
67-
symbol_table.lookup(entry_function_symbol_id),
68-
symbol_table,
69-
*message_handler);
70-
}
71-
7256
/// ANSI-C preprocessing
7357
bool cpp_languaget::preprocess(
7458
std::istream &instream,
@@ -150,12 +134,10 @@ bool cpp_languaget::typecheck(
150134
return linking(symbol_table, new_symbol_table, get_message_handler());
151135
}
152136

153-
bool cpp_languaget::final(symbol_tablet &symbol_table)
137+
bool cpp_languaget::generate_support_functions(
138+
symbol_tablet &symbol_table)
154139
{
155-
if(ansi_c_entry_point(symbol_table, get_message_handler()))
156-
return true;
157-
158-
return false;
140+
return ansi_c_entry_point(symbol_table, get_message_handler());
159141
}
160142

161143
void cpp_languaget::show_parse(std::ostream &out)

src/cpp/cpp_language.h

+3-7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class cpp_languaget:public languaget
3333
std::istream &instream,
3434
const std::string &path) override;
3535

36+
bool generate_support_functions(
37+
symbol_tablet &symbol_table) override;
38+
3639
bool typecheck(
3740
symbol_tablet &symbol_table,
3841
const std::string &module) override;
@@ -43,9 +46,6 @@ class cpp_languaget:public languaget
4346
const std::string &module,
4447
class replace_symbolt &replace_symbol) const;
4548

46-
bool final(
47-
symbol_tablet &symbol_table) override;
48-
4949
void show_parse(std::ostream &out) override;
5050

5151
// constructor, destructor
@@ -85,10 +85,6 @@ class cpp_languaget:public languaget
8585

8686
void modules_provided(std::set<std::string> &modules) override;
8787

88-
virtual bool generate_start_function(
89-
const irep_idt &entry_function_symbol_id,
90-
class symbol_tablet &symbol_table) override;
91-
9288
protected:
9389
cpp_parse_treet cpp_parse_tree;
9490
std::string parse_path;

src/goto-analyzer/goto_analyzer_parse_options.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ Author: Daniel Kroening, [email protected]
1414

1515
#include <util/ui_message.h>
1616
#include <util/parse_options.h>
17+
#include <util/language.h>
1718

1819
#include <goto-programs/goto_model.h>
1920
#include <goto-programs/show_goto_functions.h>
20-
#include <goto-programs/rebuild_goto_start_function.h>
2121

2222
#include <analyses/goto_check.h>
2323

src/goto-programs/initialize_goto_model.cpp

+40-22
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,11 @@ bool initialize_goto_model(
5353
sources.push_back(file);
5454
}
5555

56+
language_filest language_files;
57+
language_files.set_message_handler(message_handler);
58+
5659
if(!sources.empty())
5760
{
58-
language_filest language_files;
59-
60-
language_files.set_message_handler(message_handler);
61-
6261
for(const auto &filename : sources)
6362
{
6463
#ifdef _MSC_VER
@@ -114,19 +113,6 @@ bool initialize_goto_model(
114113
msg.error() << "CONVERSION ERROR" << messaget::eom;
115114
return true;
116115
}
117-
118-
if(binaries.empty())
119-
{
120-
// Enable/disable stub generation for opaque methods
121-
bool stubs_enabled=cmdline.isset("generate-opaque-stubs");
122-
language_files.set_should_generate_opaque_method_stubs(stubs_enabled);
123-
124-
if(language_files.final(goto_model.symbol_table))
125-
{
126-
msg.error() << "CONVERSION ERROR" << messaget::eom;
127-
return true;
128-
}
129-
}
130116
}
131117

132118
for(const auto &file : binaries)
@@ -137,17 +123,49 @@ bool initialize_goto_model(
137123
return true;
138124
}
139125

140-
if(cmdline.isset("function"))
126+
bool binaries_provided_start=
127+
goto_model.symbol_table.has_symbol(goto_functionst::entry_point());
128+
129+
bool entry_point_generation_failed=false;
130+
131+
if(binaries_provided_start && cmdline.isset("function"))
141132
{
142-
const std::string &function_id=cmdline.get_value("function");
143-
rebuild_goto_start_functiont start_function_rebuilder(
133+
// Rebuild the entry-point, using the language annotation of the
134+
// existing __CPROVER_start function:
135+
rebuild_goto_start_functiont rebuild_existing_start(
144136
msg.get_message_handler(),
145137
cmdline,
146138
goto_model.symbol_table,
147139
goto_model.goto_functions);
140+
entry_point_generation_failed=rebuild_existing_start();
141+
}
142+
else if(!binaries_provided_start)
143+
{
144+
// Unsure of the rationale for only generating stubs when there are no
145+
// GOTO binaries in play; simply mirroring old code in language_uit here.
146+
if(binaries.empty())
147+
{
148+
// Enable/disable stub generation for opaque methods
149+
bool stubs_enabled=cmdline.isset("generate-opaque-stubs");
150+
language_files.set_should_generate_opaque_method_stubs(stubs_enabled);
151+
}
148152

149-
if(start_function_rebuilder(function_id))
150-
return true;
153+
// Allow all language front-ends to try to provide the user-specified
154+
// (--function) entry-point, or some language-specific default:
155+
entry_point_generation_failed=
156+
language_files.generate_support_functions(goto_model.symbol_table);
157+
}
158+
159+
if(entry_point_generation_failed)
160+
{
161+
msg.error() << "SUPPORT FUNCTION GENERATION ERROR" << messaget::eom;
162+
return true;
163+
}
164+
165+
if(language_files.final(goto_model.symbol_table))
166+
{
167+
msg.error() << "FINAL STAGE CONVERSION ERROR" << messaget::eom;
168+
return true;
151169
}
152170

153171
msg.status() << "Generating GOTO Program" << messaget::eom;

src/goto-programs/rebuild_goto_start_function.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ rebuild_goto_start_functiont::rebuild_goto_start_functiont(
4444
/// called from _start
4545
/// \return Returns true if either the symbol is not found, or something went
4646
/// wrong with generating the start_function. False otherwise.
47-
bool rebuild_goto_start_functiont::operator()(
48-
const irep_idt &entry_function)
47+
bool rebuild_goto_start_functiont::operator()()
4948
{
5049
const irep_idt &mode=get_entry_point_mode();
5150

@@ -59,7 +58,7 @@ bool rebuild_goto_start_functiont::operator()(
5958
remove_existing_entry_point();
6059

6160
bool return_code=
62-
language->generate_start_function(entry_function, symbol_table);
61+
language->generate_support_functions(symbol_table);
6362

6463
// Remove the function from the goto_functions so it is copied back in
6564
// from the symbol table during goto_convert

src/goto-programs/rebuild_goto_start_function.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class rebuild_goto_start_functiont: public messaget
3030
symbol_tablet &symbol_table,
3131
goto_functionst &goto_functions);
3232

33-
bool operator()(const irep_idt &entry_function);
33+
bool operator()();
3434

3535
private:
3636
irep_idt get_entry_point_mode() const;

0 commit comments

Comments
 (0)