From 492f83f5e235793a8beaa76aee76a68252b030c3 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 28 Jun 2024 16:43:57 +0200 Subject: [PATCH] Bit negating const zero flags would give an incorrect result. #1213 --- releasenotes.md | 1 + src/compiler/sema_initializers.c | 3 ++- test/unit/regression/bitstruct_ops3.c3 | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/releasenotes.md b/releasenotes.md index f9581414e..301b0168d 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -23,6 +23,7 @@ - Bit negate does implicit integer promotion. - Bitstructs, unions and flexible arrays now correctly emitted in headers. - Fix distinct inline conversions. +- Bit negating const zero flags would give an incorrect result. ### Stdlib changes - Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions. diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index 97a475405..572573989 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -568,6 +568,7 @@ void sema_invert_bitstruct_const_initializer(ConstInitializer *initializer) if (init->kind == CONST_INIT_ZERO) { init->init_value = expr_new_const_bool(INVALID_SPAN, init->type, true); + init->kind = CONST_INIT_VALUE; continue; } init->init_value->const_expr.b = !init->init_value->const_expr.b; @@ -922,11 +923,11 @@ static inline void sema_update_const_initializer_with_designator_array(ConstInit ConstInitializer **array_elements = const_init->init_array.elements; unsigned array_count = vec_size(array_elements); - MemberIndex insert_index = 0; for (MemberIndex index = low_index; index <= high_index; index++) { + assert(insert_index >= array_count || array_elements); // Walk to the insert point or until we reached the end of the array. while (insert_index < array_count && array_elements[insert_index]->init_array_value.index < index) { diff --git a/test/unit/regression/bitstruct_ops3.c3 b/test/unit/regression/bitstruct_ops3.c3 index fe4122b87..f0c2d96e1 100644 --- a/test/unit/regression/bitstruct_ops3.c3 +++ b/test/unit/regression/bitstruct_ops3.c3 @@ -69,4 +69,22 @@ fn void test_inc_array() assert(x.a++ == 10); assert(x.a == 11, "Value was %d", x.a); assert(--x.a == 10); +} + +bitstruct Flags : int +{ + bool flag1; + bool flag2; +} + +fn void negate() +{ + Flags flags; + flags = ~flags; + assert(~0 == (int)flags); + flags = ~Flags {}; + assert(3 == (int)flags); + const Flags FLAGS = {.flag1 }; + flags = ~FLAGS; + assert(2 == (int)flags); } \ No newline at end of file