Skip to content

Commit f3da348

Browse files
committed
switch-case conversion: ensure case selection has source location
The expression operand was at times lacking a source location when it had been subject to expression simplification. Fixes the root cause in the C front-end, and makes sure the invariant is maintained during goto conversion.
1 parent 25f4436 commit f3da348

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

jbmc/src/java_bytecode/nondet.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ code_blockt generate_nondet_switch(
123123
this_block.add(switch_case);
124124
this_block.add(code_breakt());
125125
code_switch_caset this_case(
126-
from_integer(case_number, switch_value.type()), this_block);
126+
from_integer(case_number, switch_value.type())
127+
.with_source_location(source_location),
128+
this_block);
127129
switch_block.add(std::move(this_case));
128130
++case_number;
129131
}

src/ansi-c/c_typecheck_expr.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -1044,15 +1044,16 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr)
10441044
new_expr = size_of_opt.value();
10451045
}
10461046

1047+
source_locationt location = expr.source_location();
10471048
new_expr.swap(expr);
1048-
1049+
expr.add_source_location() = location;
10491050
expr.add(ID_C_c_sizeof_type)=type;
10501051

10511052
// The type may contain side-effects.
10521053
if(!clean_code.empty())
10531054
{
10541055
side_effect_exprt side_effect_expr(
1055-
ID_statement_expression, void_type(), expr.source_location());
1056+
ID_statement_expression, void_type(), location);
10561057
auto decl_block=code_blockt::from_list(clean_code);
10571058
decl_block.set_statement(ID_decl_block);
10581059
side_effect_expr.copy_to_operands(decl_block);
@@ -1064,8 +1065,9 @@ void c_typecheck_baset::typecheck_expr_sizeof(exprt &expr)
10641065
// It is not obvious whether the type or 'e' should be evaluated
10651066
// first.
10661067

1067-
binary_exprt comma_expr{
1068-
std::move(side_effect_expr), ID_comma, expr, expr.type()};
1068+
exprt comma_expr =
1069+
binary_exprt{std::move(side_effect_expr), ID_comma, expr, expr.type()}
1070+
.with_source_location(location);
10691071
expr.swap(comma_expr);
10701072
}
10711073
}
@@ -4656,6 +4658,8 @@ class is_compile_time_constantt
46564658

46574659
void c_typecheck_baset::make_constant(exprt &expr)
46584660
{
4661+
source_locationt location = expr.find_source_location();
4662+
46594663
// Floating-point expressions may require a rounding mode.
46604664
// ISO 9899:1999 F.7.2 says that the default is "round to nearest".
46614665
// Some compilers have command-line options to override.
@@ -4664,10 +4668,11 @@ void c_typecheck_baset::make_constant(exprt &expr)
46644668
adjust_float_expressions(expr, rounding_mode);
46654669

46664670
simplify(expr, *this);
4671+
expr.add_source_location() = location;
46674672

46684673
if(!is_compile_time_constantt(*this)(expr))
46694674
{
4670-
error().source_location=expr.find_source_location();
4675+
error().source_location = location;
46714676
error() << "expected constant expression, but got '" << to_string(expr)
46724677
<< "'" << eom;
46734678
throw 0;
@@ -4676,13 +4681,15 @@ void c_typecheck_baset::make_constant(exprt &expr)
46764681

46774682
void c_typecheck_baset::make_constant_index(exprt &expr)
46784683
{
4684+
source_locationt location = expr.find_source_location();
46794685
make_constant(expr);
46804686
make_index_type(expr);
46814687
simplify(expr, *this);
4688+
expr.add_source_location() = location;
46824689

46834690
if(!is_compile_time_constantt(*this)(expr))
46844691
{
4685-
error().source_location=expr.find_source_location();
4692+
error().source_location = location;
46864693
error() << "conversion to integer constant failed" << eom;
46874694
throw 0;
46884695
}

src/goto-programs/goto_convert.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,13 @@ void goto_convertt::convert_switch_case(
526526

527527
exprt::operandst &case_op_dest=cases_entry->second->second;
528528
case_op_dest.push_back(code.case_op());
529+
// make sure we have a source location in the case operand as otherwise we
530+
// end up with a GOTO instruction without a source location
531+
DATA_INVARIANT_WITH_DIAGNOSTICS(
532+
case_op_dest.back().source_location().is_not_nil(),
533+
"case operand should have a source location",
534+
case_op_dest.back().pretty(),
535+
code.pretty());
529536
}
530537
}
531538

0 commit comments

Comments
 (0)