Skip to content

Commit 0b777df

Browse files
authored
Merge pull request #7238 from tautschnig/bugfixes/7057-entry-point
C/C++ entry-point: resolve full symbol names
2 parents 3bb84f7 + e7d482a commit 0b777df

File tree

5 files changed

+55
-20
lines changed

5 files changed

+55
-20
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
void mymain()
2+
{
3+
__CPROVER_assert(false, "expected to fail");
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.cpp
3+
--function 'mymain()'
4+
^VERIFICATION FAILED$
5+
^EXIT=10$
6+
^SIGNAL=0$
7+
--
8+
^warning: ignoring

src/ansi-c/ansi_c_entry_point.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ Author: Daniel Kroening, [email protected]
1313
#include <util/config.h>
1414
#include <util/message.h>
1515
#include <util/pointer_expr.h>
16-
#include <util/range.h>
1716
#include <util/symbol_table_base.h>
1817

1918
#include <goto-programs/goto_functions.h>
@@ -118,20 +117,14 @@ bool ansi_c_entry_point(
118117
// find main symbol, if any is given
119118
if(config.main.has_value())
120119
{
121-
std::list<irep_idt> matches;
120+
auto matches = symbol_table.match_name_or_base_name(*config.main);
122121

123-
for(const auto &symbol_name_entry :
124-
equal_range(symbol_table.symbol_base_map, config.main.value()))
122+
for(auto it = matches.begin(); it != matches.end();) // no ++it
125123
{
126-
// look it up
127-
symbol_table_baset::symbolst::const_iterator s_it =
128-
symbol_table.symbols.find(symbol_name_entry.second);
129-
130-
if(s_it==symbol_table.symbols.end())
131-
continue;
132-
133-
if(s_it->second.type.id() == ID_code && !s_it->second.is_property)
134-
matches.push_back(symbol_name_entry.second);
124+
if((*it)->second.type.id() != ID_code || (*it)->second.is_property)
125+
it = matches.erase(it);
126+
else
127+
++it;
135128
}
136129

137130
if(matches.empty())
@@ -150,7 +143,7 @@ bool ansi_c_entry_point(
150143
return true;
151144
}
152145

153-
main_symbol=matches.front();
146+
main_symbol = matches.front()->first;
154147
}
155148
else
156149
main_symbol=ID_main;

src/goto-programs/initialize_goto_model.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,20 @@ static bool generate_entry_point_for_function(
4040
{
4141
const irep_idt &entry_function_name = options.get_option("function");
4242
CHECK_RETURN(!entry_function_name.empty());
43-
auto const entry_function_sym = symbol_table.lookup(entry_function_name);
44-
if(entry_function_sym == nullptr)
43+
auto matches = symbol_table.match_name_or_base_name(entry_function_name);
44+
// it's ok if this is ambiguous at this point, we just need to get a mode, the
45+
// actual entry point generator will take care of resolving (or rejecting)
46+
// ambiguity
47+
if(matches.empty())
4548
{
4649
throw invalid_command_line_argument_exceptiont{
47-
// NOLINTNEXTLINE(whitespace/braces)
48-
std::string{"couldn't find function with name '"} +
50+
std::string("couldn't find entry with name '") +
4951
id2string(entry_function_name) + "' in symbol table",
5052
"--function"};
5153
}
52-
PRECONDITION(!entry_function_sym->mode.empty());
53-
auto const entry_language = get_language_from_mode(entry_function_sym->mode);
54+
const auto &entry_point_mode = matches.front()->second.mode;
55+
PRECONDITION(!entry_point_mode.empty());
56+
auto const entry_language = get_language_from_mode(entry_point_mode);
5457
CHECK_RETURN(entry_language != nullptr);
5558
entry_language->set_message_handler(message_handler);
5659
entry_language->set_language_options(options);

src/util/symbol_table_base.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,33 @@ class symbol_table_baset
109109
return *symbol;
110110
}
111111

112+
/// Collect all symbols the name of which matches \p id or the base name of
113+
/// which matches \p id.
114+
std::list<symbolst::const_iterator>
115+
match_name_or_base_name(const irep_idt &id) const
116+
{
117+
std::list<symbolst::const_iterator> results;
118+
119+
auto name_it = symbols.find(id);
120+
if(name_it != symbols.end())
121+
results.push_back(name_it);
122+
123+
auto base_name_it_pair = symbol_base_map.equal_range(id);
124+
for(auto base_name_it = base_name_it_pair.first;
125+
base_name_it != base_name_it_pair.second;
126+
++base_name_it)
127+
{
128+
name_it = symbols.find(base_name_it->second);
129+
CHECK_RETURN(name_it != symbols.end());
130+
// don't add entries where name and base name match as this amounts to the
131+
// case already covered above
132+
if(base_name_it->first != base_name_it->second)
133+
results.push_back(name_it);
134+
}
135+
136+
return results;
137+
}
138+
112139
/// Find a symbol in the symbol table for read-write access.
113140
/// \param name: The name of the symbol to look for
114141
/// \return A pointer to the found symbol if it exists, nullptr otherwise.

0 commit comments

Comments
 (0)