mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow (Foo)0 bitstruct casts even if type sizes do not match.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
- ABI change for vectors: store and pass them as arrays #2542.
|
||||
- Add @simd and @align attributes to typedef #2543.
|
||||
- Rename `@extern` to `@cname`, deprecating the old name #2493.
|
||||
- Allow `(Foo)0` bitstruct casts even if type sizes do not match.
|
||||
|
||||
### Fixes
|
||||
- Bug in `io::write_using_write_byte`.
|
||||
|
||||
@@ -1523,7 +1523,24 @@ static bool rule_int_to_bits(CastContext *cc, bool is_explicit, bool is_silent)
|
||||
{
|
||||
Type *base_type = cc->to->decl->strukt.container_type->type;
|
||||
Type *from_type = cc->from;
|
||||
bool success = type_is_integer(base_type) && type_size(from_type) == type_size(base_type);
|
||||
Expr *expr = cc->expr;
|
||||
bool success = false;
|
||||
do
|
||||
{
|
||||
if (!type_is_integer(base_type)) break;
|
||||
if (type_size(base_type) == type_size(from_type))
|
||||
{
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
if (!sema_cast_const(expr) || !expr_is_const_int(expr)) break;
|
||||
if (!int_fits(cc->expr->const_expr.ixx, base_type->canonical->type_kind))
|
||||
{
|
||||
if (is_silent) return false;
|
||||
RETURN_CAST_ERROR(expr, "The value '%s' does not fit in the container type of the bitstruct %s, which is %s.", int_to_str(cc->expr->const_expr.ixx, 10, false), type_quoted_error_string(cc->to), type_quoted_error_string(base_type));
|
||||
}
|
||||
success = true;
|
||||
} while (0);
|
||||
if (!is_explicit || !success) return sema_cast_error(cc, success, is_silent);
|
||||
return true;
|
||||
}
|
||||
@@ -1857,7 +1874,16 @@ static void cast_expand_to_vec(Expr *expr, Type *type)
|
||||
}
|
||||
|
||||
static void cast_bitstruct_to_int_arr(Expr *expr, Type *type) { expr_rewrite_recast(expr, type); }
|
||||
static void cast_int_arr_to_bitstruct(Expr *expr, Type *type) { expr_rewrite_recast(expr, type); }
|
||||
static void cast_int_arr_to_bitstruct(Expr *expr, Type *type)
|
||||
{
|
||||
if (expr_is_const_int(expr))
|
||||
{
|
||||
Type *widening_type = type_flatten(type)->decl->strukt.container_type->type->canonical;
|
||||
expr->const_expr.ixx.type = widening_type->type_kind;
|
||||
expr->type = widening_type;
|
||||
}
|
||||
expr_rewrite_recast(expr, type);
|
||||
}
|
||||
|
||||
static void cast_bitstruct_to_bool(Expr *expr, Type *type)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
module bug_repro;
|
||||
|
||||
bitstruct Edge_Flags : char {
|
||||
bool left;
|
||||
bool top;
|
||||
bool right;
|
||||
bool bottom;
|
||||
bitstruct Edge_Flags : char
|
||||
{
|
||||
bool left;
|
||||
bool top;
|
||||
bool right;
|
||||
bool bottom;
|
||||
}
|
||||
|
||||
fn int main() {
|
||||
Edge_Flags edges;
|
||||
Edge_Flags a = edges & (Edge_Flags)(1 << 0); // #error: 'int'
|
||||
return 0;
|
||||
fn int main()
|
||||
{
|
||||
Edge_Flags edges;
|
||||
Edge_Flags a = edges & (Edge_Flags)(1 << 8); // #error: The value '256' does not fit in the container type of the bitstruct
|
||||
int x = 0;
|
||||
Edge_Flags ab = edges & (Edge_Flags)x; // #error: 'int'
|
||||
return 0;
|
||||
}
|
||||
27
test/test_suite/bitstruct/bitstruct_cast_literal.c3t
Normal file
27
test/test_suite/bitstruct/bitstruct_cast_literal.c3t
Normal file
@@ -0,0 +1,27 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
bitstruct Foo : char
|
||||
{
|
||||
bool baz;
|
||||
}
|
||||
|
||||
fn int main()
|
||||
{
|
||||
char ch = 0;
|
||||
Foo foo1 = (Foo)ch;
|
||||
Foo foo2 = (Foo)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
entry:
|
||||
%ch = alloca i8, align 1
|
||||
%foo1 = alloca i8, align 1
|
||||
%foo2 = alloca i8, align 1
|
||||
store i8 0, ptr %ch, align 1
|
||||
%0 = load i8, ptr %ch, align 1
|
||||
store i8 %0, ptr %foo1, align 1
|
||||
store i8 0, ptr %foo2, align 1
|
||||
ret i32 0
|
||||
}
|
||||
Reference in New Issue
Block a user