Skip to content

Commit bd3ee6e

Browse files
Add move insert to symbol_table
Make insertions strong exception-safe Use emplace instead of insert
1 parent d0d3620 commit bd3ee6e

File tree

4 files changed

+64
-26
lines changed

4 files changed

+64
-26
lines changed

src/java_bytecode/java_utils.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ void generate_class_stub(
8686
new_symbol.mode=ID_java;
8787
new_symbol.is_type=true;
8888

89-
symbolt *class_symbol;
89+
auto res=symbol_table.insert(std::move(new_symbol));
9090

91-
if(symbol_table.move(new_symbol, class_symbol))
91+
if(!res)
9292
{
9393
messaget message(message_handler);
9494
message.warning() <<
@@ -99,7 +99,7 @@ void generate_class_stub(
9999
else
100100
{
101101
// create the class identifier etc
102-
java_root_class(*class_symbol);
102+
java_root_class(*res);
103103
}
104104
}
105105

src/util/fresh_symbol.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,22 @@ symbolt &get_fresh_aux_symbol(
2929
{
3030
static size_t temporary_counter=0;
3131
auxiliary_symbolt new_symbol;
32-
symbolt *symbol_ptr;
3332

34-
do
33+
optionalt<std::reference_wrapper<symbolt>> res;
34+
// Loop until find a name that doesn't clash with a non-auxilliary symbol
35+
while(!res)
3536
{
3637
// Distinguish local variables with the same name
3738
new_symbol.base_name=
38-
basename_prefix+
39-
"$"+
40-
std::to_string(++temporary_counter);
39+
basename_prefix+"$"+std::to_string(++temporary_counter);
4140
if(name_prefix.empty())
4241
new_symbol.name=new_symbol.base_name;
4342
else
44-
new_symbol.name=
45-
name_prefix+
46-
"::"+
47-
id2string(new_symbol.base_name);
43+
new_symbol.name=name_prefix+"::"+id2string(new_symbol.base_name);
4844
new_symbol.type=type;
4945
new_symbol.location=source_location;
5046
new_symbol.mode=symbol_mode;
47+
res=symbol_table.insert(std::move(new_symbol));
5148
}
52-
while(symbol_table.move(new_symbol, symbol_ptr));
53-
54-
return *symbol_ptr;
49+
return *res;
5550
}

src/util/symbol_table.cpp

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,31 @@ Author: Daniel Kroening, [email protected]
1616
/// there is a symbol with the same name already in the symbol table.
1717
bool symbol_tablet::add(const symbolt &symbol)
1818
{
19-
if(!symbols.insert(std::pair<irep_idt, symbolt>(symbol.name, symbol)).second)
19+
std::pair<symbolst::iterator, bool> result=
20+
symbols.emplace(symbol.name, symbol);
21+
if(!result.second)
2022
return true;
21-
22-
symbol_base_map.insert(
23-
std::pair<irep_idt, irep_idt>(symbol.base_name, symbol.name));
24-
symbol_module_map.insert(
25-
std::pair<irep_idt, irep_idt>(symbol.module, symbol.name));
26-
23+
add_base_and_module(result.first);
2724
return false;
2825
}
2926

27+
/// Move a new symbol to the symbol table
28+
/// \remark: This is a nicer interface than move but achieves the same result
29+
/// \param symbol: The symbol to be added to the symbol table
30+
/// \return Returns an optional reference to the newly inserted symbol, without
31+
/// a value if a symbol with the same name already exists in the symbol table
32+
optionalt<std::reference_wrapper<symbolt>> symbol_tablet::insert(
33+
symbolt &&symbol)
34+
{
35+
// Add the symbol to the table or retrieve existing symbol with the same name
36+
std::pair<symbolst::iterator, bool> result=
37+
symbols.emplace(symbol.name, std::move(symbol));
38+
if(!result.second)
39+
return optionalt<std::reference_wrapper<symbolt>>();
40+
add_base_and_module(result.first);
41+
return std::ref(result.first->second);
42+
}
43+
3044
/// Move a symbol into the symbol table. If there is already a symbol with the
3145
/// same name then symbol is unchanged, new_symbol points to the symbol with the
3246
/// same name and true is returned. Otherwise, the symbol is moved into the
@@ -55,17 +69,41 @@ bool symbol_tablet::move(symbolt &symbol, symbolt *&new_symbol)
5569
return true;
5670
}
5771

58-
symbol_base_map.emplace(symbol.base_name, symbol.name);
59-
symbol_module_map.emplace(symbol.module, symbol.name);
60-
6172
// Move the provided symbol into the symbol table
6273
result.first->second.swap(symbol);
74+
75+
add_base_and_module(result.first);
76+
6377
// Return the address of the new symbol in the table
6478
new_symbol=&result.first->second;
6579

6680
return false;
6781
}
6882

83+
void symbol_tablet::add_base_and_module(symbolst::iterator added_symbol)
84+
{
85+
symbolt &symbol=added_symbol->second;
86+
try
87+
{
88+
symbol_base_mapt::iterator base_result=
89+
symbol_base_map.emplace(symbol.base_name, symbol.name);
90+
try
91+
{
92+
symbol_module_map.emplace(symbol.module, symbol.name);
93+
}
94+
catch(...)
95+
{
96+
symbol_base_map.erase(base_result);
97+
throw;
98+
}
99+
}
100+
catch(...)
101+
{
102+
symbols.erase(added_symbol);
103+
throw;
104+
}
105+
}
106+
69107
/// Remove a symbol from the symbol table
70108
/// \param name: The name of the symbol to remove
71109
/// \return Returns a boolean indicating whether the process failed

src/util/symbol_table.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Author: Daniel Kroening, [email protected]
2323
#include <map>
2424
#include <unordered_map>
2525

26+
#include <util/optional.h>
27+
2628
#include "symbol.h"
2729

2830
#define forall_symbols(it, expr) \
@@ -60,12 +62,15 @@ class symbol_tablet
6062

6163
bool add(const symbolt &symbol);
6264

65+
optionalt<std::reference_wrapper<symbolt>> insert(symbolt &&symbol);
6366
bool move(symbolt &symbol, symbolt *&new_symbol);
64-
6567
// this will go away, use add instead
6668
bool move(symbolt &symbol)
6769
{ symbolt *new_symbol; return move(symbol, new_symbol); }
70+
private:
71+
void add_base_and_module(symbolst::iterator added_symbol);
6872

73+
public:
6974
void clear()
7075
{
7176
symbols.clear();

0 commit comments

Comments
 (0)