Skip to content

Commit b72af07

Browse files
authored
Merge pull request #5724 from tautschnig/switch-range
GCC switch range: don't enumerate elements
2 parents ca126dc + 192ebd7 commit b72af07

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

regression/cbmc/gcc_switch_case_range1/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <limits.h>
2+
13
int main()
24
{
35
int x;
@@ -18,9 +20,12 @@ int main()
1820
#endif
1921
__CPROVER_assert(0, "... works");
2022
break;
21-
case 13:
23+
case 14:
2224
__CPROVER_assert(0, "13 works");
2325
break;
26+
case 15 ... INT_MAX:
27+
__CPROVER_assert(0, "large range works");
28+
break;
2429
default:
2530
__CPROVER_assert(0, "default works");
2631
break;

regression/cbmc/gcc_switch_case_range1/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ main.c
44
^EXIT=10$
55
^SIGNAL=0$
66
^VERIFICATION FAILED$
7-
^\*\* 4 of 4 failed
7+
^\*\* 5 of 5 failed
88
--
99
^warning: ignoring

src/goto-programs/goto_convert.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,10 @@ void goto_convertt::convert_gcc_switch_case_range(
416416
targets.cases_map.insert({target, --targets.cases.end()}).first;
417417
}
418418

419-
exprt::operandst &case_op_dest = cases_entry->second->second;
420-
421-
for(mp_integer i = *lb; i <= *ub; ++i)
422-
case_op_dest.push_back(from_integer(i, code.lower().type()));
419+
// create a skeleton for case_guard
420+
cases_entry->second->second.push_back(
421+
and_exprt{binary_relation_exprt{code.lower(), ID_le, nil_exprt{}},
422+
binary_relation_exprt{nil_exprt{}, ID_le, code.upper()}});
423423
}
424424

425425
/// converts 'code' and appends the result to 'dest'
@@ -1100,18 +1100,27 @@ exprt goto_convertt::case_guard(
11001100
{
11011101
PRECONDITION(!case_op.empty());
11021102

1103-
if(case_op.size() == 1)
1104-
return equal_exprt(value, case_op.at(0));
1105-
else
1106-
{
1107-
exprt::operandst disjuncts;
1108-
disjuncts.reserve(case_op.size());
1103+
exprt::operandst disjuncts;
1104+
disjuncts.reserve(case_op.size());
11091105

1110-
for(const auto &op : case_op)
1106+
for(const auto &op : case_op)
1107+
{
1108+
// could be a skeleton generated by convert_gcc_switch_case_range
1109+
if(op.id() == ID_and)
1110+
{
1111+
const binary_exprt &and_expr = to_binary_expr(op);
1112+
PRECONDITION(to_binary_expr(and_expr.op0()).op1().is_nil());
1113+
PRECONDITION(to_binary_expr(and_expr.op1()).op0().is_nil());
1114+
binary_exprt skeleton = and_expr;
1115+
to_binary_expr(skeleton.op0()).op1() = value;
1116+
to_binary_expr(skeleton.op1()).op0() = value;
1117+
disjuncts.push_back(skeleton);
1118+
}
1119+
else
11111120
disjuncts.push_back(equal_exprt(value, op));
1112-
1113-
return disjunction(disjuncts);
11141121
}
1122+
1123+
return disjunction(disjuncts);
11151124
}
11161125

11171126
void goto_convertt::convert_switch(

0 commit comments

Comments
 (0)