Skip to content

Commit f278f3d

Browse files
committed
C++ front-end: put "this" parameter in the symbol table
The "this" parameter must carry a unique name for each class and must be stored in the symbol table. And indeed make sure that all parameters are in the symbol table, unless the method a member of a class template and is never used, in which case the method symbol must be removed. Previously we mostly did this removal, but would fail for methods with a body not involving any symbols (as we tested for the existence of some cpp_name).
1 parent 42efbd7 commit f278f3d

5 files changed

+22
-16
lines changed

src/cpp/cpp_declarator_converter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,15 @@ symbolt &cpp_declarator_convertert::convert(
104104
{
105105
// adjust type if it's a non-static member function
106106
if(final_type.id()==ID_code)
107+
{
108+
cpp_save_scopet save_scope(cpp_typecheck.cpp_scopes);
109+
cpp_typecheck.cpp_scopes.go_to(*scope);
110+
107111
cpp_typecheck.add_this_to_method_type(
108112
cpp_typecheck.lookup(scope->identifier),
109113
to_code_type(final_type),
110114
method_qualifier);
115+
}
111116

112117
get_final_identifier();
113118

src/cpp/cpp_typecheck.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ void cpp_typecheckt::typecheck()
5454
for(auto &item : cpp_parse_tree.items)
5555
convert(item);
5656

57-
typecheck_method_bodies();
58-
5957
static_and_dynamic_initialization();
6058

59+
typecheck_method_bodies();
60+
6161
do_not_typechecked();
6262

6363
clean_up();
@@ -276,13 +276,10 @@ void cpp_typecheckt::clean_up()
276276

277277
const symbolt &symbol=cur_it->second;
278278

279-
// erase templates
280-
if(symbol.type.get_bool(ID_is_template) ||
281-
// Remove all symbols that have not been converted.
282-
// In particular this includes symbols created for functions
283-
// during template instantiation that are never called,
284-
// and hence, their bodies have not been converted.
285-
contains_cpp_name(symbol.value))
279+
// erase templates and all member functions that have not been converted
280+
if(
281+
symbol.type.get_bool(ID_is_template) ||
282+
deferred_typechecking.find(symbol.name) != deferred_typechecking.end())
286283
{
287284
symbol_table.erase(cur_it);
288285
continue;

src/cpp/cpp_typecheck.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ Author: Daniel Kroening, [email protected]
1212
#ifndef CPROVER_CPP_CPP_TYPECHECK_H
1313
#define CPROVER_CPP_CPP_TYPECHECK_H
1414

15-
#include <cassert>
16-
#include <set>
1715
#include <list>
1816
#include <map>
17+
#include <set>
18+
#include <unordered_set>
1919

2020
#include <util/std_code.h>
2121
#include <util/std_types.h>
@@ -588,6 +588,7 @@ class cpp_typecheckt:public c_typecheck_baset
588588
typedef std::list<irep_idt> dynamic_initializationst;
589589
dynamic_initializationst dynamic_initializations;
590590
bool disable_access_control; // Disable protect and private
591+
std::unordered_set<irep_idt> deferred_typechecking;
591592
};
592593

593594
#endif // CPROVER_CPP_CPP_TYPECHECK_H

src/cpp/cpp_typecheck_compound_type.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,8 +1335,7 @@ void cpp_typecheckt::typecheck_member_function(
13351335
// Is this in a class template?
13361336
// If so, we defer typechecking until used.
13371337
if(cpp_scopes.current_scope().get_parent().is_template_scope())
1338-
{
1339-
}
1338+
deferred_typechecking.insert(new_symbol->name);
13401339
else // remember for later typechecking of body
13411340
add_method_body(new_symbol);
13421341
}
@@ -1360,9 +1359,11 @@ void cpp_typecheckt::add_this_to_method_type(
13601359
subtype.set(ID_C_volatile, true);
13611360

13621361
code_typet::parametert parameter(pointer_type(subtype));
1363-
parameter.set_identifier(ID_this); // check? Not qualified
1362+
parameter.set_identifier(ID_this);
13641363
parameter.set_base_name(ID_this);
13651364
parameter.set_this();
1365+
if(!cpp_scopes.current_scope().get_parent().is_template_scope())
1366+
convert_parameter(compound_symbol.mode, parameter);
13661367

13671368
code_typet::parameterst &parameters = type.parameters();
13681369
parameters.insert(parameters.begin(), parameter);

src/cpp/cpp_typecheck_function.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void cpp_typecheckt::convert_parameter(
3131
parameter.set_base_name(base_name);
3232
}
3333

34+
PRECONDITION(!cpp_scopes.current_scope().prefix.empty());
3435
irep_idt identifier=cpp_scopes.current_scope().prefix+
3536
id2string(base_name);
3637

@@ -147,6 +148,8 @@ void cpp_typecheckt::convert_function(symbolt &symbol)
147148
symbol.value.type()=symbol.type;
148149

149150
return_type = old_return_type;
151+
152+
deferred_typechecking.erase(symbol.name);
150153
}
151154

152155
/// for function overloading
@@ -171,8 +174,7 @@ irep_idt cpp_typecheckt::function_identifier(const typet &type)
171174
code_typet::parameterst::const_iterator it=
172175
parameters.begin();
173176

174-
if(it!=parameters.end() &&
175-
it->get_identifier()==ID_this)
177+
if(it != parameters.end() && it->get_base_name() == ID_this)
176178
{
177179
const typet &pointer=it->type();
178180
const typet &symbol =pointer.subtype();

0 commit comments

Comments
 (0)