Skip to content

Commit df616e4

Browse files
committed
Add well-formedness checks for symbols.
Add a method that checks a symbol for structural validity according to some predetermined rule, and add it as an extra rule for symbol-table validity that each symbol is well-formed.
1 parent 5f55c33 commit df616e4

File tree

7 files changed

+88
-1
lines changed

7 files changed

+88
-1
lines changed

src/util/symbol.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Author: Daniel Kroening, [email protected]
1212

1313
#include "source_location.h"
1414
#include "std_expr.h"
15+
#include "suffix.h"
1516

1617
/// Dump the state of a symbol object to a given output stream.
1718
/// \param out: The stream to output object state to.
@@ -121,3 +122,25 @@ symbol_exprt symbolt::symbol_expr() const
121122
{
122123
return symbol_exprt(name, type);
123124
}
125+
126+
/// Check that the instance object is well formed.
127+
/// \return: true if well-formed; false otherwise.
128+
bool symbolt::is_well_formed() const
129+
{
130+
// Well-formedness criterion number 1 is for a symbol
131+
// to have a non-empty mode (see #1880)
132+
if(mode.empty())
133+
{
134+
return false;
135+
}
136+
137+
// Well-formedness criterion number 2 is for a symbol
138+
// to have it's base name as a suffix to it's more
139+
// general name.
140+
if(!has_suffix(id2string(name), id2string(base_name)))
141+
{
142+
return false;
143+
}
144+
145+
return true;
146+
}

src/util/symbol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ class symbolt
121121
PRECONDITION(type.id() == ID_code);
122122
value = exprt(ID_compiled);
123123
}
124+
125+
/// Check that a symbol is well formed.
126+
bool is_well_formed() const;
124127
};
125128

126129
std::ostream &operator<<(std::ostream &out, const symbolt &symbol);

src/util/symbol_table.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ void symbol_tablet::validate(const validation_modet vm) const
128128
const auto symbol_key = elem.first;
129129
const auto &symbol = elem.second;
130130

131+
// First of all, ensure symbol well-formedness
132+
DATA_CHECK_WITH_DIAGNOSTICS(
133+
vm, symbol.is_well_formed(), "Symbol is malformed: ", symbol_key);
134+
131135
// Check that symbols[id].name == id
132136
DATA_CHECK_WITH_DIAGNOSTICS(
133137
vm,

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ SRC += analyses/ai/ai.cpp \
6363
util/string_utils/split_string.cpp \
6464
util/string_utils/strip_string.cpp \
6565
util/symbol_table.cpp \
66+
util/symbol.cpp \
6667
util/unicode.cpp \
6768
# Empty last line
6869

unit/goto-programs/goto_model_function_type_consistency.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SCENARIO(
2222
code_typet fun_type2({}, type2);
2323

2424
symbolt function_symbol;
25+
function_symbol.mode = "C";
2526
irep_idt function_symbol_name = "foo";
2627
function_symbol.name = function_symbol_name;
2728

unit/util/symbol.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/// Author: Diffblue Ltd.
2+
3+
/// \file Tests for symbol_tablet
4+
5+
#include <testing-utils/catch.hpp>
6+
#include <util/exception_utils.h>
7+
#include <util/symbol.h>
8+
9+
SCENARIO(
10+
"Constructed symbol validity checks",
11+
"[core][utils][symbol__validity_checks]")
12+
{
13+
GIVEN("A valid symbol")
14+
{
15+
symbolt symbol;
16+
irep_idt symbol_name = "Test_TestBase";
17+
symbol.name = symbol_name;
18+
symbol.base_name = "TestBase";
19+
symbol.module = "TestModule";
20+
symbol.mode = "C";
21+
22+
THEN("Symbol should be well formed")
23+
{
24+
REQUIRE(symbol.is_well_formed());
25+
}
26+
}
27+
28+
GIVEN("An improperly initialised symbol")
29+
{
30+
symbolt symbol;
31+
32+
WHEN("The symbol doesn't have a valid mode")
33+
{
34+
symbol.mode = "";
35+
36+
THEN("Symbol well-formedness check should fail")
37+
{
38+
REQUIRE_FALSE(symbol.is_well_formed());
39+
}
40+
}
41+
42+
WHEN("The symbol doesn't have base name as a suffix to name")
43+
{
44+
symbol.name = "TEST";
45+
symbol.base_name = "TestBase";
46+
symbol.mode = "C";
47+
48+
THEN("Symbol well-formedness check should fail")
49+
{
50+
REQUIRE_FALSE(symbol.is_well_formed());
51+
}
52+
}
53+
}
54+
}

unit/util/symbol_table.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ SCENARIO(
3535
symbol_tablet symbol_table;
3636

3737
symbolt symbol;
38-
irep_idt symbol_name = "Test";
38+
irep_idt symbol_name = "Test_TestBase";
3939
symbol.name = symbol_name;
4040
symbol.base_name = "TestBase";
4141
symbol.module = "TestModule";
42+
symbol.mode = "C";
4243

4344
symbol_table.insert(symbol);
4445

0 commit comments

Comments
 (0)