Skip to content

Commit b8de17a

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 5625173 commit b8de17a

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
@@ -1465,17 +1465,34 @@ void goto_convertt::convert_ifthenelse(
14651465
// convert 'then'-branch
14661466
goto_programt tmp_then;
14671467
convert(code.then_case(), tmp_then, mode);
1468+
source_locationt then_end_location =
1469+
code.then_case().get_statement() == ID_block
1470+
? to_code_block(code.then_case()).end_location()
1471+
: code.then_case().source_location();
14681472

14691473
goto_programt tmp_else;
1474+
source_locationt else_end_location;
14701475

14711476
if(has_else)
1477+
{
14721478
convert(code.else_case(), tmp_else, mode);
1479+
else_end_location = code.else_case().get_statement() == ID_block
1480+
? to_code_block(code.else_case()).end_location()
1481+
: code.else_case().source_location();
1482+
}
14731483

14741484
exprt tmp_guard=code.cond();
14751485
clean_expr(tmp_guard, dest, mode);
14761486

14771487
generate_ifthenelse(
1478-
tmp_guard, tmp_then, tmp_else, source_location, dest, mode);
1488+
tmp_guard,
1489+
source_location,
1490+
tmp_then,
1491+
then_end_location,
1492+
tmp_else,
1493+
else_end_location,
1494+
dest,
1495+
mode);
14791496
}
14801497

14811498
void goto_convertt::collect_operands(
@@ -1507,9 +1524,11 @@ static inline bool is_size_one(const goto_programt &g)
15071524
/// if(guard) true_case; else false_case;
15081525
void goto_convertt::generate_ifthenelse(
15091526
const exprt &guard,
1527+
const source_locationt &source_location,
15101528
goto_programt &true_case,
1529+
const source_locationt &then_end_location,
15111530
goto_programt &false_case,
1512-
const source_locationt &source_location,
1531+
const source_locationt &else_end_location,
15131532
goto_programt &dest,
15141533
const irep_idt &mode)
15151534
{
@@ -1579,13 +1598,17 @@ void goto_convertt::generate_ifthenelse(
15791598

15801599
// Flip around if no 'true' case code.
15811600
if(is_empty(true_case))
1601+
{
15821602
return generate_ifthenelse(
15831603
boolean_negate(guard),
1604+
source_location,
15841605
false_case,
1606+
else_end_location,
15851607
true_case,
1586-
source_location,
1608+
then_end_location,
15871609
dest,
15881610
mode);
1611+
}
15891612

15901613
bool has_else=!is_empty(false_case);
15911614

@@ -1605,14 +1628,13 @@ void goto_convertt::generate_ifthenelse(
16051628

16061629
// do the x label
16071630
goto_programt tmp_x;
1608-
goto_programt::targett x = tmp_x.add(goto_programt::make_incomplete_goto(
1609-
true_exprt(), true_case.instructions.back().source_location()));
1631+
goto_programt::targett x = tmp_x.add(
1632+
goto_programt::make_incomplete_goto(true_exprt(), then_end_location));
16101633

16111634
// do the z label
16121635
goto_programt tmp_z;
1613-
goto_programt::targett z = tmp_z.add(goto_programt::make_skip());
1614-
// We deliberately don't set a location for 'z', it's a dummy
1615-
// target.
1636+
goto_programt::targett z = tmp_z.add(
1637+
goto_programt::make_skip(has_else ? else_end_location : then_end_location));
16161638

16171639
// y: Q;
16181640
goto_programt tmp_y;

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

+2
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,9 @@ class goto_convertt:public messaget
572572
// if(cond) { true_case } else { false_case }
573573
void generate_ifthenelse(
574574
const exprt &cond,
575+
const source_locationt &,
575576
goto_programt &true_case,
577+
const source_locationt &,
576578
goto_programt &false_case,
577579
const source_locationt &,
578580
goto_programt &dest,

0 commit comments

Comments
 (0)