mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Const slice lengths were not always detected as constant.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
- Non-const macros may not return untyped lists.
|
||||
- `$for` ct-state not properly popped.
|
||||
- Inline `r / complex` for complex numbers fixed.
|
||||
- Const slice lengths were not always detected as constant.
|
||||
|
||||
### Stdlib changes
|
||||
|
||||
|
||||
@@ -2214,7 +2214,7 @@ static void cast_slice_to_bool(Expr *expr, Type *type)
|
||||
}
|
||||
if (expr_is_const_slice(expr))
|
||||
{
|
||||
expr_rewrite_const_bool(expr, type, expr->const_expr.slice_init != NULL);
|
||||
expr_rewrite_const_bool(expr, type, expr->const_expr.slice_init != NULL && expr->const_expr.slice_init->kind != CONST_INIT_ZERO);
|
||||
return;
|
||||
}
|
||||
Expr *inner = expr_copy(expr);
|
||||
|
||||
@@ -12,7 +12,17 @@ ArrayIndex sema_len_from_const(Expr *expr)
|
||||
// We also handle the case where we have a cast from a const array.
|
||||
if (!sema_cast_const(expr))
|
||||
{
|
||||
if (type_flatten(expr->type)->type_kind != TYPE_SLICE) return -1;
|
||||
Type *flat = type_flatten(expr->type);
|
||||
switch (flat->type_kind)
|
||||
{
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_VECTOR:
|
||||
return flat->array.len;
|
||||
case TYPE_SLICE:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (expr->expr_kind == EXPR_SLICE)
|
||||
{
|
||||
return range_const_len(&expr->slice_expr.range);
|
||||
|
||||
@@ -5889,28 +5889,18 @@ CHECK_DEEPER:
|
||||
// 9. Fix hard coded function `len` on slices and arrays
|
||||
if (kw == kw_len)
|
||||
{
|
||||
ArrayIndex index = sema_len_from_const(current_parent);
|
||||
if (index > -1)
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_isz, index);
|
||||
return true;
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_SLICE)
|
||||
{
|
||||
// Handle literal "foo".len which is now a slice.
|
||||
sema_expr_flatten_const_ident(current_parent);
|
||||
if (expr_is_const_string(current_parent))
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_isz, current_parent->const_expr.bytes.len);
|
||||
return true;
|
||||
}
|
||||
expr_rewrite_slice_len(expr, current_parent, type_usz);
|
||||
return true;
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_ARRAY || flat_type->type_kind == TYPE_VECTOR)
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_isz, flat_type->array.len);
|
||||
return true;
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_UNTYPED_LIST)
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_isz, vec_size(current_parent->const_expr.untyped_list));
|
||||
return true;
|
||||
}
|
||||
assert(flat_type->type_kind != TYPE_ARRAY && flat_type->type_kind != TYPE_VECTOR);
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_TYPEID)
|
||||
{
|
||||
|
||||
6
test/test_suite/slices/const_slice_len.c3
Normal file
6
test/test_suite/slices/const_slice_len.c3
Normal file
@@ -0,0 +1,6 @@
|
||||
fn int main()
|
||||
{
|
||||
const char[][] SEQUENCE = { { 1 }};
|
||||
var $i = SEQUENCE.len;
|
||||
return 0;
|
||||
}
|
||||
@@ -15,8 +15,5 @@ fn int main()
|
||||
/* #expect: test.ll
|
||||
|
||||
entry:
|
||||
%literal = alloca %Foo, align 8
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %literal, i8 0, i64 16, i1 false)
|
||||
%ptradd = getelementptr inbounds i8, ptr %literal, i64 8
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user