Skip to content

Commit 093e97c

Browse files
authored
Merge pull request #5157 from antlechner/antonia/no_empty_module_symbols_in_module_map
[TG-9830] [UFC] Exclude symbols with empty module from the symbol module map
2 parents e1e7a74 + 4718929 commit 093e97c

File tree

4 files changed

+94
-29
lines changed

4 files changed

+94
-29
lines changed

src/util/symbol_table.cpp

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ std::pair<symbolt &, bool> symbol_tablet::insert(symbolt symbol)
2828
{
2929
symbol_base_mapt::iterator base_result=
3030
internal_symbol_base_map.emplace(new_symbol.base_name, new_symbol.name);
31-
try
31+
if(!new_symbol.module.empty())
3232
{
33-
internal_symbol_module_map.emplace(new_symbol.module, new_symbol.name);
34-
}
35-
catch(...)
36-
{
37-
internal_symbol_base_map.erase(base_result);
38-
throw;
33+
try
34+
{
35+
internal_symbol_module_map.emplace(
36+
new_symbol.module, new_symbol.name);
37+
}
38+
catch(...)
39+
{
40+
internal_symbol_base_map.erase(base_result);
41+
throw;
42+
}
3943
}
4044
}
4145
catch(...)
@@ -89,10 +93,8 @@ void symbol_tablet::erase(const symbolst::const_iterator &entry)
8993
{
9094
const symbolt &symbol=entry->second;
9195

92-
symbol_base_mapt::const_iterator
93-
base_it=symbol_base_map.lower_bound(entry->second.base_name);
94-
symbol_base_mapt::const_iterator
95-
base_it_end=symbol_base_map.upper_bound(entry->second.base_name);
96+
auto base_it = symbol_base_map.lower_bound(symbol.base_name);
97+
const auto base_it_end = symbol_base_map.upper_bound(symbol.base_name);
9698
while(base_it!=base_it_end && base_it->second!=symbol.name)
9799
++base_it;
98100
INVARIANT(
@@ -103,18 +105,23 @@ void symbol_tablet::erase(const symbolst::const_iterator &entry)
103105
"current base_name: "+id2string(symbol.base_name)+")");
104106
internal_symbol_base_map.erase(base_it);
105107

106-
symbol_module_mapt::const_iterator
107-
module_it=symbol_module_map.lower_bound(entry->second.module),
108-
module_it_end=symbol_module_map.upper_bound(entry->second.module);
109-
while(module_it!=module_it_end && module_it->second!=symbol.name)
110-
++module_it;
111-
INVARIANT(
112-
module_it!=module_it_end,
113-
"symbolt::module should not be changed "
114-
"after it is added to the symbol_table "
115-
"(name: "+id2string(symbol.name)+", "
116-
"current module: "+id2string(symbol.module)+")");
117-
internal_symbol_module_map.erase(module_it);
108+
if(!symbol.module.empty())
109+
{
110+
auto module_it = symbol_module_map.lower_bound(symbol.module);
111+
auto module_it_end = symbol_module_map.upper_bound(symbol.module);
112+
while(module_it != module_it_end && module_it->second != symbol.name)
113+
++module_it;
114+
INVARIANT(
115+
module_it != module_it_end,
116+
"symbolt::module should not be changed "
117+
"after it is added to the symbol_table "
118+
"(name: " +
119+
id2string(symbol.name) +
120+
", "
121+
"current module: " +
122+
id2string(symbol.module) + ")");
123+
internal_symbol_module_map.erase(module_it);
124+
}
118125

119126
internal_symbols.erase(entry);
120127
}

src/util/symbol_table.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
class symbol_tablet : public symbol_table_baset
2020
{
2121
private:
22+
/// Value referenced by \ref symbol_table_baset::symbols.
2223
symbolst internal_symbols;
24+
/// Value referenced by \ref symbol_table_baset::symbol_base_map.
2325
symbol_base_mapt internal_symbol_base_map;
26+
/// Value referenced by \ref symbol_table_baset::symbol_module_map.
2427
symbol_module_mapt internal_symbol_module_map;
2528

2629
public:

src/util/symbol_table_base.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,17 @@ class symbol_table_baset
2424
typedef std::unordered_map<irep_idt, symbolt> symbolst;
2525

2626
public:
27+
/// Read-only field, used to look up symbols given their names.
28+
/// Typically a subclass will have its own corresponding writeable field, and
29+
/// the read-only fields declared here function as "getters" for them.
2730
const symbolst &symbols;
31+
/// Read-only field, used to look up symbol names given their base names.
32+
/// See \ref symbols.
2833
const symbol_base_mapt &symbol_base_map;
34+
/// Read-only field, used to look up symbol names given their modules.
35+
/// See \ref symbols.
36+
/// Note that symbols whose module is empty are not recorded in this map.
37+
/// Currently only used in EBMC.
2938
const symbol_module_mapt &symbol_module_map;
3039

3140
public:

unit/util/symbol_table.cpp

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ SCENARIO(
5959
symbol_table.validate(validation_modet::EXCEPTION),
6060
incorrect_goto_program_exceptiont);
6161
}
62-
// Reset symbol to a valid name after the previous test
63-
transformed_symbol.name = symbol_name;
6462
}
6563
WHEN(
6664
"A symbol base_name is transformed without updating the base_name "
@@ -76,8 +74,6 @@ SCENARIO(
7674
symbol_table.validate(validation_modet::EXCEPTION),
7775
incorrect_goto_program_exceptiont);
7876
}
79-
// Reset symbol to a valid base_name after the previous test
80-
transformed_symbol.base_name = "TestBase";
8177
}
8278
WHEN(
8379
"A symbol module identifier is transformed without updating the module "
@@ -92,8 +88,58 @@ SCENARIO(
9288
symbol_table.validate(validation_modet::EXCEPTION),
9389
incorrect_goto_program_exceptiont);
9490
}
95-
// Reset symbol to a valid module name
96-
transformed_symbol.module = "TestModule";
91+
}
92+
}
93+
}
94+
95+
SCENARIO(
96+
"symbol_table_symbol_module_map",
97+
"[core][utils][symbol_table_symbol_module_map]")
98+
{
99+
GIVEN("A valid symbol table")
100+
{
101+
symbol_tablet symbol_table;
102+
WHEN("Inserting a symbol with non-empty module")
103+
{
104+
symbolt symbol;
105+
symbol.name = "TestName";
106+
symbol.module = "TestModule";
107+
symbol_table.insert(std::move(symbol));
108+
THEN("The symbol module map contains an entry for the symbol")
109+
{
110+
REQUIRE(symbol_table.symbol_module_map.size() == 1);
111+
const auto entry = symbol_table.symbol_module_map.begin();
112+
REQUIRE(id2string(entry->first) == "TestModule");
113+
REQUIRE(id2string(entry->second) == "TestName");
114+
}
115+
WHEN("Removing the symbol again")
116+
{
117+
symbol_table.remove("TestName");
118+
THEN("The symbol module map no longer contains an entry for the symbol")
119+
{
120+
REQUIRE(symbol_table.symbol_module_map.size() == 0);
121+
}
122+
}
123+
}
124+
WHEN("Inserting a symbol with empty module")
125+
{
126+
symbolt symbol;
127+
symbol.name = "TestName";
128+
symbol_table.insert(std::move(symbol));
129+
THEN("The symbol module map does not contain an entry for the symbol")
130+
{
131+
REQUIRE(symbol_table.symbol_module_map.size() == 0);
132+
}
133+
WHEN("Removing the symbol again")
134+
{
135+
symbol_table.remove("TestName");
136+
THEN(
137+
"The symbol module map still does not contain an entry for the "
138+
"symbol")
139+
{
140+
REQUIRE(symbol_table.symbol_module_map.size() == 0);
141+
}
142+
}
97143
}
98144
}
99145
}

0 commit comments

Comments
 (0)