Skip to content

Commit 4725365

Browse files
authored
Merge pull request #8168 from tautschnig/cleanup/linking-cleanup
Declutter linking implementation
2 parents 804c708 + 4abd030 commit 4725365

File tree

7 files changed

+670
-610
lines changed

7 files changed

+670
-610
lines changed

src/linking/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
SRC = linking.cpp \
1+
SRC = casting_replace_symbol.cpp \
2+
linking.cpp \
3+
linking_diagnostics.cpp \
24
remove_internal_symbols.cpp \
35
static_lifetime_init.cpp \
46
# Empty last line
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*******************************************************************\
2+
3+
Module: ANSI-C Linking
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// ANSI-C Linking
11+
12+
#include "casting_replace_symbol.h"
13+
14+
#include <util/pointer_expr.h>
15+
#include <util/std_code.h>
16+
#include <util/std_expr.h>
17+
18+
bool casting_replace_symbolt::replace(exprt &dest) const
19+
{
20+
bool result = true; // unchanged
21+
22+
// first look at type
23+
24+
const exprt &const_dest(dest);
25+
if(have_to_replace(const_dest.type()))
26+
if(!replace_symbolt::replace(dest.type()))
27+
result = false;
28+
29+
// now do expression itself
30+
31+
if(!have_to_replace(dest))
32+
return result;
33+
34+
if(dest.id() == ID_side_effect)
35+
{
36+
if(auto call = expr_try_dynamic_cast<side_effect_expr_function_callt>(dest))
37+
{
38+
if(!have_to_replace(call->function()))
39+
return replace_symbolt::replace(dest);
40+
41+
exprt before = dest;
42+
code_typet type = to_code_type(call->function().type());
43+
44+
result &= replace_symbolt::replace(call->function());
45+
46+
// maybe add type casts here?
47+
for(auto &arg : call->arguments())
48+
result &= replace_symbolt::replace(arg);
49+
50+
if(
51+
type.return_type() !=
52+
to_code_type(call->function().type()).return_type())
53+
{
54+
call->type() = to_code_type(call->function().type()).return_type();
55+
dest = typecast_exprt(*call, type.return_type());
56+
result = true;
57+
}
58+
59+
return result;
60+
}
61+
}
62+
else if(dest.id() == ID_address_of)
63+
{
64+
pointer_typet ptr_type = to_pointer_type(dest.type());
65+
66+
result &= replace_symbolt::replace(dest);
67+
68+
address_of_exprt address_of = to_address_of_expr(dest);
69+
if(address_of.object().type() != ptr_type.base_type())
70+
{
71+
to_pointer_type(address_of.type()).base_type() =
72+
address_of.object().type();
73+
dest = typecast_exprt{address_of, std::move(ptr_type)};
74+
result = true;
75+
}
76+
77+
return result;
78+
}
79+
80+
return replace_symbolt::replace(dest);
81+
}
82+
83+
bool casting_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
84+
{
85+
expr_mapt::const_iterator it = expr_map.find(s.get_identifier());
86+
87+
if(it == expr_map.end())
88+
return true;
89+
90+
const exprt &e = it->second;
91+
92+
source_locationt previous_source_location{s.source_location()};
93+
DATA_INVARIANT_WITH_DIAGNOSTICS(
94+
previous_source_location.is_not_nil(),
95+
"front-ends should construct symbol expressions with source locations",
96+
s.pretty());
97+
if(e.type().id() != ID_array && e.type().id() != ID_code)
98+
{
99+
typet type = s.type();
100+
static_cast<exprt &>(s) = typecast_exprt::conditional_cast(e, type);
101+
}
102+
else
103+
static_cast<exprt &>(s) = e;
104+
s.add_source_location() = std::move(previous_source_location);
105+
106+
return false;
107+
}

src/linking/casting_replace_symbol.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************\
2+
3+
Module: ANSI-C Linking
4+
5+
Author: Michael Tautschnig
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// ANSI-C Linking
11+
12+
#ifndef CPROVER_LINKING_CASTING_REPLACE_SYMBOL_H
13+
#define CPROVER_LINKING_CASTING_REPLACE_SYMBOL_H
14+
15+
#include <util/replace_symbol.h>
16+
17+
/// A variant of \ref replace_symbolt that does not require types to match, but
18+
/// instead inserts type casts as needed when replacing one symbol by another.
19+
class casting_replace_symbolt : public replace_symbolt
20+
{
21+
public:
22+
bool replace(exprt &dest) const override;
23+
24+
private:
25+
bool replace_symbol_expr(symbol_exprt &dest) const override;
26+
};
27+
28+
#endif // CPROVER_LINKING_CASTING_REPLACE_SYMBOL_H

0 commit comments

Comments
 (0)