Skip to content

Commit defc129

Browse files
authored
Merge pull request #1434 from diffblue/smv-identifier-checks
SMV: extract code for duplicate identifiers
2 parents 08032cc + 422ceab commit defc129

File tree

9 files changed

+135
-56
lines changed

9 files changed

+135
-56
lines changed

regression/smv/define/define2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
define2.smv
33

4-
^file .* line 6: variable `x' already declared.*$
4+
^file .* line 6: identifier x already used as variable$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

regression/smv/define/define3.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
define3.smv
33

4-
^file .* line 6: variable x already declared, at file .* line 3$
4+
^file .* line 6: identifier x already used as define$
55
^EXIT=2$
66
^SIGNAL=0$
77
--
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
name_collision1.smv
33

4-
^EXIT=0$
4+
^file .* line 6: identifier red already used as enum$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This crashes.

regression/smv/enums/name_collision2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
name_collision2.smv
33

4-
^file .* line 8: enum red already declared, at file .* line 3$
4+
^file .* line 8: identifier red already used as variable$
55
^EXIT=2$
66
^SIGNAL=0$
77
--
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
KNOWNBUG
1+
CORE
22
name_collision3.smv
33

4-
^EXIT=0$
4+
^file .* line 8: identifier red already used as enum$
5+
^EXIT=2$
56
^SIGNAL=0$
67
--
78
^warning: ignoring
89
--
9-
This crashes.

regression/smv/var/already_declared1.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
already_declared1.smv
33

4-
^file .* line 6: variable x already declared, at file .* line 3$
4+
^file .* line 6: identifier x already used as variable$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

regression/smv/var/already_declared2.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
already_declared2.smv
33

4-
^file .* line 6: variable x already declared, at file .* line 3$
4+
^file .* line 6: identifier x already used as define$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

regression/smv/var/already_declared3.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CORE
22
already_declared3.smv
33

4-
^file .* line 8: variable x already declared, at file .* line 5$
4+
^file .* line 8: identifier x already used as variable$
55
^EXIT=2$
66
^SIGNAL=0$
77
--

src/smvlang/smv_typecheck.cpp

Lines changed: 123 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ class smv_typecheckt:public typecheckt
6060
} modet;
6161

6262
void convert(smv_parse_treet::modulet &);
63-
void create_var_symbols(
64-
const smv_parse_treet::modulet::element_listt &,
65-
const std::list<irep_idt> &module_parameters);
63+
void create_var_symbols(const smv_parse_treet::modulet::element_listt &);
6664

6765
void collect_define(const equal_exprt &);
6866
void convert_defines(exprt::operandst &invar);
@@ -88,6 +86,8 @@ class smv_typecheckt:public typecheckt
8886
void check_type(typet &);
8987
smv_ranget convert_type(const typet &);
9088

89+
void variable_checks(const smv_parse_treet::modulet &);
90+
9191
void convert(smv_parse_treet::modulet::elementt &);
9292
void typecheck(smv_parse_treet::modulet::elementt &);
9393
void typecheck_expr_rec(exprt &, modet);
@@ -2126,7 +2126,7 @@ void smv_typecheckt::convert(smv_parse_treet::modulet::elementt &element)
21262126

21272127
/*******************************************************************\
21282128
2129-
Function: smv_typecheckt::create_var_symbols
2129+
Function: smv_typecheckt::variable_checks
21302130
21312131
Inputs:
21322132
@@ -2136,42 +2136,141 @@ Function: smv_typecheckt::create_var_symbols
21362136
21372137
\*******************************************************************/
21382138

2139-
void smv_typecheckt::create_var_symbols(
2140-
const smv_parse_treet::modulet::element_listt &elements,
2141-
const std::list<irep_idt> &module_parameters)
2139+
void smv_typecheckt::variable_checks(const smv_parse_treet::modulet &module)
21422140
{
2143-
const irep_idt mode = "SMV";
2141+
std::unordered_set<irep_idt, irep_id_hash> enums, defines, vars, parameters;
21442142

2145-
// to catch variables that have the same name as enums
2146-
std::unordered_set<irep_idt, irep_id_hash> enums;
2147-
2148-
// to catch re-use of parameter identifiers
2149-
std::unordered_set<irep_idt, irep_id_hash> parameters;
2150-
2151-
for(const auto &parameter : module_parameters)
2143+
for(const auto &parameter : module.parameters)
21522144
parameters.insert(parameter);
21532145

2154-
for(const auto &element : elements)
2146+
for(const auto &element : module.elements)
21552147
{
21562148
if(element.is_var() || element.is_ivar())
21572149
{
2158-
irep_idt base_name = to_smv_identifier_expr(element.expr).identifier();
2159-
irep_idt identifier = module + "::var::" + id2string(base_name);
2150+
const auto &identifier_expr = to_smv_identifier_expr(element.expr);
2151+
irep_idt base_name = identifier_expr.identifier();
21602152

21612153
// already used as enum?
21622154
if(enums.find(base_name) != enums.end())
21632155
{
2164-
throw errort{}.with_location(element.expr.source_location())
2156+
throw errort{}.with_location(identifier_expr.source_location())
21652157
<< "identifier " << base_name << " already used as enum";
21662158
}
21672159

21682160
// already used as a parameter?
21692161
if(parameters.find(base_name) != parameters.end())
21702162
{
2171-
throw errort{}.with_location(element.expr.source_location())
2163+
throw errort{}.with_location(identifier_expr.source_location())
2164+
<< "identifier " << base_name << " already used as a parameter";
2165+
}
2166+
2167+
// already used as variable?
2168+
if(vars.find(base_name) != vars.end())
2169+
{
2170+
throw errort{}.with_location(identifier_expr.source_location())
2171+
<< "identifier " << base_name << " already used as variable";
2172+
}
2173+
2174+
// already used as define?
2175+
if(defines.find(base_name) != defines.end())
2176+
{
2177+
throw errort{}.with_location(identifier_expr.source_location())
2178+
<< "identifier " << base_name << " already used as define";
2179+
}
2180+
2181+
vars.insert(base_name);
2182+
}
2183+
else if(element.is_define())
2184+
{
2185+
const auto &identifier_expr =
2186+
to_smv_identifier_expr(to_equal_expr(element.expr).lhs());
2187+
irep_idt base_name = identifier_expr.identifier();
2188+
2189+
// already used as enum?
2190+
if(enums.find(base_name) != enums.end())
2191+
{
2192+
throw errort{}.with_location(identifier_expr.source_location())
2193+
<< "identifier " << base_name << " already used as enum";
2194+
}
2195+
2196+
// already used as a parameter?
2197+
if(parameters.find(base_name) != parameters.end())
2198+
{
2199+
throw errort{}.with_location(identifier_expr.source_location())
21722200
<< "identifier " << base_name << " already used as a parameter";
21732201
}
21742202

2203+
// already used as variable?
2204+
if(vars.find(base_name) != vars.end())
2205+
{
2206+
throw errort{}.with_location(identifier_expr.source_location())
2207+
<< "identifier " << base_name << " already used as variable";
2208+
}
2209+
2210+
// already used as define?
2211+
if(defines.find(base_name) != defines.end())
2212+
{
2213+
throw errort{}.with_location(identifier_expr.source_location())
2214+
<< "identifier " << base_name << " already used as define";
2215+
}
2216+
2217+
defines.insert(base_name);
2218+
}
2219+
else if(element.is_enum())
2220+
{
2221+
const auto &identifier_expr = to_smv_identifier_expr(element.expr);
2222+
irep_idt base_name = identifier_expr.identifier();
2223+
2224+
// already used as a parameter?
2225+
if(parameters.find(base_name) != parameters.end())
2226+
{
2227+
throw errort{}.with_location(identifier_expr.source_location())
2228+
<< "identifier " << base_name << " already used as a parameter";
2229+
}
2230+
2231+
// already used as variable?
2232+
if(vars.find(base_name) != vars.end())
2233+
{
2234+
throw errort{}.with_location(identifier_expr.source_location())
2235+
<< "identifier " << base_name << " already used as variable";
2236+
}
2237+
2238+
// already used as define?
2239+
if(defines.find(base_name) != defines.end())
2240+
{
2241+
throw errort{}.with_location(identifier_expr.source_location())
2242+
<< "identifier " << base_name << " already used as define";
2243+
}
2244+
2245+
enums.insert(base_name);
2246+
}
2247+
}
2248+
}
2249+
2250+
/*******************************************************************\
2251+
2252+
Function: smv_typecheckt::create_var_symbols
2253+
2254+
Inputs:
2255+
2256+
Outputs:
2257+
2258+
Purpose:
2259+
2260+
\*******************************************************************/
2261+
2262+
void smv_typecheckt::create_var_symbols(
2263+
const smv_parse_treet::modulet::element_listt &elements)
2264+
{
2265+
const irep_idt mode = "SMV";
2266+
2267+
for(const auto &element : elements)
2268+
{
2269+
if(element.is_var() || element.is_ivar())
2270+
{
2271+
irep_idt base_name = to_smv_identifier_expr(element.expr).identifier();
2272+
irep_idt identifier = module + "::var::" + id2string(base_name);
2273+
21752274
auto symbol_ptr = symbol_table.lookup(identifier);
21762275
if(symbol_ptr != nullptr)
21772276
{
@@ -2213,20 +2312,6 @@ void smv_typecheckt::create_var_symbols(
22132312
irep_idt base_name = identifier_expr.identifier();
22142313
irep_idt identifier = module + "::var::" + id2string(base_name);
22152314

2216-
// already used as enum?
2217-
if(enums.find(base_name) != enums.end())
2218-
{
2219-
throw errort{}.with_location(identifier_expr.source_location())
2220-
<< "identifier " << base_name << " already used as enum";
2221-
}
2222-
2223-
// already used as a parameter?
2224-
if(parameters.find(base_name) != parameters.end())
2225-
{
2226-
throw errort{}.with_location(identifier_expr.source_location())
2227-
<< "identifier " << base_name << " already used as a parameter";
2228-
}
2229-
22302315
auto symbol_ptr = symbol_table.lookup(identifier);
22312316
if(symbol_ptr != nullptr)
22322317
{
@@ -2261,22 +2346,13 @@ void smv_typecheckt::create_var_symbols(
22612346
irep_idt base_name = to_smv_identifier_expr(element.expr).identifier();
22622347
irep_idt identifier = module + "::var::" + id2string(base_name);
22632348

2264-
// already used as a parameter?
2265-
if(parameters.find(base_name) != parameters.end())
2266-
{
2267-
throw errort{}.with_location(element.expr.source_location())
2268-
<< "identifier " << base_name << " already used as a parameter";
2269-
}
2270-
22712349
auto symbol_ptr = symbol_table.lookup(identifier);
22722350
if(symbol_ptr != nullptr)
22732351
{
22742352
throw errort{}.with_location(element.expr.source_location())
22752353
<< "enum " << base_name << " already declared, at "
22762354
<< symbol_ptr->location;
22772355
}
2278-
2279-
enums.insert(base_name);
22802356
}
22812357
}
22822358
}
@@ -2421,8 +2497,11 @@ void smv_typecheckt::convert(smv_parse_treet::modulet &smv_module)
24212497

24222498
define_map.clear();
24232499

2500+
// check for re-use of variables/defines/parameter identifiers
2501+
variable_checks(smv_module);
2502+
24242503
// variables/defines first, can be used before their declaration
2425-
create_var_symbols(smv_module.elements, smv_module.parameters);
2504+
create_var_symbols(smv_module.elements);
24262505

24272506
// transition relation
24282507

0 commit comments

Comments
 (0)