Skip to content

Commit c48170e

Browse files
authored
Merge pull request diffblue#192 from diffblue/smowton/feature/split_frontend_final_stage
SEC-58: Split the entry-point-generation phase into two parts
2 parents ab347d5 + f4df5c6 commit c48170e

34 files changed

+218
-244
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
int getone() {
3+
return 1;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
extern int getone();
3+
4+
#include <assert.h>
5+
6+
int main(int argc, char** argv) {
7+
assert(getone()==1);
8+
}
9+
10+
int altmain() {
11+
assert(getone()==0);
12+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.gb
3+
lib.c --function altmain
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.gb
3+
lib.c
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
int getone() {
3+
return 1;
4+
}
4.35 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
extern int getone();
3+
4+
#include <assert.h>
5+
6+
int main(int argc, char** argv) {
7+
assert(getone()==1);
8+
}
9+
10+
int altmain() {
11+
assert(getone()==0);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
lib.gb --function altmain
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
--
8+
^warning: ignoring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
lib.gb
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/ansi-c/ansi_c_language.cpp

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

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

144-
bool ansi_c_languaget::final(
145-
symbol_tablet &symbol_table,
146-
bool create_start_function)
128+
bool ansi_c_languaget::generate_support_functions(
129+
symbol_tablet &symbol_table)
147130
{
131+
// Note this can happen here because C doesn't currently
132+
// support lazy loading at the symbol-table level, and therefore
133+
// function bodies have already been populated and external stub
134+
// symbols created during the typecheck() phase. If it gains lazy
135+
// loading support then stubs will need to be created during
136+
// function body parsing, or else generate-stubs moved to the
137+
// final phase.
148138
generate_opaque_method_stubs(symbol_table);
149-
150-
if(create_start_function)
151-
{
152-
if(ansi_c_entry_point(symbol_table, get_message_handler()))
153-
return true;
154-
}
155-
156-
return false;
139+
// This creates __CPROVER_start and __CPROVER_initialize:
140+
return ansi_c_entry_point(symbol_table, get_message_handler());
157141
}
158142

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

src/ansi-c/ansi_c_language.h

+3-8
Original file line numberDiff line numberDiff line change
@@ -31,14 +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,
40-
bool create_start_function) override;
41-
4241
void show_parse(std::ostream &out) override;
4342

4443
~ansi_c_languaget() override;
@@ -77,10 +76,6 @@ class ansi_c_languaget:public languaget
7776

7877
void modules_provided(std::set<std::string> &modules) override;
7978

80-
virtual bool generate_start_function(
81-
const irep_idt &entry_function_symbol_id,
82-
class symbol_tablet &symbol_table) override;
83-
8479
protected:
8580
ansi_c_parse_treet parse_tree;
8681
std::string parse_path;

src/cbmc/cbmc_parse_options.cpp

-15
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ Author: Daniel Kroening, [email protected]
5151
#include <goto-programs/show_properties.h>
5252
#include <goto-programs/string_abstraction.h>
5353
#include <goto-programs/string_instrumentation.h>
54-
#include <goto-programs/rebuild_goto_start_function.h>
5554

5655
#include <goto-symex/rewrite_union.h>
5756
#include <goto-symex/adjust_float_expressions.h>
@@ -629,20 +628,6 @@ int cbmc_parse_optionst::get_goto_program(
629628
// are already compiled
630629
return 6;
631630

632-
if(cmdline.isset("function"))
633-
{
634-
const std::string &function_id=cmdline.get_value("function");
635-
rebuild_goto_start_functiont start_function_rebuilder(
636-
get_message_handler(),
637-
goto_model.symbol_table,
638-
goto_model.goto_functions);
639-
640-
if(start_function_rebuilder(function_id))
641-
{
642-
return 6;
643-
}
644-
}
645-
646631
if(cmdline.isset("show-symbol-table"))
647632
{
648633
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-26
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,6 @@ void cpp_languaget::modules_provided(std::set<std::string> &modules)
5454
modules.insert(get_base_name(parse_path, true));
5555
}
5656

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

154-
bool cpp_languaget::final(
155-
symbol_tablet &symbol_table,
156-
bool create_start_function)
138+
bool cpp_languaget::generate_support_functions(
139+
symbol_tablet &symbol_table)
157140
{
158-
if(create_start_function)
159-
{
160-
if(ansi_c_entry_point(symbol_table, get_message_handler()))
161-
return true;
162-
}
163-
164-
return false;
141+
return ansi_c_entry_point(symbol_table, get_message_handler());
165142
}
166143

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

src/cpp/cpp_language.h

+3-8
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,10 +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,
48-
bool create_start_function) override;
49-
5049
void show_parse(std::ostream &out) override;
5150

5251
// constructor, destructor
@@ -89,10 +88,6 @@ class cpp_languaget:public languaget
8988

9089
void modules_provided(std::set<std::string> &modules) override;
9190

92-
virtual bool generate_start_function(
93-
const irep_idt &entry_function_symbol_id,
94-
class symbol_tablet &symbol_table) override;
95-
9691
protected:
9792
cpp_parse_treet cpp_parse_tree;
9893
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

+31-23
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ Author: Daniel Kroening, [email protected]
2929
bool initialize_goto_model(
3030
goto_modelt &goto_model,
3131
const cmdlinet &cmdline,
32-
bool generate_start_function,
3332
message_handlert &message_handler)
3433
{
3534
messaget msg(message_handler);
@@ -54,12 +53,11 @@ bool initialize_goto_model(
5453
sources.push_back(file);
5554
}
5655

56+
language_filest language_files;
57+
language_files.set_message_handler(message_handler);
58+
5759
if(!sources.empty())
5860
{
59-
language_filest language_files;
60-
61-
language_files.set_message_handler(message_handler);
62-
6361
for(const auto &filename : sources)
6462
{
6563
#ifdef _MSC_VER
@@ -115,17 +113,6 @@ bool initialize_goto_model(
115113
msg.error() << "CONVERSION ERROR" << messaget::eom;
116114
return true;
117115
}
118-
119-
if(binaries.empty())
120-
{
121-
if(language_files.final(
122-
goto_model.symbol_table,
123-
generate_start_function))
124-
{
125-
msg.error() << "CONVERSION ERROR" << messaget::eom;
126-
return true;
127-
}
128-
}
129116
}
130117

131118
for(const auto &file : binaries)
@@ -136,18 +123,39 @@ bool initialize_goto_model(
136123
return true;
137124
}
138125

139-
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"))
140132
{
141-
const std::string &function_id=cmdline.get_value("function");
142-
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(
143136
msg.get_message_handler(),
144137
goto_model.symbol_table,
145138
goto_model.goto_functions);
139+
entry_point_generation_failed=rebuild_existing_start();
140+
}
141+
else if(!binaries_provided_start)
142+
{
143+
// Allow all language front-ends to try to provide the user-specified
144+
// (--function) entry-point, or some language-specific default:
145+
entry_point_generation_failed=
146+
language_files.generate_support_functions(goto_model.symbol_table);
147+
}
146148

147-
if(start_function_rebuilder(function_id))
148-
{
149-
return 6;
150-
}
149+
if(entry_point_generation_failed)
150+
{
151+
msg.error() << "SUPPORT FUNCTION GENERATION ERROR" << messaget::eom;
152+
return true;
153+
}
154+
155+
if(language_files.final(goto_model.symbol_table))
156+
{
157+
msg.error() << "FINAL STAGE CONVERSION ERROR" << messaget::eom;
158+
return true;
151159
}
152160

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

src/goto-programs/initialize_goto_model.h

-10
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,6 @@ Author: Daniel Kroening, [email protected]
2121
bool initialize_goto_model(
2222
goto_modelt &goto_model,
2323
const cmdlinet & cmdline,
24-
bool generate_start_function,
2524
message_handlert &message_handler);
2625

27-
inline bool initialize_goto_model(
28-
goto_modelt &goto_model,
29-
const cmdlinet &cmdline,
30-
message_handlert &message_handler)
31-
{
32-
return initialize_goto_model(goto_model, cmdline, true, message_handler);
33-
}
34-
35-
3626
#endif // CPROVER_GOTO_PROGRAMS_INITIALIZE_GOTO_MODEL_H

0 commit comments

Comments
 (0)