Skip to content

Commit e16e48e

Browse files
committed
All if-then-else goto conversion instructions have a location
We must not produce goto-program instructions without location, even when they are considered dummy instructions: those instructions may subsequently be used to produce a source location, which was thus missing when converting nested if-then-else statements.
1 parent cfdbbde commit e16e48e

File tree

5 files changed

+74
-9
lines changed

5 files changed

+74
-9
lines changed

Diff for: regression/cbmc-cover/location3/main.c

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
int main()
2+
{
3+
int b, c;
4+
5+
if(b)
6+
{
7+
if(c)
8+
{
9+
c = 1;
10+
}
11+
else
12+
{
13+
c = 2;
14+
}
15+
}
16+
else
17+
{
18+
b = 0;
19+
}
20+
21+
return 1;
22+
}

Diff for: regression/cbmc-cover/location3/test.desc

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
main.c
3+
--cover location
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[main.coverage.\d+\] file main.c line 9 function main block \d+ \(lines main.c:main:9,10\): SATISFIED$
7+
^\[main.coverage.\d+\] file main.c line 15 function main block \d+ \(lines main.c:main:15\): SATISFIED$
8+
^\*\* 7 of 7 covered \(100.0%\)
9+
--
10+
^warning: ignoring
11+
--
12+
All gotos must have a source location annotated.

Diff for: src/goto-programs/goto_clean_expr.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,14 @@ void goto_convertt::clean_expr(
284284

285285
// generate guard for argument side-effects
286286
generate_ifthenelse(
287-
if_expr.cond(), tmp_true, tmp_false, source_location, dest, mode);
287+
if_expr.cond(),
288+
source_location,
289+
tmp_true,
290+
if_expr.true_case().source_location(),
291+
tmp_false,
292+
if_expr.false_case().source_location(),
293+
dest,
294+
mode);
288295

289296
return;
290297
}

Diff for: src/goto-programs/goto_convert.cpp

+30-8
Original file line numberDiff line numberDiff line change
@@ -1613,17 +1613,34 @@ void goto_convertt::convert_ifthenelse(
16131613
// convert 'then'-branch
16141614
goto_programt tmp_then;
16151615
convert(code.then_case(), tmp_then, mode);
1616+
source_locationt then_end_location =
1617+
code.then_case().get_statement() == ID_block
1618+
? to_code_block(code.then_case()).end_location()
1619+
: code.then_case().source_location();
16161620

16171621
goto_programt tmp_else;
1622+
source_locationt else_end_location;
16181623

16191624
if(has_else)
1625+
{
16201626
convert(code.else_case(), tmp_else, mode);
1627+
else_end_location = code.else_case().get_statement() == ID_block
1628+
? to_code_block(code.else_case()).end_location()
1629+
: code.else_case().source_location();
1630+
}
16211631

16221632
exprt tmp_guard=code.cond();
16231633
clean_expr(tmp_guard, dest, mode);
16241634

16251635
generate_ifthenelse(
1626-
tmp_guard, tmp_then, tmp_else, source_location, dest, mode);
1636+
tmp_guard,
1637+
source_location,
1638+
tmp_then,
1639+
then_end_location,
1640+
tmp_else,
1641+
else_end_location,
1642+
dest,
1643+
mode);
16271644
}
16281645

16291646
void goto_convertt::collect_operands(
@@ -1655,9 +1672,11 @@ static inline bool is_size_one(const goto_programt &g)
16551672
/// if(guard) true_case; else false_case;
16561673
void goto_convertt::generate_ifthenelse(
16571674
const exprt &guard,
1675+
const source_locationt &source_location,
16581676
goto_programt &true_case,
1677+
const source_locationt &then_end_location,
16591678
goto_programt &false_case,
1660-
const source_locationt &source_location,
1679+
const source_locationt &else_end_location,
16611680
goto_programt &dest,
16621681
const irep_idt &mode)
16631682
{
@@ -1727,13 +1746,17 @@ void goto_convertt::generate_ifthenelse(
17271746

17281747
// Flip around if no 'true' case code.
17291748
if(is_empty(true_case))
1749+
{
17301750
return generate_ifthenelse(
17311751
boolean_negate(guard),
1752+
source_location,
17321753
false_case,
1754+
else_end_location,
17331755
true_case,
1734-
source_location,
1756+
then_end_location,
17351757
dest,
17361758
mode);
1759+
}
17371760

17381761
bool has_else=!is_empty(false_case);
17391762

@@ -1753,14 +1776,13 @@ void goto_convertt::generate_ifthenelse(
17531776

17541777
// do the x label
17551778
goto_programt tmp_x;
1756-
goto_programt::targett x = tmp_x.add(goto_programt::make_incomplete_goto(
1757-
true_exprt(), true_case.instructions.back().source_location()));
1779+
goto_programt::targett x = tmp_x.add(
1780+
goto_programt::make_incomplete_goto(true_exprt(), then_end_location));
17581781

17591782
// do the z label
17601783
goto_programt tmp_z;
1761-
goto_programt::targett z = tmp_z.add(goto_programt::make_skip());
1762-
// We deliberately don't set a location for 'z', it's a dummy
1763-
// target.
1784+
goto_programt::targett z = tmp_z.add(
1785+
goto_programt::make_skip(has_else ? else_end_location : then_end_location));
17641786

17651787
// y: Q;
17661788
goto_programt tmp_y;

Diff for: src/goto-programs/goto_convert_class.h

+2
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,9 @@ class goto_convertt:public messaget
578578
// if(cond) { true_case } else { false_case }
579579
void generate_ifthenelse(
580580
const exprt &cond,
581+
const source_locationt &,
581582
goto_programt &true_case,
583+
const source_locationt &,
582584
goto_programt &false_case,
583585
const source_locationt &,
584586
goto_programt &dest,

0 commit comments

Comments
 (0)