mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Bitstruct as substruct fails to properly work with designated initializers. #2827
This commit is contained in:
@@ -127,6 +127,7 @@
|
|||||||
- Empty enums would return the values as zero sized arrays #2838
|
- Empty enums would return the values as zero sized arrays #2838
|
||||||
- Store of zero in lowering did not properly handle optionals in some cases #2837
|
- Store of zero in lowering did not properly handle optionals in some cases #2837
|
||||||
- Bitstruct accidentally allowed other arrays than char arrays #2836
|
- Bitstruct accidentally allowed other arrays than char arrays #2836
|
||||||
|
- Bitstruct as substruct fails to properly work with designated initializers. #2827
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
||||||
|
|||||||
@@ -519,13 +519,11 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type *original = flattened->canonical;
|
Type *original = flattened->canonical;
|
||||||
bool is_bitstruct = original->type_kind == TYPE_BITSTRUCT;
|
bool is_structlike = type_is_union_or_strukt(original) || original->type_kind == TYPE_BITSTRUCT;
|
||||||
bool is_structlike = type_is_union_or_strukt(original) || is_bitstruct;
|
|
||||||
ArrayIndex max_index = -1;
|
ArrayIndex max_index = -1;
|
||||||
bool optional = false;
|
bool optional = false;
|
||||||
Type *inner_type = NULL;
|
Type *inner_type = NULL;
|
||||||
bool is_inferred = type_is_inferred(flattened);
|
bool is_inferred = type_is_inferred(flattened);
|
||||||
int bitmember_count_without_value = 0;
|
|
||||||
FOREACH(Expr *, expr, init_expressions)
|
FOREACH(Expr *, expr, init_expressions)
|
||||||
{
|
{
|
||||||
Decl *member;
|
Decl *member;
|
||||||
@@ -535,10 +533,8 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
|||||||
Expr *value = expr->designator_expr.value;
|
Expr *value = expr->designator_expr.value;
|
||||||
if (!value && is_bitmember && member->var.start_bit == member->var.end_bit && type_flatten(result) == type_bool)
|
if (!value && is_bitmember && member->var.start_bit == member->var.end_bit && type_flatten(result) == type_bool)
|
||||||
{
|
{
|
||||||
ASSERT(is_bitstruct);
|
|
||||||
value = expr_new_const_bool(INVALID_SPAN, type_bool, true);
|
value = expr_new_const_bool(INVALID_SPAN, type_bool, true);
|
||||||
expr->designator_expr.value = value;
|
expr->designator_expr.value = value;
|
||||||
bitmember_count_without_value += 1;
|
|
||||||
}
|
}
|
||||||
if (!value) RETURN_SEMA_ERROR(expr, "This initializer needs a value.");
|
if (!value) RETURN_SEMA_ERROR(expr, "This initializer needs a value.");
|
||||||
if (!sema_analyse_expr_rhs(context, result, value, true, no_match_ref, false)) return false;
|
if (!sema_analyse_expr_rhs(context, result, value, true, no_match_ref, false)) return false;
|
||||||
@@ -553,10 +549,6 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
|||||||
inner_type = type_no_optional(value->type);
|
inner_type = type_no_optional(value->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bitmember_count_without_value != 0 && bitmember_count_without_value != vec_size(init_expressions))
|
|
||||||
{
|
|
||||||
RETURN_SEMA_ERROR(initializer, "Mixing the omission of initializers is not permitted.");
|
|
||||||
}
|
|
||||||
Type *type;
|
Type *type;
|
||||||
if (!is_structlike && is_inferred)
|
if (!is_structlike && is_inferred)
|
||||||
{
|
{
|
||||||
|
|||||||
18
test/test_suite/bitstruct/bitstruct_designated_deep.c3t
Normal file
18
test/test_suite/bitstruct/bitstruct_designated_deep.c3t
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
// #target: macos-x64
|
||||||
|
module test;
|
||||||
|
struct Foo4
|
||||||
|
{
|
||||||
|
bitstruct : short
|
||||||
|
{
|
||||||
|
short expand : 1..7;
|
||||||
|
bool b : 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn void main()
|
||||||
|
{
|
||||||
|
Foo4 f4 = { .expand = 2, .b };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #expect: test.ll
|
||||||
|
|
||||||
|
@.__const = private unnamed_addr constant %Foo4 { i16 260 }, align 2
|
||||||
@@ -91,12 +91,10 @@ fn void test4()
|
|||||||
Flags1 flags1 = {.a, .b, .c};
|
Flags1 flags1 = {.a, .b, .c};
|
||||||
flags1 = {.a};
|
flags1 = {.a};
|
||||||
flags1 = {.a = true, .b = true, .c = false};
|
flags1 = {.a = true, .b = true, .c = false};
|
||||||
flags1 = {.a, .b = true, .c = true}; // #error: Mixing the omission
|
|
||||||
Foo foo = { .x = 0, .z }; // #error: needs a value
|
Foo foo = { .x = 0, .z }; // #error: needs a value
|
||||||
|
|
||||||
Flags2 flags2 = {.b, .d};
|
Flags2 flags2 = {.b, .d};
|
||||||
flags2 = {.b, .c, .d}; // #error: needs a value
|
flags2 = {.b, .c, .d}; // #error: needs a value
|
||||||
flags2 = {.a, .c = 1, .d}; // #error: Mixing the omission
|
|
||||||
|
|
||||||
Flags2_Struct flags2s;
|
Flags2_Struct flags2s;
|
||||||
flags2s = {.b, .c, .d}; // #error: needs a value
|
flags2s = {.b, .c, .d}; // #error: needs a value
|
||||||
|
|||||||
Reference in New Issue
Block a user