|
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>
|
@@ -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 | 456 | targets.cases.push_back(std::make_pair(target, caset()));
|
440 |
| - cases_entry=targets.cases_map.insert(std::make_pair( |
| 457 | + cases_entry = targets.cases_map.insert(std::make_pair( |
441 | 458 | 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