Skip to content

Commit 965d458

Browse files
committed
Move promotion rule application to C front-end
The front-ends handle type conversion when doing arithmetic over enum types. The case of an enum tag is not expected in goto-program conversion. That, however, was only the case for some operators. Made the C front-end properly handle all assignment operators.
1 parent 60a5920 commit 965d458

File tree

4 files changed

+34
-18
lines changed

4 files changed

+34
-18
lines changed

regression/cbmc/enum8/main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <assert.h>
2+
3+
enum E
4+
{
5+
A = 1,
6+
B = 16
7+
};
8+
9+
int main()
10+
{
11+
enum E e = A;
12+
e <<= 4;
13+
assert(e == B);
14+
e >>= 4;
15+
assert(e == A);
16+
e |= B;
17+
e ^= A;
18+
assert(e == B);
19+
e -= 15;
20+
assert(e == A);
21+
return 0;
22+
}

regression/cbmc/enum8/test.desc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3344,6 +3344,7 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
33443344
else if(statement==ID_assign_shl ||
33453345
statement==ID_assign_shr)
33463346
{
3347+
implicit_typecast_arithmetic(op0);
33473348
implicit_typecast_arithmetic(op1);
33483349

33493350
if(is_number(op1.type()))
@@ -3358,12 +3359,6 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
33583359

33593360
typet underlying_type=op0.type();
33603361

3361-
if(underlying_type.id()==ID_c_enum_tag)
3362-
{
3363-
const auto &c_enum_type = to_c_enum_tag_type(underlying_type);
3364-
underlying_type=c_enum_type.subtype();
3365-
}
3366-
33673362
if(underlying_type.id()==ID_unsignedbv ||
33683363
underlying_type.id()==ID_c_bool)
33693364
{
@@ -3399,7 +3394,7 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
33993394
o_type0.id()==ID_signedbv ||
34003395
o_type0.id()==ID_c_bit_field)
34013396
{
3402-
implicit_typecast(op1, o_type0);
3397+
implicit_typecast_arithmetic(op0, op1);
34033398
return;
34043399
}
34053400
else if(o_type0.id()==ID_vector &&

src/goto-programs/goto_convert_side_effect.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,10 @@ void goto_convertt::remove_assignment(
105105
tmp.op0().make_typecast(expr.op1().type());
106106
rhs=typecast_exprt(is_not_zero(tmp, ns), expr.op0().type());
107107
}
108-
else if(op0_type.id() == ID_c_enum_tag)
109-
{
110-
// We convert c_enums to their underlying type, do the
111-
// operation, and then convert back
112-
const auto &enum_type = ns.follow_tag(to_c_enum_tag_type(op0_type));
113-
auto underlying_type = enum_type.subtype();
114-
auto op0 = typecast_exprt(expr.op0(), underlying_type);
115-
auto op1 = typecast_exprt(expr.op1(), underlying_type);
116-
binary_exprt tmp(op0, new_id, op1, underlying_type);
117-
rhs = typecast_exprt(tmp, expr.op0().type());
118-
}
119108
else
120109
{
110+
PRECONDITION(
111+
op0_type.id() != ID_c_enum_tag && op0_type.id() != ID_c_enum);
121112
rhs.id(new_id);
122113
rhs.copy_to_operands(expr.op0(), expr.op1());
123114
rhs.type()=expr.op0().type();

0 commit comments

Comments
 (0)