Skip to content

Commit 7df3543

Browse files
committed
Remove typecheckt interface from linkingt
There is no particular benefit in this inheritance. Also prepare for maintaining state across multiple calls to the linker by making the source symbol table an argument specific to each linking call.
1 parent cfcfcf6 commit 7df3543

File tree

4 files changed

+115
-100
lines changed

4 files changed

+115
-100
lines changed

regression/cbmc/incomplete-structs/test.desc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
CORE new-smt-backend
22
typesmain.c
33
types1.c types2.c types3.c
4-
reason for conflict at \*#this.u: number of members is different \(3/0\)
5-
reason for conflict at \*#this.u: number of members is different \(0/3\)
6-
struct U \(incomplete\)
74
warning: pointer parameter types differ between declaration and definition "bar"
85
warning: pointer parameter types differ between declaration and definition "foo"
96
^VERIFICATION SUCCESSFUL$

src/goto-programs/link_goto_model.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ Author: Michael Tautschnig, Daniel Kroening
1010
/// Link Goto Programs
1111

1212
#include "link_goto_model.h"
13+
#include <linking/linking_class.h>
1314

14-
#include <unordered_set>
15-
16-
#include <util/symbol.h>
15+
#include <util/message.h>
1716
#include <util/rename_symbol.h>
18-
19-
#include <linking/linking_class.h>
17+
#include <util/symbol.h>
2018

2119
#include "goto_model.h"
2220

21+
#include <unordered_set>
22+
2323
static void rename_symbols_in_function(
2424
goto_functionst::goto_functiont &function,
2525
irep_idt &new_function_name,
@@ -119,9 +119,9 @@ optionalt<replace_symbolt::expr_mapt> link_goto_model(
119119
weak_symbols.insert(symbol_pair.first);
120120
}
121121

122-
linkingt linking(dest.symbol_table, src.symbol_table, message_handler);
122+
linkingt linking(dest.symbol_table, message_handler);
123123

124-
if(linking.typecheck_main())
124+
if(linking.link(src.symbol_table))
125125
{
126126
messaget log{message_handler};
127127
log.error() << "typechecking main failed" << messaget::eom;

src/linking/linking.cpp

Lines changed: 90 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Daniel Kroening, [email protected]
1515
#include <util/c_types.h>
1616
#include <util/find_symbols.h>
1717
#include <util/mathematical_types.h>
18+
#include <util/message.h>
1819
#include <util/pointer_expr.h>
1920
#include <util/pointer_offset_size.h>
2021
#include <util/simplify_expr.h>
@@ -201,7 +202,8 @@ bool linkingt::detailed_conflict_report_rec(
201202
bool conclusive = false;
202203

203204
#ifdef DEBUG
204-
debug() << "<BEGIN DEPTH " << depth << ">" << eom;
205+
messaget log{message_handler};
206+
log.debug() << "<BEGIN DEPTH " << depth << ">" << messaget::eom;
205207
#endif
206208

207209
std::string msg;
@@ -455,18 +457,23 @@ bool linkingt::detailed_conflict_report_rec(
455457

456458
if(conclusive && !msg.empty())
457459
{
458-
error() << '\n';
459-
error() << "reason for conflict at "
460-
<< expr_to_string(irep_idt(), conflict_path) << ": " << msg << '\n';
461-
462-
error() << '\n';
463-
error() << type_to_string_verbose(old_symbol, t1) << '\n';
464-
error() << type_to_string_verbose(new_symbol, t2) << '\n';
460+
#ifndef DEBUG
461+
messaget log{message_handler};
462+
#endif
463+
log.error() << '\n';
464+
log.error() << "reason for conflict at "
465+
<< expr_to_string(irep_idt(), conflict_path) << ": " << msg
466+
<< '\n';
467+
468+
log.error() << '\n';
469+
log.error() << type_to_string_verbose(old_symbol, t1) << '\n';
470+
log.error() << type_to_string_verbose(new_symbol, t2) << '\n'
471+
<< messaget::eom;
465472
}
466473

467474
#ifdef DEBUG
468-
debug() << "<END DEPTH " << depth << ">" << eom;
469-
#endif
475+
log.debug() << "<END DEPTH " << depth << ">" << messaget::eom;
476+
#endif
470477

471478
return conclusive;
472479
}
@@ -476,37 +483,39 @@ void linkingt::link_error(
476483
const symbolt &new_symbol,
477484
const std::string &msg)
478485
{
479-
error().source_location=new_symbol.location;
480-
481-
error() << "error: " << msg << " '" << old_symbol.display_name() << "'"
482-
<< '\n';
483-
error() << "old definition in module '" << old_symbol.module << "' "
484-
<< old_symbol.location << '\n'
485-
<< type_to_string_verbose(old_symbol) << '\n';
486-
error() << "new definition in module '" << new_symbol.module << "' "
487-
<< new_symbol.location << '\n'
488-
<< type_to_string_verbose(new_symbol) << eom;
486+
messaget log{message_handler};
487+
log.error().source_location = new_symbol.location;
488+
489+
log.error() << "error: " << msg << " '" << old_symbol.display_name() << "'"
490+
<< '\n';
491+
log.error() << "old definition in module '" << old_symbol.module << "' "
492+
<< old_symbol.location << '\n'
493+
<< type_to_string_verbose(old_symbol) << '\n';
494+
log.error() << "new definition in module '" << new_symbol.module << "' "
495+
<< new_symbol.location << '\n'
496+
<< type_to_string_verbose(new_symbol) << messaget::eom;
489497
}
490498

491499
void linkingt::link_warning(
492500
const symbolt &old_symbol,
493501
const symbolt &new_symbol,
494502
const std::string &msg)
495503
{
496-
warning().source_location=new_symbol.location;
497-
498-
warning() << "warning: " << msg << " \""
499-
<< old_symbol.display_name()
500-
<< "\"" << '\n';
501-
warning() << "old definition in module " << old_symbol.module << " "
502-
<< old_symbol.location << '\n'
503-
<< type_to_string_verbose(old_symbol) << '\n';
504-
warning() << "new definition in module " << new_symbol.module << " "
505-
<< new_symbol.location << '\n'
506-
<< type_to_string_verbose(new_symbol) << eom;
504+
messaget log{message_handler};
505+
log.warning().source_location = new_symbol.location;
506+
507+
log.warning() << "warning: " << msg << " \"" << old_symbol.display_name()
508+
<< "\"" << '\n';
509+
log.warning() << "old definition in module " << old_symbol.module << " "
510+
<< old_symbol.location << '\n'
511+
<< type_to_string_verbose(old_symbol) << '\n';
512+
log.warning() << "new definition in module " << new_symbol.module << " "
513+
<< new_symbol.location << '\n'
514+
<< type_to_string_verbose(new_symbol) << messaget::eom;
507515
}
508516

509-
irep_idt linkingt::rename(const irep_idt &id)
517+
irep_idt
518+
linkingt::rename(const symbol_table_baset &src_symbol_table, const irep_idt &id)
510519
{
511520
unsigned cnt=0;
512521

@@ -738,11 +747,6 @@ void linkingt::duplicate_code_symbol(
738747
{
739748
warn_msg="pointer parameter types differ between "
740749
"declaration and definition";
741-
detailed_conflict_report(
742-
old_symbol,
743-
new_symbol,
744-
conflicts.front().first,
745-
conflicts.front().second);
746750
}
747751

748752
replace=new_symbol.value.is_not_nil();
@@ -855,12 +859,12 @@ void linkingt::duplicate_code_symbol(
855859
else if(old_symbol.type == new_symbol.type)
856860
{
857861
// keep the one in old_symbol -- libraries come last!
858-
debug().source_location = new_symbol.location;
859-
860-
debug() << "function '" << old_symbol.name << "' in module '"
861-
<< new_symbol.module
862-
<< "' is shadowed by a definition in module '"
863-
<< old_symbol.module << "'" << eom;
862+
messaget log{message_handler};
863+
log.debug().source_location = new_symbol.location;
864+
log.debug() << "function '" << old_symbol.name << "' in module '"
865+
<< new_symbol.module
866+
<< "' is shadowed by a definition in module '"
867+
<< old_symbol.module << "'" << messaget::eom;
864868
}
865869
else
866870
link_error(
@@ -1146,16 +1150,18 @@ void linkingt::duplicate_object_symbol(
11461150
}
11471151
else
11481152
{
1149-
warning().source_location=new_symbol.location;
1150-
1151-
warning() << "warning: conflicting initializers for"
1152-
<< " variable \"" << old_symbol.name << "\"\n";
1153-
warning() << "using old value in module " << old_symbol.module << " "
1154-
<< old_symbol.value.find_source_location() << '\n'
1155-
<< expr_to_string(old_symbol.name, tmp_old) << '\n';
1156-
warning() << "ignoring new value in module " << new_symbol.module << " "
1157-
<< new_symbol.value.find_source_location() << '\n'
1158-
<< expr_to_string(new_symbol.name, tmp_new) << eom;
1153+
messaget log{message_handler};
1154+
log.warning().source_location = new_symbol.location;
1155+
1156+
log.warning() << "warning: conflicting initializers for"
1157+
<< " variable \"" << old_symbol.name << "\"\n";
1158+
log.warning() << "using old value in module " << old_symbol.module
1159+
<< " " << old_symbol.value.find_source_location() << '\n'
1160+
<< expr_to_string(old_symbol.name, tmp_old) << '\n';
1161+
log.warning() << "ignoring new value in module " << new_symbol.module
1162+
<< " " << new_symbol.value.find_source_location() << '\n'
1163+
<< expr_to_string(new_symbol.name, tmp_new)
1164+
<< messaget::eom;
11591165
}
11601166
}
11611167
}
@@ -1363,13 +1369,16 @@ bool linkingt::needs_renaming_type(
13631369
return true; // different
13641370
}
13651371

1366-
void linkingt::do_type_dependencies(
1367-
std::unordered_set<irep_idt> &needs_to_be_renamed)
1372+
static void do_type_dependencies(
1373+
const symbol_table_baset &src_symbol_table,
1374+
std::unordered_set<irep_idt> &needs_to_be_renamed,
1375+
message_handlert &message_handler)
13681376
{
13691377
// Any type that uses a symbol that will be renamed also
13701378
// needs to be renamed, and so on, until saturation.
13711379

1372-
used_byt used_by;
1380+
// X -> Y iff Y uses X for new symbol type IDs X and Y
1381+
std::unordered_map<irep_idt, std::unordered_set<irep_idt>> used_by;
13731382

13741383
for(const auto &symbol_pair : src_symbol_table.symbols)
13751384
{
@@ -1401,14 +1410,16 @@ void linkingt::do_type_dependencies(
14011410
{
14021411
queue.push_back(dep);
14031412
#ifdef DEBUG
1404-
debug() << "LINKING: needs to be renamed (dependency): "
1405-
<< dep << eom;
1406-
#endif
1413+
messaget log{message_handler};
1414+
log.debug() << "LINKING: needs to be renamed (dependency): " << dep
1415+
<< messaget::eom;
1416+
#endif
14071417
}
14081418
}
14091419
}
14101420

14111421
std::unordered_map<irep_idt, irep_idt> linkingt::rename_symbols(
1422+
const symbol_table_baset &src_symbol_table,
14121423
const std::unordered_set<irep_idt> &needs_to_be_renamed)
14131424
{
14141425
std::unordered_map<irep_idt, irep_idt> new_identifiers;
@@ -1423,13 +1434,14 @@ std::unordered_map<irep_idt, irep_idt> linkingt::rename_symbols(
14231434
if(new_symbol.is_type)
14241435
new_identifier=type_to_name(src_ns, id, new_symbol.type);
14251436
else
1426-
new_identifier=rename(id);
1437+
new_identifier = rename(src_symbol_table, id);
14271438

14281439
new_identifiers.emplace(id, new_identifier);
14291440

14301441
#ifdef DEBUG
1431-
debug() << "LINKING: renaming " << id << " to "
1432-
<< new_identifier << eom;
1442+
messaget log{message_handler};
1443+
log.debug() << "LINKING: renaming " << id << " to " << new_identifier
1444+
<< messaget::eom;
14331445
#endif
14341446

14351447
if(new_symbol.is_type)
@@ -1442,6 +1454,7 @@ std::unordered_map<irep_idt, irep_idt> linkingt::rename_symbols(
14421454
}
14431455

14441456
void linkingt::copy_symbols(
1457+
const symbol_table_baset &src_symbol_table,
14451458
const std::unordered_map<irep_idt, irep_idt> &new_identifiers)
14461459
{
14471460
std::map<irep_idt, symbolt> src_symbols;
@@ -1506,8 +1519,11 @@ void linkingt::copy_symbols(
15061519
}
15071520
}
15081521

1509-
void linkingt::typecheck()
1522+
bool linkingt::link(const symbol_table_baset &src_symbol_table)
15101523
{
1524+
const unsigned errors_before =
1525+
message_handler.get_message_count(messaget::M_ERROR);
1526+
15111527
// We do this in three phases. We first figure out which symbols need to
15121528
// be renamed, and then build the renaming, and finally apply this
15131529
// renaming in the second pass over the symbol table.
@@ -1527,28 +1543,31 @@ void linkingt::typecheck()
15271543
{
15281544
needs_to_be_renamed.insert(symbol_pair.first);
15291545
#ifdef DEBUG
1530-
debug() << "LINKING: needs to be renamed: " << symbol_pair.first << eom;
1531-
#endif
1546+
messaget log{message_handler};
1547+
log.debug() << "LINKING: needs to be renamed: " << symbol_pair.first
1548+
<< messaget::eom;
1549+
#endif
15321550
}
15331551
}
15341552

15351553
// renaming types may trigger further renaming
1536-
do_type_dependencies(needs_to_be_renamed);
1554+
do_type_dependencies(src_symbol_table, needs_to_be_renamed, message_handler);
15371555

15381556
// PHASE 2: actually rename them
1539-
auto new_identifiers = rename_symbols(needs_to_be_renamed);
1557+
auto new_identifiers = rename_symbols(src_symbol_table, needs_to_be_renamed);
15401558

15411559
// PHASE 3: copy new symbols to main table
1542-
copy_symbols(new_identifiers);
1560+
copy_symbols(src_symbol_table, new_identifiers);
1561+
1562+
return message_handler.get_message_count(messaget::M_ERROR) != errors_before;
15431563
}
15441564

15451565
bool linking(
15461566
symbol_table_baset &dest_symbol_table,
15471567
const symbol_table_baset &new_symbol_table,
15481568
message_handlert &message_handler)
15491569
{
1550-
linkingt linking(
1551-
dest_symbol_table, new_symbol_table, message_handler);
1570+
linkingt linking(dest_symbol_table, message_handler);
15521571

1553-
return linking.typecheck_main();
1572+
return linking.link(new_symbol_table);
15541573
}

0 commit comments

Comments
 (0)