Skip to content

Commit 849aca8

Browse files
Add option handling for dynamic array initialisation
Adds the --pointers-to-treat-as-arrays --associated-array-sizes --max-dynamic-array-size options. The intended behaviour is that the former should indicate which of the function parameters to an entry function that are pointers should be backed by an array, the parameter that should hold the size of that array (if any) and the maximum size of such an array (minimum 1) respectively. These options currently have no effect and will be implemented in a later commit
1 parent 6a700f6 commit 849aca8

File tree

3 files changed

+143
-2
lines changed

3 files changed

+143
-2
lines changed

src/ansi-c/ansi_c_language.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,26 @@ Author: Daniel Kroening, [email protected]
2222
// clang-format off
2323
#define OPT_ANSI_C_LANGUAGE \
2424
"(max-nondet-tree-depth):" \
25-
"(min-null-tree-depth):"
25+
"(min-null-tree-depth):" \
26+
"(pointers-to-treat-as-arrays):" \
27+
"(associated-array-sizes):" \
28+
"(max-dynamic-array-size):" \
2629

2730
#define HELP_ANSI_C_LANGUAGE \
2831
" --max-nondet-tree-depth N limit size of nondet (e.g. input) object tree;\n" /* NOLINT(*) */\
2932
" at level N pointers are set to null\n" \
3033
" --min-null-tree-depth N minimum level at which a pointer can first be\n" /* NOLINT(*) */\
31-
" NULL in a recursively nondet initialized struct\n" /* NOLINT(*) */
34+
" NULL in a recursively nondet initialized struct\n" /* NOLINT(*) */\
35+
" --pointers-to-treat-as-arrays <identifier,...> comma separated list of\n" \
36+
" identifiers that should be initialized as arrays\n" /* NOLINT(*) */ \
37+
" --associated-array-sizes <identifier:identifier...>\n" \
38+
" comma separated list of colon separated pairs\n" /* NOLINT(*) */ \
39+
" of identifiers; The first element of the pair \n" /* NOLINT(*) */ \
40+
" should be the name of an array pointer \n" \
41+
" (see --pointers-to-treat-as-arrays),\n" \
42+
" the second an integer parameter that\n" \
43+
" should hold its size\n" \
44+
" --max-dynamic-array-size <size> max size for dynamically allocated arrays\n" /* NOLINT(*) */
3245
// clang-format on
3346

3447
class ansi_c_languaget:public languaget

src/ansi-c/c_object_factory_parameters.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,118 @@ Author: Daniel Poetzl
88

99
#include "c_object_factory_parameters.h"
1010

11+
#include <util/cmdline.h>
12+
#include <util/exception_utils.h>
13+
#include <util/optional_utils.h>
14+
#include <util/string_utils.h>
15+
16+
#include <algorithm>
17+
#include <iterator>
18+
#include <string>
19+
1120
void parse_c_object_factory_options(const cmdlinet &cmdline, optionst &options)
1221
{
1322
parse_object_factory_options(cmdline, options);
23+
if(cmdline.isset("pointers-to-treat-as-arrays"))
24+
{
25+
options.set_option(
26+
"pointers-to-treat-as-arrays",
27+
cmdline.get_comma_separated_values("pointers-to-treat-as-arrays"));
28+
}
29+
if(cmdline.isset("associated-array-sizes"))
30+
{
31+
options.set_option(
32+
"associated-array-sizes",
33+
cmdline.get_comma_separated_values("associated-array-sizes"));
34+
}
35+
if(cmdline.isset("max-dynamic-array-size"))
36+
{
37+
options.set_option(
38+
"max-dynamic-array-size", cmdline.get_value("max-dynamic-array-size"));
39+
}
40+
}
41+
42+
void c_object_factory_parameterst::set(const optionst &options)
43+
{
44+
object_factory_parameterst::set(options);
45+
auto const &pointers_to_treat_as_array =
46+
options.get_list_option("pointers-to-treat-as-arrays");
47+
std::transform(
48+
std::begin(pointers_to_treat_as_array),
49+
std::end(pointers_to_treat_as_array),
50+
std::inserter(
51+
this->pointers_to_treat_as_array, this->pointers_to_treat_as_array.end()),
52+
id2string);
53+
54+
if(options.is_set("max-dynamic-array-size"))
55+
{
56+
max_dynamic_array_size =
57+
options.get_unsigned_int_option("max-dynamic-array-size");
58+
if(max_dynamic_array_size == 0)
59+
{
60+
throw invalid_command_line_argument_exceptiont(
61+
"Max dynamic array size must be >= 1", "--max-dynamic-array-size");
62+
}
63+
}
64+
if(options.is_set("associated-array-sizes"))
65+
{
66+
array_name_to_associated_array_size_variable.clear();
67+
variables_that_hold_array_sizes.clear();
68+
auto const &array_size_pairs =
69+
options.get_list_option("associated-array-sizes");
70+
for(auto const &array_size_pair : array_size_pairs)
71+
{
72+
std::string array_name;
73+
std::string size_name;
74+
try
75+
{
76+
split_string(array_size_pair, ':', array_name, size_name);
77+
}
78+
catch(const deserialization_exceptiont &e)
79+
{
80+
throw invalid_command_line_argument_exceptiont{
81+
"can't parse parameter value",
82+
"--associated-array-sizes",
83+
"pairs of array/size parameter names, separated by a ':' colon"};
84+
}
85+
auto const mapping_insert_result =
86+
array_name_to_associated_array_size_variable.insert(
87+
{irep_idt{array_name}, irep_idt{size_name}});
88+
if(!mapping_insert_result.second)
89+
{
90+
throw invalid_command_line_argument_exceptiont{
91+
"duplicate associated size entries for array `" + array_name +
92+
"', existing: `" + id2string(mapping_insert_result.first->second) +
93+
"', tried to insert: `" + size_name + "'",
94+
"--associated-array-sizes"};
95+
}
96+
auto const size_name_insert_result =
97+
variables_that_hold_array_sizes.insert(irep_idt{size_name});
98+
if(!size_name_insert_result.second)
99+
{
100+
throw invalid_command_line_argument_exceptiont{
101+
"using size parameter `" + size_name + "' more than once",
102+
"--associated-array-sizes"};
103+
}
104+
}
105+
}
106+
}
107+
108+
bool c_object_factory_parameterst::is_array_size_parameter(irep_idt id) const
109+
{
110+
return variables_that_hold_array_sizes.find(id) !=
111+
end(variables_that_hold_array_sizes);
112+
}
113+
114+
optionalt<irep_idt> c_object_factory_parameterst::get_associated_size_variable(
115+
irep_idt array_id) const
116+
{
117+
return optional_lookup(
118+
array_name_to_associated_array_size_variable, array_id);
119+
}
120+
121+
bool c_object_factory_parameterst::should_be_treated_as_array(irep_idt id) const
122+
{
123+
return pointers_to_treat_as_array.find(id) !=
124+
pointers_to_treat_as_array.end();
14125
}

src/ansi-c/c_object_factory_parameters.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ Author: Daniel Poetzl
99
#ifndef CPROVER_ANSI_C_C_OBJECT_FACTORY_PARAMETERS_H
1010
#define CPROVER_ANSI_C_C_OBJECT_FACTORY_PARAMETERS_H
1111

12+
#include <map>
13+
#include <set>
1214
#include <util/object_factory_parameters.h>
15+
#include <util/optional.h>
16+
#include <util/options.h>
1317

1418
struct c_object_factory_parameterst final : public object_factory_parameterst
1519
{
@@ -21,6 +25,19 @@ struct c_object_factory_parameterst final : public object_factory_parameterst
2125
: object_factory_parameterst(options)
2226
{
2327
}
28+
29+
bool should_be_treated_as_array(irep_idt id) const;
30+
bool is_array_size_parameter(irep_idt id) const;
31+
optionalt<irep_idt> get_associated_size_variable(irep_idt array_id) const;
32+
33+
void set(const optionst &options) override;
34+
35+
std::size_t max_dynamic_array_size = 2;
36+
37+
private:
38+
std::set<irep_idt> pointers_to_treat_as_array;
39+
std::set<irep_idt> variables_that_hold_array_sizes;
40+
std::map<irep_idt, irep_idt> array_name_to_associated_array_size_variable;
2441
};
2542

2643
/// Parse the c object factory parameters from a given command line

0 commit comments

Comments
 (0)