Skip to content

Commit 9c34196

Browse files
committed
dump-c: output a generated environment via --harness
dump-c previously would not print __CPROVER__start code as this is deemed tool-internal. With increasing support for test-harness construction, the harness code may be of interest to users, who may wish to tweak and use re-use it.
1 parent 5e5c78e commit 9c34196

File tree

9 files changed

+139
-11
lines changed

9 files changed

+139
-11
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* GOTO-INSTRUMENT: New option --print-path-lenghts
88
* GOTO-ANALYZER: New option --unreachable-functions, --reachable-functions
99
* GOTO-INSTRUMENT: New option --undefined-function-is-assume-false
10+
* GOTO-INSTRUMENT: dump-c can output the generated environment via --harness
1011

1112

1213
5.7
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <assert.h>
2+
3+
int main(int argc, char* argv[])
4+
{
5+
assert(argc<2 || argv[1]!=0);
6+
7+
return 0;
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
--model-argc-argv 3 --dump-c --harness
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
Adding up to 3 command line arguments
7+
--
8+
^warning: ignoring

src/clobber/clobber_parse_options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ int clobber_parse_optionst::doit()
190190
if(!out)
191191
throw std::string("failed to create file simulator.c");
192192

193-
dump_c(goto_functions, true, ns, out);
193+
dump_c(goto_functions, true, false, ns, out);
194194

195195
status() << "instrumentation complete; compile and execute simulator.c"
196196
<< eom;

src/goto-instrument/dump_c.cpp

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include <util/find_symbols.h>
1616
#include <util/base_type.h>
1717
#include <util/cprover_prefix.h>
18+
#include <util/replace_symbol.h>
1819

1920
#include <ansi-c/ansi_c_language.h>
2021
#include <cpp/cpp_language.h>
@@ -163,7 +164,9 @@ void dump_ct::operator()(std::ostream &os)
163164
}
164165

165166
// we don't want to dump in full all definitions
166-
if(!tag_added && ignore(symbol))
167+
if(!tag_added &&
168+
ignore(symbol) &&
169+
symbol.name!=goto_functions.entry_point())
167170
continue;
168171

169172
if(!symbols_sorted.insert(name_str).second)
@@ -206,7 +209,8 @@ void dump_ct::operator()(std::ostream &os)
206209
goto_functionst::function_mapt::const_iterator func_entry=
207210
goto_functions.function_map.find(symbol.name);
208211

209-
if(func_entry!=goto_functions.function_map.end() &&
212+
if(!harness &&
213+
func_entry!=goto_functions.function_map.end() &&
210214
func_entry->second.body_available() &&
211215
(symbol.name==ID_main ||
212216
(!config.main.empty() && symbol.name==config.main)))
@@ -990,6 +994,73 @@ void dump_ct::convert_global_variable(
990994

991995
/*******************************************************************\
992996
997+
Function: dump_ct::cleanup_harness
998+
999+
Inputs: b Code block to be cleaned
1000+
1001+
Outputs:
1002+
1003+
Purpose: Replace CPROVER internal symbols in b by printable values and
1004+
generate necessary declarations.
1005+
1006+
\*******************************************************************/
1007+
1008+
void dump_ct::cleanup_harness(code_blockt &b)
1009+
{
1010+
replace_symbolt replace;
1011+
code_blockt decls;
1012+
1013+
const symbolt *argc_sym=nullptr;
1014+
if(!ns.lookup("argc'", argc_sym))
1015+
{
1016+
symbol_exprt argc("argc", argc_sym->type);
1017+
replace.insert(argc_sym->name, argc);
1018+
code_declt d(argc);
1019+
decls.add(d);
1020+
}
1021+
const symbolt *argv_sym=nullptr;
1022+
if(!ns.lookup("argv'", argv_sym))
1023+
{
1024+
symbol_exprt argv("argv", argv_sym->type);
1025+
replace.insert(argv_sym->name, argv);
1026+
code_declt d(argv);
1027+
decls.add(d);
1028+
}
1029+
const symbolt *return_sym=nullptr;
1030+
if(!ns.lookup("return'", return_sym))
1031+
{
1032+
symbol_exprt return_value("return_value", return_sym->type);
1033+
replace.insert(return_sym->name, return_value);
1034+
code_declt d(return_value);
1035+
decls.add(d);
1036+
}
1037+
1038+
Forall_operands(it, b)
1039+
{
1040+
codet &code=to_code(*it);
1041+
1042+
if(code.get_statement()==ID_function_call)
1043+
{
1044+
exprt &func=to_code_function_call(code).function();
1045+
if(func.id()==ID_symbol)
1046+
{
1047+
symbol_exprt &s=to_symbol_expr(func);
1048+
if(s.get_identifier()==ID_main)
1049+
s.set_identifier(CPROVER_PREFIX+id2string(ID_main));
1050+
else if(s.get_identifier()==CPROVER_PREFIX "initialize")
1051+
continue;
1052+
}
1053+
}
1054+
1055+
decls.add(code);
1056+
}
1057+
1058+
b.swap(decls);
1059+
replace(b);
1060+
}
1061+
1062+
/*******************************************************************\
1063+
9931064
Function: dump_ct::convert_function_declarations
9941065
9951066
Inputs:
@@ -1050,9 +1121,20 @@ void dump_ct::convert_function_declaration(
10501121
converted_enum.swap(converted_e_bak);
10511122
converted_compound.swap(converted_c_bak);
10521123

1124+
if(harness && symbol.name==goto_functions.entry_point())
1125+
cleanup_harness(b);
1126+
10531127
os_body << "// " << symbol.name << std::endl;
10541128
os_body << "// " << symbol.location << std::endl;
1055-
os_body << make_decl(symbol.name, symbol.type) << std::endl;
1129+
if(symbol.name==goto_functions.entry_point())
1130+
os_body << make_decl(ID_main, symbol.type) << std::endl;
1131+
else if(!harness || symbol.name!=ID_main)
1132+
os_body << make_decl(symbol.name, symbol.type) << std::endl;
1133+
else if(harness && symbol.name==ID_main)
1134+
{
1135+
os_body << make_decl(CPROVER_PREFIX+id2string(symbol.name), symbol.type)
1136+
<< std::endl;
1137+
}
10561138
os_body << expr_to_string(b);
10571139
os_body << std::endl << std::endl;
10581140

@@ -1066,6 +1148,13 @@ void dump_ct::convert_function_declaration(
10661148
os_decl << "// " << symbol.location << std::endl;
10671149
os_decl << make_decl(symbol.name, symbol.type) << ";" << std::endl;
10681150
}
1151+
else if(harness && symbol.name==ID_main)
1152+
{
1153+
os_decl << "// " << symbol.name << std::endl;
1154+
os_decl << "// " << symbol.location << std::endl;
1155+
os_decl << make_decl(CPROVER_PREFIX+id2string(symbol.name), symbol.type)
1156+
<< ";" << std::endl;
1157+
}
10691158
}
10701159

10711160
/*******************************************************************\
@@ -1507,10 +1596,12 @@ Function: dump_c
15071596
void dump_c(
15081597
const goto_functionst &src,
15091598
const bool use_system_headers,
1599+
const bool include_harness,
15101600
const namespacet &ns,
15111601
std::ostream &out)
15121602
{
1513-
dump_ct goto2c(src, use_system_headers, ns, new_ansi_c_language);
1603+
dump_ct goto2c(
1604+
src, use_system_headers, include_harness, ns, new_ansi_c_language);
15141605
out << goto2c;
15151606
}
15161607

@@ -1529,9 +1620,11 @@ Function: dump_cpp
15291620
void dump_cpp(
15301621
const goto_functionst &src,
15311622
const bool use_system_headers,
1623+
const bool include_harness,
15321624
const namespacet &ns,
15331625
std::ostream &out)
15341626
{
1535-
dump_ct goto2cpp(src, use_system_headers, ns, new_cpp_language);
1627+
dump_ct goto2cpp(
1628+
src, use_system_headers, include_harness, ns, new_cpp_language);
15361629
out << goto2cpp;
15371630
}

src/goto-instrument/dump_c.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ Author: Daniel Kroening, [email protected]
1414
void dump_c(
1515
const goto_functionst &src,
1616
const bool use_system_headers,
17+
const bool include_harness,
1718
const namespacet &ns,
1819
std::ostream &out);
1920

2021
void dump_cpp(
2122
const goto_functionst &src,
2223
const bool use_system_headers,
24+
const bool include_harness,
2325
const namespacet &ns,
2426
std::ostream &out);
2527

src/goto-instrument/dump_c_class.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ class dump_ct
2222
dump_ct(
2323
const goto_functionst &_goto_functions,
2424
const bool use_system_headers,
25+
const bool include_harness,
2526
const namespacet &_ns,
2627
language_factoryt factory):
2728
goto_functions(_goto_functions),
2829
copied_symbol_table(_ns.get_symbol_table()),
2930
ns(copied_symbol_table),
30-
language(factory())
31+
language(factory()),
32+
harness(include_harness)
3133
{
3234
if(use_system_headers)
3335
init_system_library_map();
@@ -45,6 +47,7 @@ class dump_ct
4547
symbol_tablet copied_symbol_table;
4648
const namespacet ns;
4749
languaget *language;
50+
const bool harness;
4851

4952
typedef std::unordered_set<irep_idt, irep_id_hash> convertedt;
5053
convertedt converted_compound, converted_global, converted_enum;
@@ -133,6 +136,7 @@ class dump_ct
133136
code_declt &decl,
134137
std::list<irep_idt> &local_static,
135138
std::list<irep_idt> &local_type_decls);
139+
void cleanup_harness(code_blockt &b);
136140
};
137141

138142
#endif // CPROVER_GOTO_INSTRUMENT_DUMP_C_CLASS_H

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,8 @@ int goto_instrument_parse_optionst::doit()
649649
if(cmdline.isset("dump-c") || cmdline.isset("dump-cpp"))
650650
{
651651
const bool is_cpp=cmdline.isset("dump-cpp");
652-
const bool h=cmdline.isset("use-system-headers");
652+
const bool headers=cmdline.isset("use-system-headers");
653+
const bool harness=cmdline.isset("harness");
653654
namespacet ns(symbol_table);
654655

655656
// restore RETURN instructions in case remove_returns had been
@@ -668,10 +669,20 @@ int goto_instrument_parse_optionst::doit()
668669
error() << "failed to write to `" << cmdline.args[1] << "'";
669670
return 10;
670671
}
671-
(is_cpp ? dump_cpp : dump_c)(goto_functions, h, ns, out);
672+
(is_cpp ? dump_cpp : dump_c)(
673+
goto_functions,
674+
headers,
675+
harness,
676+
ns,
677+
out);
672678
}
673679
else
674-
(is_cpp ? dump_cpp : dump_c)(goto_functions, h, ns, std::cout);
680+
(is_cpp ? dump_cpp : dump_c)(
681+
goto_functions,
682+
headers,
683+
harness,
684+
ns,
685+
std::cout);
675686

676687
return 0;
677688
}
@@ -1640,6 +1651,7 @@ void goto_instrument_parse_optionst::help()
16401651
"\n"
16411652
"Other options:\n"
16421653
" --use-system-headers with --dump-c/--dump-cpp: generate C source with includes\n" // NOLINT(*)
1654+
" --harness with --dump-c/--dump-cpp: include input generator in output\n" // NOLINT(*)
16431655
" --version show version and exit\n"
16441656
" --xml-ui use XML-formatted output\n"
16451657
" --json-ui use JSON-formatted output\n"

src/goto-instrument/goto_instrument_parse_options.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Author: Daniel Kroening, [email protected]
2323
"(all)" \
2424
"(document-claims-latex)(document-claims-html)" \
2525
"(document-properties-latex)(document-properties-html)" \
26-
"(dump-c)(dump-cpp)(use-system-headers)(dot)(xml)" \
26+
"(dump-c)(dump-cpp)(use-system-headers)(harness)(dot)(xml)" \
2727
OPT_GOTO_CHECK \
2828
/* no-X-check are deprecated and ignored */ \
2929
"(no-bounds-check)(no-pointer-check)(no-div-by-zero-check)" \

0 commit comments

Comments
 (0)