|
13 | 13 |
|
14 | 14 | #include <cassert>
|
15 | 15 |
|
| 16 | +#include <util/arith_tools.h> |
16 | 17 | #include <util/cprover_prefix.h>
|
17 | 18 | #include <util/expr_util.h>
|
18 | 19 | #include <util/fresh_symbol.h>
|
19 | 20 | #include <util/prefix.h>
|
| 21 | +#include <util/simplify_expr.h> |
20 | 22 | #include <util/std_expr.h>
|
21 | 23 | #include <util/symbol_table.h>
|
22 |
| -#include <util/simplify_expr.h> |
23 | 24 |
|
24 | 25 | #include <util/c_types.h>
|
25 | 26 |
|
@@ -426,25 +427,41 @@ void goto_convertt::convert_gcc_switch_case_range(
|
426 | 427 | throw 0;
|
427 | 428 | }
|
428 | 429 |
|
| 430 | + const auto lb = numeric_cast<mp_integer>(code.op0()); |
| 431 | + const auto ub = numeric_cast<mp_integer>(code.op1()); |
| 432 | + |
| 433 | + if(!lb.has_value() || !ub.has_value()) |
| 434 | + { |
| 435 | + error().source_location = code.find_source_location(); |
| 436 | + error() << "GCC's switch-case-range statement requires constant bounds" |
| 437 | + << eom; |
| 438 | + throw 0; |
| 439 | + } |
| 440 | + else if(*lb > *ub) |
| 441 | + { |
| 442 | + warning().source_location = code.find_source_location(); |
| 443 | + warning() << "GCC's switch-case-range statement with empty case range" |
| 444 | + << eom; |
| 445 | + } |
| 446 | + |
429 | 447 | goto_programt tmp;
|
430 | 448 | convert(to_code(code.op2()), tmp, mode);
|
431 | 449 |
|
432 |
| - // goto_programt::targett target=tmp.instructions.begin(); |
| 450 | + goto_programt::targett target = tmp.instructions.begin(); |
433 | 451 | dest.destructive_append(tmp);
|
434 | 452 |
|
435 |
| - #if 0 |
436 |
| - cases_mapt::iterator cases_entry=targets.cases_map.find(target); |
437 |
| - if(cases_entry==targets.cases_map.end()) |
| 453 | + cases_mapt::iterator cases_entry = targets.cases_map.find(target); |
| 454 | + if(cases_entry == targets.cases_map.end()) |
438 | 455 | {
|
439 |
| - targets.cases.push_back(std::make_pair(target, caset())); |
440 |
| - cases_entry=targets.cases_map.insert(std::make_pair( |
441 |
| - target, --targets.cases.end())).first; |
| 456 | + targets.cases.push_back({target, caset()}); |
| 457 | + cases_entry = |
| 458 | + targets.cases_map.insert({target, --targets.cases.end()}).first; |
442 | 459 | }
|
443 | 460 |
|
444 |
| - // TODO |
445 |
| - exprt::operandst &case_op_dest=cases_entry->second->second; |
446 |
| - case_op_dest.push_back(code.case_op()); |
447 |
| - #endif |
| 461 | + exprt::operandst &case_op_dest = cases_entry->second->second; |
| 462 | + |
| 463 | + for(mp_integer i = *lb; i <= *ub; ++i) |
| 464 | + case_op_dest.push_back(from_integer(i, code.op0().type())); |
448 | 465 | }
|
449 | 466 |
|
450 | 467 | /// converts 'code' and appends the result to 'dest'
|
|
0 commit comments