Fix bug where enums were treated interchangeably with uint16_t.

ANSI C makes no guarantee about the size of an enum, only that it will be the
minimum required integer type that can hold all the given values. Treating
enums as interchangeable with uint16_t data caused undefined behavoiur on
platforms where enums were always at least 32 bits.
This commit is contained in:
Jason Heeris 2020-12-28 21:46:37 +08:00
parent 9053ebe6ee
commit e13c143c99

View file

@ -236,9 +236,11 @@ static void decode_value(struct value* v, Type_ptr type, Value_ptr value, const
break;
case Value_int16:
case Value_uint16:
case Value__enum:
v->intval = v->v.int16;
break;
case Value__enum:
v->intval = v->v._enum;
break;
case Value_int32:
case Value_uint32:
case Value_float32:
@ -750,8 +752,9 @@ static void do_union(struct strings *s, struct node *n, struct field *first_fiel
* only need to emit one switch block as the layout will line up
* in the C union */
union_cases(s, n, first_field, (1 << Type__bool));
union_cases(s, n, first_field, (1 << Type__enum));
union_cases(s, n, first_field, (1 << Type_int8) | (1 << Type_uint8));
union_cases(s, n, first_field, (1 << Type_int16) | (1 << Type_uint16) | (1 << Type__enum));
union_cases(s, n, first_field, (1 << Type_int16) | (1 << Type_uint16));
union_cases(s, n, first_field, (1 << Type_int32) | (1 << Type_uint32) | (1 << Type_float32));
union_cases(s, n, first_field, (1 << Type_int64) | (1 << Type_uint64) | (1 << Type_float64));
union_cases(s, n, first_field, (1 << Type_text));