Skip to content

Commit 9d3adc0

Browse files
committed
Introduce get_goto_model_from_c() for use in unit tests
The function takes a C program (as a string or an input stream) and converts it to a goto model.
1 parent 2e0a7f0 commit 9d3adc0

File tree

6 files changed

+185
-57
lines changed

6 files changed

+185
-57
lines changed

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ SRC += analyses/ai/ai.cpp \
1616
analyses/does_remove_const/is_type_at_least_as_const_as.cpp \
1717
big-int/big-int.cpp \
1818
compound_block_locations.cpp \
19+
get_goto_model_from_c_test.cpp \
1920
goto-checker/report_util/is_property_less_than.cpp \
2021
goto-instrument/cover_instrument.cpp \
2122
goto-instrument/cover/cover_only.cpp \

unit/get_goto_model_from_c_test.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*******************************************************************\
2+
3+
Module: Get goto model test
4+
5+
Author: Daniel Poetzl
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/use_catch.h>
10+
#include <testing-utils/get_goto_model_from_c.h>
11+
12+
TEST_CASE("Get goto model from C test", "[core]")
13+
{
14+
const std::string code =
15+
"int g;"
16+
"void f(int a) { int b; }"
17+
"void main() {}";
18+
19+
const auto goto_model_opt = get_goto_model_from_c(code);
20+
REQUIRE(goto_model_opt);
21+
22+
const auto &goto_model = *goto_model_opt;
23+
24+
const auto &function_map = goto_model.goto_functions.function_map;
25+
26+
REQUIRE(function_map.find("main") != function_map.end());
27+
REQUIRE(function_map.find(CPROVER_PREFIX "_start") != function_map.end());
28+
REQUIRE(function_map.find("f") != function_map.end());
29+
30+
const auto &main_instructions = function_map.at("main").body.instructions;
31+
REQUIRE(!main_instructions.empty());
32+
33+
const auto &f_instructions = function_map.at("f").body.instructions;
34+
REQUIRE(f_instructions.size() >= 2);
35+
36+
const auto &symbol_table = goto_model.symbol_table;
37+
38+
REQUIRE(symbol_table.has_symbol("main"));
39+
REQUIRE(symbol_table.has_symbol(CPROVER_PREFIX "_start"));
40+
REQUIRE(symbol_table.has_symbol("g"));
41+
REQUIRE(symbol_table.has_symbol("f::a"));
42+
REQUIRE(symbol_table.has_symbol("f::1::b"));
43+
}

unit/json_symbol_table.cpp

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <util/options.h>
2424
#include <util/symbol_table.h>
2525

26+
#include <testing-utils/get_goto_model_from_c.h>
2627
#include <testing-utils/message.h>
2728
#include <testing-utils/use_catch.h>
2829

@@ -49,67 +50,14 @@ class test_ui_message_handlert : public ui_message_handlert
4950
json_stream_arrayt json_stream_array;
5051
};
5152

52-
void get_goto_model(std::istream &in, goto_modelt &goto_model)
53-
{
54-
optionst options;
55-
cbmc_parse_optionst::set_default_options(options);
56-
57-
messaget null_message(null_message_handler);
58-
59-
language_filest language_files;
60-
language_files.set_message_handler(null_message_handler);
61-
62-
std::string filename;
63-
64-
language_filet &language_file = language_files.add_file(filename);
65-
66-
language_file.language = get_default_language();
67-
68-
languaget &language = *language_file.language;
69-
language.set_message_handler(null_message_handler);
70-
language.set_language_options(options);
71-
72-
{
73-
bool r = language.parse(in, filename);
74-
REQUIRE(!r);
75-
}
76-
77-
language_file.get_modules();
78-
79-
{
80-
bool r = language_files.typecheck(goto_model.symbol_table);
81-
REQUIRE(!r);
82-
}
83-
84-
REQUIRE(!goto_model.symbol_table.has_symbol(goto_functionst::entry_point()));
85-
86-
{
87-
bool r = language_files.generate_support_functions(goto_model.symbol_table);
88-
REQUIRE(!r);
89-
}
90-
91-
goto_convert(
92-
goto_model.symbol_table, goto_model.goto_functions, null_message_handler);
93-
}
94-
9553
TEST_CASE("json symbol table read/write consistency")
9654
{
97-
register_language(new_ansi_c_language);
98-
99-
cmdlinet cmdline;
100-
config.main = std::string("main");
101-
config.set(cmdline);
102-
103-
goto_modelt goto_model;
104-
10555
// Get symbol table associated with goto program
56+
const std::string program = "int main() { return 0; }\n";
57+
const auto goto_model_opt = get_goto_model_from_c(program);
10658

107-
{
108-
std::string program = "int main() { return 0; }\n";
109-
110-
std::istringstream in(program);
111-
get_goto_model(in, goto_model);
112-
}
59+
REQUIRE(goto_model_opt);
60+
const auto &goto_model = *goto_model_opt;
11361

11462
const symbol_tablet &symbol_table1 = goto_model.symbol_table;
11563

unit/testing-utils/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
SRC = \
22
call_graph_test_utils.cpp \
33
free_form_cmdline.cpp \
4+
get_goto_model_from_c.cpp \
45
invariant.cpp \
56
message.cpp \
67
require_expr.cpp \
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*******************************************************************\
2+
3+
Module: Get goto model
4+
5+
Author: Daniel Poetzl
6+
7+
\*******************************************************************/
8+
9+
#include "get_goto_model_from_c.h"
10+
11+
#include <ansi-c/ansi_c_language.h>
12+
13+
#include <cbmc/cbmc_parse_options.h>
14+
15+
#include <goto-programs/goto_convert_functions.h>
16+
17+
#include <langapi/language_file.h>
18+
#include <langapi/mode.h>
19+
20+
#include <util/cmdline.h>
21+
#include <util/config.h>
22+
#include <util/invariant.h>
23+
#include <util/message.h>
24+
#include <util/options.h>
25+
#include <util/symbol_table.h>
26+
27+
#include <testing-utils/message.h>
28+
29+
namespace
30+
{
31+
bool initialized = false;
32+
optionst options;
33+
34+
void initialize()
35+
{
36+
PRECONDITION(!initialized);
37+
38+
register_language(new_ansi_c_language);
39+
40+
cmdlinet cmdline;
41+
42+
config.main = std::string("main");
43+
config.set(cmdline);
44+
45+
optionst options;
46+
cbmc_parse_optionst::set_default_options(options);
47+
}
48+
}
49+
50+
optionalt<goto_modelt> get_goto_model_from_c(std::istream &in)
51+
{
52+
if(!initialized)
53+
{
54+
initialize();
55+
initialized = true;
56+
}
57+
58+
language_filest language_files;
59+
language_files.set_message_handler(null_message_handler);
60+
61+
language_filet &language_file = language_files.add_file("");
62+
63+
language_file.language = get_default_language();
64+
65+
languaget &language = *language_file.language;
66+
language.set_message_handler(null_message_handler);
67+
language.set_language_options(options);
68+
69+
{
70+
const bool error = language.parse(in, "");
71+
72+
if(error)
73+
return {};
74+
}
75+
76+
language_file.get_modules();
77+
78+
goto_modelt goto_model;
79+
80+
{
81+
const bool error = language_files.typecheck(goto_model.symbol_table);
82+
83+
if(error)
84+
return {};
85+
}
86+
87+
{
88+
const bool error =
89+
language_files.generate_support_functions(goto_model.symbol_table);
90+
91+
if(error)
92+
return {};
93+
}
94+
95+
goto_convert(
96+
goto_model.symbol_table, goto_model.goto_functions, null_message_handler);
97+
98+
return goto_model;
99+
}
100+
101+
optionalt<goto_modelt> get_goto_model_from_c(const std::string &code)
102+
{
103+
std::istringstream in(code);
104+
return get_goto_model_from_c(in);
105+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*******************************************************************\
2+
3+
Module: Get goto model
4+
5+
Author: Daniel Poetzl
6+
7+
\*******************************************************************/
8+
9+
#ifndef UNIT_TESTING_UTILS_GET_GOTO_MODEL_H
10+
#define UNIT_TESTING_UTILS_GET_GOTO_MODEL_H
11+
12+
#include <goto-programs/goto_model.h>
13+
14+
#include <util/optional.h>
15+
16+
#include <iosfwd>
17+
18+
/// Convert C program to a goto model
19+
///
20+
/// \param code: string giving the C program
21+
/// \return goto model if successful, empty optional otherwise
22+
optionalt<goto_modelt> get_goto_model_from_c(const std::string &code);
23+
24+
/// Convert C program to a goto model
25+
///
26+
/// \param in: input stream to read a C program from
27+
/// \return goto model if successful, empty optional otherwise
28+
optionalt<goto_modelt> get_goto_model_from_c(const std::istream &in);
29+
30+
#endif /* UNIT_TESTING_UTILS_GET_GOTO_MODEL_H_ */

0 commit comments

Comments
 (0)