ompile time dereference of a constant slice was too generous #2821

This commit is contained in:
Christoffer Lerno
2026-01-24 22:42:04 +01:00
parent ce8167a102
commit 9b2fc04959
4 changed files with 33 additions and 10 deletions

View File

@@ -120,7 +120,8 @@
- Generating typeid from function gives incorrect typeid #2816
- Recursive definitions not discovered when initializer is access on other const #2817
- Slice overrun detected late hit codegen assert #2822
- Compile time dereference of a constant slice was too generous #2821
### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
- Add `@in` compile-time macro to check for a value in a variable list of constants. #2662

View File

@@ -8921,8 +8921,18 @@ static inline bool sema_expr_analyse_deref(SemaContext *context, Expr *expr, boo
break;
case CONST_BYTES:
case CONST_STRING:
expr_rewrite_const_int(expr, type_get_indexed_type(inner->type), inner->const_expr.bytes.len ? inner->const_expr.bytes.ptr[0] : 0);
{
if (inner->type->type_kind != TYPE_POINTER) break;
Type *inner_type = type_get_indexed_type(inner->type);
if (!type_kind_is_any_integer(type_flatten(inner_type)->type_kind)) break;
if (!inner->const_expr.bytes.len)
{
RETURN_SEMA_ERROR(inner, "You cannot dereference an empty constant array or slice.");
}
expr_rewrite_const_int(expr, inner_type, inner->const_expr.bytes.ptr[0]);
return true;
}
default:
UNREACHABLE
}

View File

@@ -4,13 +4,11 @@ import std;
const char *VOWS = "aeiou";
const char *CONS = "bcdfghjklmnpqrstvwxyz";
const char *TEST = "";
fn int main (String[] args)
{
char a = *VOWS;
char b = *CONS;
char c = *TEST;
return 0;
}
@@ -18,12 +16,9 @@ fn int main (String[] args)
@.str = private unnamed_addr constant [6 x i8] c"aeiou\00", align 1
@test.VOWS = local_unnamed_addr constant ptr @.str, align 8
@.str.3 = private unnamed_addr constant [22 x i8] c"bcdfghjklmnpqrstvwxyz\00", align 1
@test.CONS = local_unnamed_addr constant ptr @.str.3, align 8
@.str.4 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
@test.TEST = local_unnamed_addr constant ptr @.str.4, align 8
@.str.2 = private unnamed_addr constant [22 x i8] c"bcdfghjklmnpqrstvwxyz\00", align 1
@test.CONS = local_unnamed_addr constant ptr @.str.2, align 8
store i8 97, ptr %a, align 1
store i8 98, ptr %b, align 1
store i8 0, ptr %c, align 1
ret i32 0
ret i32 0

View File

@@ -0,0 +1,17 @@
// #target: macos-x64
module test;
fn int main()
{
char[*] b = *(char[5]*)"";
return 0;
}
/* #expect: test.ll
@.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
define i32 @main() #0 {
entry:
%b = alloca [5 x i8], align 1
call void @llvm.memcpy.p0.p0.i32(ptr align 1 %b, ptr align 1 @.str, i32 5, i1 false)
ret i32 0
}