mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- 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:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
7
test/test_suite/arrays/bad_slice.c3t
Normal file
7
test/test_suite/arrays/bad_slice.c3t
Normal file
@@ -0,0 +1,7 @@
|
||||
fn int main()
|
||||
{
|
||||
int[] x;
|
||||
int a;
|
||||
x[(a = 52)..2] = 5;
|
||||
return 0;
|
||||
}
|
||||
7
test/test_suite/compile_time/typeid_from_function.c3
Normal file
7
test/test_suite/compile_time/typeid_from_function.c3
Normal file
@@ -0,0 +1,7 @@
|
||||
fn int main()
|
||||
{
|
||||
var $foo = main.typeid;
|
||||
$typefrom($foo) a;
|
||||
a = &main;
|
||||
return 0;
|
||||
}
|
||||
7
test/test_suite/constants/self_ref_through_access.c3
Normal file
7
test/test_suite/constants/self_ref_through_access.c3
Normal 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
|
||||
@@ -0,0 +1,4 @@
|
||||
fn int main()
|
||||
{
|
||||
ulong x1 = (int[<2>]){ 10, 20 } + ulong.max; // #error: is out of range for
|
||||
}
|
||||
Reference in New Issue
Block a user