From e13c143c993b2efb63a06f80cb178877e9d9a7db Mon Sep 17 00:00:00 2001 From: Jason Heeris Date: Mon, 28 Dec 2020 21:46:37 +0800 Subject: [PATCH] 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. --- compiler/capnpc-c.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/capnpc-c.c b/compiler/capnpc-c.c index 8499e0d..3505a0f 100644 --- a/compiler/capnpc-c.c +++ b/compiler/capnpc-c.c @@ -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));