- Incorrectly try compile time int check on vector #2815

- 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
This commit is contained in:
Christoffer Lerno
2026-01-24 19:38:51 +01:00
parent 397d065a74
commit ce8167a102
11 changed files with 65 additions and 29 deletions

View File

@@ -292,17 +292,17 @@ fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels c
if (bswap(header.be_magic) != 'qoif') return INVALID_DATA~;
// copy header data to desc
desc.width = bswap(header.be_width);
desc.height = bswap(header.be_height);
desc.channels = header.channels;
uint width = desc.width = bswap(header.be_width);
uint height = desc.height = bswap(header.be_height);
QOIChannels desc_channels = desc.channels = header.channels;
desc.colorspace = header.colorspace;
if (desc.channels == AUTO) return INVALID_DATA~; // Channels must be specified in the header
if (desc_channels == AUTO) return INVALID_DATA~; // Channels must be specified in the header
// check width and height
if (desc.width == 0 || desc.height == 0) return INVALID_DATA~;
if (width == 0 || height == 0) return INVALID_DATA~;
// check pixel count
ulong pixels = (ulong)desc.width * (ulong)desc.height;
ulong pixels = (ulong)width * (ulong)height;
if (pixels > PIXELS_MAX) return TOO_MANY_PIXELS~;
uint pos = Header.sizeof; // Current position in data
@@ -313,7 +313,7 @@ fn char[]? decode(Allocator allocator, char[] data, QOIDesc* desc, QOIChannels c
Pixel[64] palette; // Zero-initialized by default
Pixel p = { 0, 0, 0, 255 };
if (channels == AUTO) channels = desc.channels;
if (channels == AUTO) channels = desc_channels;
// allocate memory for image data
usz image_size = (usz)pixels * channels;

View File

@@ -930,9 +930,9 @@ module std::math::bigint @private;
<*
@param [&out] quotient
@param [&inout] quotient
@param [&in] bi2
@param [&out] remainder
@param [&inout] remainder
*>
fn void BigInt.single_byte_divide(&self, BigInt* bi2, BigInt* quotient, BigInt* remainder)
{
@@ -982,9 +982,9 @@ fn void BigInt.single_byte_divide(&self, BigInt* bi2, BigInt* quotient, BigInt*
}
<*
@param [&out] quotient
@param [&inout] quotient
@param [&in] other
@param [&out] remainder
@param [&inout] remainder
*>
fn void BigInt.multi_byte_divide(&self, BigInt* other, BigInt* quotient, BigInt* remainder)
{

View File

@@ -116,7 +116,11 @@
- Constant shifting incorrectly doesn't flatten the underlying vector base #2825
- String not set as attributes resolved breaking has_tagof #2824
- Self referencing forward resolved const enum fails to be properly detected #2823
- Incorrectly try compile time int check on vector #2815
- 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
### 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

@@ -1597,16 +1597,27 @@ void llvm_emit_panic(GenContext *c, const char *message, SourceSpan loc, const c
void llvm_emit_panic_if_true(GenContext *c, BEValue *value, const char *panic_name, SourceSpan loc, const char *fmt, BEValue *value_1,
BEValue *value_2)
{
bool always_panic = false;
if (LLVMIsAConstantInt(value->value))
{
ASSERT_AT(loc, !LLVMConstIntGetZExtValue(value->value) && "Unexpected bounds check failed.");
return;
if (!LLVMConstIntGetZExtValue(value->value))
{
return;
}
sema_warning_at(loc, "The code here was detected to always panic at runtime.");
always_panic = true;
}
LLVMBasicBlockRef panic_block = llvm_basic_block_new(c, "panic");
LLVMBasicBlockRef ok_block = llvm_basic_block_new(c, "checkok");
value->value = llvm_emit_expect_false(c, value);
llvm_emit_cond_br(c, value, panic_block, ok_block);
if (always_panic)
{
llvm_emit_br(c, panic_block);
}
else
{
value->value = llvm_emit_expect_false(c, value);
llvm_emit_cond_br(c, value, panic_block, ok_block);
}
llvm_emit_block(c, panic_block);
vec_add(c->panic_blocks, panic_block);
BEValue *values = NULL;

View File

@@ -129,10 +129,6 @@ void llvm_value_rvalue(GenContext *c, BEValue *value)
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value)
{
if (!c->catch.block)
{
puts("foekf");
}
ASSERT_AT(c->last_emitted_loc, c->catch.block && "unexpected emit");
bool is_constant_opt = llvm_is_const(opt_value);

View File

@@ -6326,7 +6326,7 @@ static inline void sema_expr_flatten_const_ident(Expr *expr)
return;
}
Expr *init_expr = ident->var.init_expr;
if (!init_expr) return;
if (!init_expr || init_expr->resolve_status != RESOLVE_DONE) return;
sema_expr_flatten_const_ident(init_expr);
if (expr_is_const(init_expr))
{
@@ -6364,7 +6364,7 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo
expr->type = type_typeid;
expr->expr_kind = EXPR_CONST;
expr->const_expr.const_kind = CONST_TYPEID;
expr->const_expr.typeid = parent->type;
expr->const_expr.typeid = type_get_func_ptr(parent->type);
expr->resolve_status = RESOLVE_DONE;
return true;
}
@@ -7723,7 +7723,7 @@ static bool sema_binary_arithmetic_promotion(SemaContext *context, Expr *left, E
}
RETURN_SEMA_ERROR(parent, error_message, type_quoted_error_string(left->type), type_quoted_error_string(right->type));
}
if (type_is_signed_any(flat_max))
if (type_is_signed(flat_max))
{
if (!sema_check_untyped_promotion(context, left, true, flat_max, max)) return false;
if (!sema_check_untyped_promotion(context, right, false, flat_max, max)) return false;
@@ -12046,7 +12046,11 @@ static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr, bool mutat
RETURN_SEMA_ERROR(expr, "A macro name must be followed by '('.");
}
// We may have kept FOO.x.y as a reference, fold it now if y is not an aggregate.
if (mutate) sema_expr_flatten_const_ident(expr->access_resolved_expr.parent);
if (mutate)
{
sema_expr_flatten_const_ident(expr->access_resolved_expr.parent);
if (!sema_cast_rvalue(context, expr->access_resolved_expr.parent, mutate)) return false;
}
return true;
case EXPR_TYPEINFO:
switch (expr->type_expr->type->type_kind)

View File

@@ -1066,10 +1066,6 @@ Type *type_get_optional(Type *optional_type)
Type *type_get_slice(Type *arr_type)
{
if (!type_is_valid_for_array(arr_type))
{
puts("ofek");
}
ASSERT(type_is_valid_for_array(arr_type));
return type_generate_slice(arr_type, false);
}

View File

@@ -0,0 +1,7 @@
fn int main()
{
int[] x;
int a;
x[(a = 52)..2] = 5;
return 0;
}

View File

@@ -0,0 +1,7 @@
fn int main()
{
var $foo = main.typeid;
$typefrom($foo) a;
a = &main;
return 0;
}

View File

@@ -0,0 +1,7 @@
struct Abc
{
int a;
int b;
}
const Abc X = { 2, Y };
const Y = X.b; // #error: This looks like the initialization of the variable was circular

View File

@@ -0,0 +1,4 @@
fn int main()
{
ulong x1 = (int[<2>]){ 10, 20 } + ulong.max; // #error: is out of range for
}