Skip to content

Commit 1a2918e

Browse files
committed
Maintain source location while replacing symbol expressions
Linking (and also other workflows) use expression replacement. Doing so must not destroy the source location annotated to an expression. This left us with instructions without location.
1 parent 0d29ab6 commit 1a2918e

File tree

5 files changed

+47
-0
lines changed

5 files changed

+47
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
int foo()
2+
{
3+
return 0;
4+
}
5+
6+
int main()
7+
{
8+
int result;
9+
result = foo();
10+
return result;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int foo();
2+
3+
int bar()
4+
{
5+
return foo();
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
other.c
4+
file main.c line 9 function main
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
--
9+
We previously lost the location attached to the call of `foo` in function main.

src/linking/linking.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,19 @@ bool casting_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
100100

101101
const exprt &e = it->second;
102102

103+
source_locationt previous_source_location{s.source_location()};
104+
DATA_INVARIANT_WITH_DIAGNOSTICS(
105+
previous_source_location.is_not_nil(),
106+
"front-ends should construct symbol expressions with source locations",
107+
s.pretty());
103108
if(e.type().id() != ID_array && e.type().id() != ID_code)
104109
{
105110
typet type = s.type();
106111
static_cast<exprt &>(s) = typecast_exprt::conditional_cast(e, type);
107112
}
108113
else
109114
static_cast<exprt &>(s) = e;
115+
s.add_source_location() = std::move(previous_source_location);
110116

111117
return false;
112118
}

src/util/replace_symbol.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ bool replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
5151
s.type() == it->second.type(),
5252
"types to be replaced should match. s.type:\n" + s.type().pretty() +
5353
"\nit->second.type:\n" + it->second.type().pretty());
54+
source_locationt previous_source_location{s.source_location()};
5455
static_cast<exprt &>(s) = it->second;
56+
// back-end generated or internal symbols (like rounding mode) might not have
57+
// a source location
58+
if(s.source_location().is_nil() && previous_source_location.is_not_nil())
59+
s.add_source_location() = std::move(previous_source_location);
5560

5661
return false;
5762
}
@@ -334,7 +339,12 @@ bool unchecked_replace_symbolt::replace_symbol_expr(symbol_exprt &s) const
334339
if(it == expr_map.end())
335340
return true;
336341

342+
source_locationt previous_source_location{s.source_location()};
337343
static_cast<exprt &>(s) = it->second;
344+
// back-end generated or internal symbols (like rounding mode) might not have
345+
// a source location
346+
if(s.source_location().is_nil() && previous_source_location.is_not_nil())
347+
s.add_source_location() = std::move(previous_source_location);
338348

339349
return false;
340350
}
@@ -415,7 +425,12 @@ bool address_of_aware_replace_symbolt::replace_symbol_expr(
415425

416426
// Note s_copy is no longer a symbol_exprt due to the replace operation,
417427
// and after this line `s` won't be either
428+
source_locationt previous_source_location{s.source_location()};
418429
s = s_copy;
430+
// back-end generated or internal symbols (like rounding mode) might not have
431+
// a source location
432+
if(s.source_location().is_nil() && previous_source_location.is_not_nil())
433+
s.add_source_location() = std::move(previous_source_location);
419434

420435
return false;
421436
}

0 commit comments

Comments
 (0)