mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
&self not runtime null-checked in macro #1827. Regression in temp allocators.
This commit is contained in:
@@ -203,10 +203,11 @@ fn void*? TempAllocator.resize(&self, void* pointer, usz size, usz alignment) @d
|
||||
}
|
||||
}
|
||||
void* data = self.acquire(size, NO_ZERO, alignment)!;
|
||||
mem::copy(data, pointer, chunk.size, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
usz len_to_copy = chunk.size > size ? size : chunk.size;
|
||||
mem::copy(data, pointer, len_to_copy, mem::DEFAULT_MEM_ALIGNMENT, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
if (is_realloc_of_last)
|
||||
{
|
||||
self.used = ((void*)chunk - &self.data);
|
||||
self.used = (uptr)chunk - (uptr)&self.data;
|
||||
$if env::ADDRESS_SANITIZER:
|
||||
asan::poison_memory_region(chunk, TempAllocatorChunk.sizeof + chunk.size);
|
||||
$endif
|
||||
|
||||
@@ -317,12 +317,13 @@ macro void clear_inline(void* dst, usz $len, usz $dst_align = 0, bool $is_volati
|
||||
Copy memory from src to dst efficiently, assuming the memory ranges do not overlap.
|
||||
|
||||
@param [&out] dst : "The destination to copy to"
|
||||
@param [&in] src : "The source to copy from"
|
||||
@param [in] src : "The source to copy from"
|
||||
@param len : "The number of bytes to copy"
|
||||
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
|
||||
|
||||
@require src != null || len == 0 : "Copying a null with non-zero length is invalid"
|
||||
@require len == 0 || dst + len <= src || src + len <= dst : "Ranges may not overlap"
|
||||
*>
|
||||
macro void copy(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
|
||||
@@ -335,12 +336,13 @@ macro void copy(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_alig
|
||||
will always be inlined and never call memcopy
|
||||
|
||||
@param [&out] dst : "The destination to copy to"
|
||||
@param [&in] src : "The source to copy from"
|
||||
@param [in] src : "The source to copy from"
|
||||
@param $len : "The number of bytes to copy"
|
||||
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
|
||||
|
||||
@require src != null || len == 0 : "Copying a null with non-zero length is invalid"
|
||||
@require $len == 0 || dst + $len <= src || src + $len <= dst : "Ranges may not overlap"
|
||||
*>
|
||||
macro void copy_inline(void* dst, void* src, usz $len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
|
||||
@@ -352,11 +354,13 @@ macro void copy_inline(void* dst, void* src, usz $len, usz $dst_align = 0, usz $
|
||||
Copy memory from src to dst but correctly handle the possibility of overlapping ranges.
|
||||
|
||||
@param [&out] dst : "The destination to copy to"
|
||||
@param [&in] src : "The source to copy from"
|
||||
@param [in] src : "The source to copy from"
|
||||
@param len : "The number of bytes to copy"
|
||||
@param $dst_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $src_align : "the alignment of the destination if different from the default, 0 assumes the default"
|
||||
@param $is_volatile : "True if this copy should be treated as volatile, i.e. it can't be optimized away."
|
||||
|
||||
@require src != null || len == 0 : "Moving a null with non-zero length is invalid"
|
||||
*>
|
||||
macro void move(void* dst, void* src, usz len, usz $dst_align = 0, usz $src_align = 0, bool $is_volatile = false)
|
||||
{
|
||||
|
||||
@@ -433,7 +433,7 @@ fn Allocator create_temp_allocator_on_demand() @private
|
||||
if (!auto_create_temp)
|
||||
{
|
||||
auto_create_temp = true;
|
||||
abort("Use '@pool_init()' to enable the temp allocator on a new thread. A pool is implicitly created only on the main thread.");
|
||||
abort("Use '@pool_init()' to enable the temp allocator on a new thread. A temp allocator is only implicitly created on the main thread.");
|
||||
}
|
||||
return create_temp_allocator(base_allocator(), temp_allocator_size());
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
- Crash resolving a method on `Foo[2]` when `Foo` is distinct #2042.
|
||||
- Bug due to missing cast when doing `$i[$x] = $z`.
|
||||
- Incorrectly allowed getting pointer to a macro #2049.
|
||||
- &self not runtime null-checked in macro #1827.
|
||||
|
||||
### Stdlib changes
|
||||
- `new_*` functions in general moved to version without `new_` prefix.
|
||||
|
||||
@@ -2195,6 +2195,7 @@ Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v);
|
||||
Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value);
|
||||
Expr *expr_new_const_typeid(SourceSpan span, Type *type);
|
||||
Expr *expr_new_const_string(SourceSpan span, const char *string);
|
||||
Expr *expr_new_const_null(SourceSpan span, Type *type);
|
||||
Expr *expr_new_const_initializer(SourceSpan span, Type *type, ConstInitializer *initializer);
|
||||
const char *expr_kind_to_string(ExprKind kind);
|
||||
bool expr_is_simple(Expr *expr, bool to_float);
|
||||
|
||||
@@ -1035,6 +1035,19 @@ Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value)
|
||||
return expr;
|
||||
}
|
||||
|
||||
Expr *expr_new_const_null(SourceSpan span, Type *type)
|
||||
{
|
||||
Expr *expr = expr_calloc();
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->span = span;
|
||||
expr->type = type;
|
||||
ASSERT(type_flatten(type)->type_kind == TYPE_POINTER);
|
||||
expr->const_expr.ptr = 0;
|
||||
expr->const_expr.const_kind = CONST_POINTER;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return expr;
|
||||
}
|
||||
|
||||
Expr *expr_new_const_string(SourceSpan span, const char *string)
|
||||
{
|
||||
Expr *expr = expr_calloc();
|
||||
|
||||
@@ -1821,7 +1821,7 @@ static inline bool sema_call_check_contract_param_match(SemaContext *context, De
|
||||
{
|
||||
if (param->var.not_null && expr_is_const_pointer(expr) && !expr->const_expr.ptr)
|
||||
{
|
||||
RETURN_SEMA_ERROR(expr, "You may not pass null to a '&' parameter.");
|
||||
RETURN_SEMA_ERROR(expr, "You may not pass null to the '&' parameter.");
|
||||
}
|
||||
if (expr->expr_kind == EXPR_UNARY && expr->unary_expr.expr->expr_kind == EXPR_IDENTIFIER)
|
||||
{
|
||||
@@ -2211,15 +2211,37 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
|
||||
BlockExit** block_exit_ref = CALLOCS(BlockExit*);
|
||||
macro_context.block_exit_ref = block_exit_ref;
|
||||
|
||||
FOREACH(Decl *, param, params)
|
||||
AstId assert_first = 0;
|
||||
AstId* next = &assert_first;
|
||||
|
||||
FOREACH_IDX(idx, Decl *, param, params)
|
||||
{
|
||||
// Skip raw vararg
|
||||
if (!param) continue;
|
||||
if (!sema_add_local(¯o_context, param)) goto EXIT_FAIL;
|
||||
if (param->var.init_expr && param->var.not_null)
|
||||
{
|
||||
Expr *expr = expr_variable(param);
|
||||
Expr *binary = expr_new_expr(EXPR_BINARY, expr);
|
||||
binary->binary_expr.left = exprid(expr);
|
||||
binary->binary_expr.right = exprid(expr_new_const_null(expr->span, type_voidptr));
|
||||
binary->binary_expr.operator = BINARYOP_NE;
|
||||
if (!sema_analyse_expr_rhs(context, type_bool, binary, false, NULL, false)) goto EXIT_FAIL;
|
||||
const char *string = struct_var && idx == 0 ? "Called a method on a null value." : "Passed null to a ref ('&') parameter.";
|
||||
if (expr_is_const_bool(binary) && !binary->const_expr.b)
|
||||
{
|
||||
sema_error_at(context, param->var.init_expr->span, string);
|
||||
goto EXIT_FAIL;
|
||||
}
|
||||
|
||||
AstId assert_first = 0;
|
||||
AstId* next = &assert_first;
|
||||
Ast *assert = new_ast(AST_ASSERT_STMT, param->var.init_expr->span);
|
||||
assert->assert_stmt.is_ensure = true;
|
||||
assert->assert_stmt.expr = exprid(binary);
|
||||
Expr *comment_expr = expr_new_const_string(expr->span, string);
|
||||
assert->assert_stmt.message = exprid(comment_expr);
|
||||
ast_append(&next, assert);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_ensures = false;
|
||||
if (!sema_analyse_contracts(¯o_context, docs, &next, call_expr->span, &has_ensures)) goto EXIT_FAIL;
|
||||
|
||||
@@ -69,6 +69,8 @@ entry:
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 8, i1 false)
|
||||
%0 = call i32 @test.Abc.add(ptr %x)
|
||||
store i32 %0, ptr %a, align 4
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%1 = load i32, ptr %x, align 4
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 4
|
||||
%2 = load i32, ptr %ptradd, align 4
|
||||
@@ -76,8 +78,10 @@ entry:
|
||||
store i32 %add, ptr %b, align 4
|
||||
store i32 100, ptr %f, align 4
|
||||
call void @test.Foo.add(ptr %f)
|
||||
%neq1 = icmp ne ptr %f, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%3 = load i32, ptr %f, align 4
|
||||
%add1 = add i32 %3, 1
|
||||
store i32 %add1, ptr %f, align 4
|
||||
%add2 = add i32 %3, 1
|
||||
store i32 %add2, ptr %f, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -131,43 +131,51 @@ entry:
|
||||
%i = alloca i32, align 4
|
||||
%y = alloca i32, align 4
|
||||
%a = alloca i32, align 4
|
||||
%.anon2 = alloca i32, align 4
|
||||
%i6 = alloca i32, align 4
|
||||
%y7 = alloca ptr, align 8
|
||||
%a8 = alloca i32, align 4
|
||||
%.anon13 = alloca i32, align 4
|
||||
%i17 = alloca i32, align 4
|
||||
%y18 = alloca i32, align 4
|
||||
%a19 = alloca i32, align 4
|
||||
%.anon24 = alloca i32, align 4
|
||||
%i28 = alloca i32, align 4
|
||||
%y29 = alloca i32, align 4
|
||||
%a30 = alloca i32, align 4
|
||||
%.anon35 = alloca i32, align 4
|
||||
%i39 = alloca i32, align 4
|
||||
%y40 = alloca i32, align 4
|
||||
%a41 = alloca i32, align 4
|
||||
%.anon47 = alloca [5 x i32], align 16
|
||||
%.anon48 = alloca i64, align 8
|
||||
%i51 = alloca i64, align 8
|
||||
%y52 = alloca i32, align 4
|
||||
%.anon56 = alloca [5 x i32], align 16
|
||||
%.anon57 = alloca i64, align 8
|
||||
%i61 = alloca i64, align 8
|
||||
%y62 = alloca i32, align 4
|
||||
%.anon7 = alloca i32, align 4
|
||||
%i11 = alloca i32, align 4
|
||||
%y12 = alloca ptr, align 8
|
||||
%a13 = alloca i32, align 4
|
||||
%.anon20 = alloca i32, align 4
|
||||
%i24 = alloca i32, align 4
|
||||
%y25 = alloca i32, align 4
|
||||
%a26 = alloca i32, align 4
|
||||
%.anon33 = alloca i32, align 4
|
||||
%i37 = alloca i32, align 4
|
||||
%y38 = alloca i32, align 4
|
||||
%a39 = alloca i32, align 4
|
||||
%.anon46 = alloca i32, align 4
|
||||
%i50 = alloca i32, align 4
|
||||
%y51 = alloca i32, align 4
|
||||
%a52 = alloca i32, align 4
|
||||
%.anon59 = alloca [5 x i32], align 16
|
||||
%.anon60 = alloca i64, align 8
|
||||
%i63 = alloca i64, align 8
|
||||
%y64 = alloca i32, align 4
|
||||
%.anon68 = alloca [5 x i32], align 16
|
||||
%.anon69 = alloca i64, align 8
|
||||
%i73 = alloca i64, align 8
|
||||
%y74 = alloca i32, align 4
|
||||
%sretparam = alloca [5 x i32], align 4
|
||||
%.anon66 = alloca i64, align 8
|
||||
%i70 = alloca i64, align 8
|
||||
%y71 = alloca i32, align 4
|
||||
%y76 = alloca ptr, align 8
|
||||
%.anon78 = alloca i64, align 8
|
||||
%i82 = alloca i64, align 8
|
||||
%y83 = alloca i32, align 4
|
||||
%y90 = alloca ptr, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const.2, i32 12, i1 false)
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%neq1 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 4
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%neq2 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq2)
|
||||
%ptradd3 = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%0 = load i32, ptr %x, align 4
|
||||
%1 = load i32, ptr %ptradd, align 4
|
||||
%2 = load i32, ptr %ptradd1, align 4
|
||||
%2 = load i32, ptr %ptradd3, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.3, i32 %0, i32 %1, i32 %2)
|
||||
%3 = call ptr @foo.call(ptr %x)
|
||||
%neq4 = icmp ne ptr %3, null
|
||||
call void @llvm.assume(i1 %neq4)
|
||||
store i32 0, ptr %.anon, align 4
|
||||
br label %loop.cond
|
||||
|
||||
@@ -181,6 +189,8 @@ loop.body: ; preds = %loop.cond
|
||||
store i32 %5, ptr %i, align 4
|
||||
%6 = load i32, ptr %.anon, align 4
|
||||
store i32 %6, ptr %a, align 4
|
||||
%neq5 = icmp ne ptr %3, null
|
||||
call void @llvm.assume(i1 %neq5)
|
||||
%7 = load i32, ptr %a, align 4
|
||||
%sext = sext i32 %7 to i64
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %3, i64 %sext
|
||||
@@ -195,212 +205,238 @@ loop.body: ; preds = %loop.cond
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
store i32 0, ptr %.anon2, align 4
|
||||
br label %loop.cond3
|
||||
%neq6 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq6)
|
||||
store i32 0, ptr %.anon7, align 4
|
||||
br label %loop.cond8
|
||||
|
||||
loop.cond3: ; preds = %loop.body5, %loop.exit
|
||||
%12 = load i32, ptr %.anon2, align 4
|
||||
%lt4 = icmp slt i32 %12, 3
|
||||
br i1 %lt4, label %loop.body5, label %loop.exit12
|
||||
loop.cond8: ; preds = %loop.body10, %loop.exit
|
||||
%12 = load i32, ptr %.anon7, align 4
|
||||
%lt9 = icmp slt i32 %12, 3
|
||||
br i1 %lt9, label %loop.body10, label %loop.exit18
|
||||
|
||||
loop.body5: ; preds = %loop.cond3
|
||||
%13 = load i32, ptr %.anon2, align 4
|
||||
store i32 %13, ptr %i6, align 4
|
||||
%14 = load i32, ptr %.anon2, align 4
|
||||
store i32 %14, ptr %a8, align 4
|
||||
%15 = load i32, ptr %a8, align 4
|
||||
%sext9 = sext i32 %15 to i64
|
||||
%ptroffset10 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext9
|
||||
store ptr %ptroffset10, ptr %y7, align 8
|
||||
%16 = load ptr, ptr %y7, align 8
|
||||
loop.body10: ; preds = %loop.cond8
|
||||
%13 = load i32, ptr %.anon7, align 4
|
||||
store i32 %13, ptr %i11, align 4
|
||||
%14 = load i32, ptr %.anon7, align 4
|
||||
store i32 %14, ptr %a13, align 4
|
||||
%neq14 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq14)
|
||||
%15 = load i32, ptr %a13, align 4
|
||||
%sext15 = sext i32 %15 to i64
|
||||
%ptroffset16 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext15
|
||||
store ptr %ptroffset16, ptr %y12, align 8
|
||||
%16 = load ptr, ptr %y12, align 8
|
||||
%17 = load i32, ptr %16, align 4
|
||||
%add = add i32 %17, 1
|
||||
store i32 %add, ptr %16, align 4
|
||||
%18 = load ptr, ptr %y7, align 8
|
||||
%19 = load i32, ptr %i6, align 4
|
||||
%18 = load ptr, ptr %y12, align 8
|
||||
%19 = load i32, ptr %i11, align 4
|
||||
%20 = load i32, ptr %18, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.5, i32 %19, i32 %20)
|
||||
%21 = load i32, ptr %.anon2, align 4
|
||||
%addnsw11 = add nsw i32 %21, 1
|
||||
store i32 %addnsw11, ptr %.anon2, align 4
|
||||
br label %loop.cond3
|
||||
%21 = load i32, ptr %.anon7, align 4
|
||||
%addnsw17 = add nsw i32 %21, 1
|
||||
store i32 %addnsw17, ptr %.anon7, align 4
|
||||
br label %loop.cond8
|
||||
|
||||
loop.exit12: ; preds = %loop.cond3
|
||||
store i32 0, ptr %.anon13, align 4
|
||||
br label %loop.cond14
|
||||
loop.exit18: ; preds = %loop.cond8
|
||||
%neq19 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq19)
|
||||
store i32 0, ptr %.anon20, align 4
|
||||
br label %loop.cond21
|
||||
|
||||
loop.cond14: ; preds = %loop.body16, %loop.exit12
|
||||
%22 = load i32, ptr %.anon13, align 4
|
||||
%lt15 = icmp slt i32 %22, 3
|
||||
br i1 %lt15, label %loop.body16, label %loop.exit23
|
||||
loop.cond21: ; preds = %loop.body23, %loop.exit18
|
||||
%22 = load i32, ptr %.anon20, align 4
|
||||
%lt22 = icmp slt i32 %22, 3
|
||||
br i1 %lt22, label %loop.body23, label %loop.exit31
|
||||
|
||||
loop.body16: ; preds = %loop.cond14
|
||||
%23 = load i32, ptr %.anon13, align 4
|
||||
store i32 %23, ptr %i17, align 4
|
||||
%24 = load i32, ptr %.anon13, align 4
|
||||
store i32 %24, ptr %a19, align 4
|
||||
%25 = load i32, ptr %a19, align 4
|
||||
%sext20 = sext i32 %25 to i64
|
||||
%ptroffset21 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext20
|
||||
%26 = load i32, ptr %ptroffset21, align 4
|
||||
store i32 %26, ptr %y18, align 4
|
||||
%27 = load i32, ptr %i17, align 4
|
||||
%28 = load i32, ptr %y18, align 4
|
||||
loop.body23: ; preds = %loop.cond21
|
||||
%23 = load i32, ptr %.anon20, align 4
|
||||
store i32 %23, ptr %i24, align 4
|
||||
%24 = load i32, ptr %.anon20, align 4
|
||||
store i32 %24, ptr %a26, align 4
|
||||
%neq27 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq27)
|
||||
%25 = load i32, ptr %a26, align 4
|
||||
%sext28 = sext i32 %25 to i64
|
||||
%ptroffset29 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext28
|
||||
%26 = load i32, ptr %ptroffset29, align 4
|
||||
store i32 %26, ptr %y25, align 4
|
||||
%27 = load i32, ptr %i24, align 4
|
||||
%28 = load i32, ptr %y25, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.6, i32 %27, i32 %28)
|
||||
%29 = load i32, ptr %.anon13, align 4
|
||||
%addnsw22 = add nsw i32 %29, 1
|
||||
store i32 %addnsw22, ptr %.anon13, align 4
|
||||
br label %loop.cond14
|
||||
%29 = load i32, ptr %.anon20, align 4
|
||||
%addnsw30 = add nsw i32 %29, 1
|
||||
store i32 %addnsw30, ptr %.anon20, align 4
|
||||
br label %loop.cond21
|
||||
|
||||
loop.exit23: ; preds = %loop.cond14
|
||||
store i32 0, ptr %.anon24, align 4
|
||||
br label %loop.cond25
|
||||
loop.exit31: ; preds = %loop.cond21
|
||||
%neq32 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq32)
|
||||
store i32 0, ptr %.anon33, align 4
|
||||
br label %loop.cond34
|
||||
|
||||
loop.cond25: ; preds = %loop.body27, %loop.exit23
|
||||
%30 = load i32, ptr %.anon24, align 4
|
||||
%lt26 = icmp slt i32 %30, 3
|
||||
br i1 %lt26, label %loop.body27, label %loop.exit34
|
||||
loop.cond34: ; preds = %loop.body36, %loop.exit31
|
||||
%30 = load i32, ptr %.anon33, align 4
|
||||
%lt35 = icmp slt i32 %30, 3
|
||||
br i1 %lt35, label %loop.body36, label %loop.exit44
|
||||
|
||||
loop.body27: ; preds = %loop.cond25
|
||||
%31 = load i32, ptr %.anon24, align 4
|
||||
store i32 %31, ptr %i28, align 4
|
||||
%32 = load i32, ptr %.anon24, align 4
|
||||
store i32 %32, ptr %a30, align 4
|
||||
%33 = load i32, ptr %a30, align 4
|
||||
%sext31 = sext i32 %33 to i64
|
||||
%ptroffset32 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext31
|
||||
%34 = load i32, ptr %ptroffset32, align 4
|
||||
store i32 %34, ptr %y29, align 4
|
||||
%35 = load i32, ptr %i28, align 4
|
||||
%36 = load i32, ptr %y29, align 4
|
||||
loop.body36: ; preds = %loop.cond34
|
||||
%31 = load i32, ptr %.anon33, align 4
|
||||
store i32 %31, ptr %i37, align 4
|
||||
%32 = load i32, ptr %.anon33, align 4
|
||||
store i32 %32, ptr %a39, align 4
|
||||
%neq40 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq40)
|
||||
%33 = load i32, ptr %a39, align 4
|
||||
%sext41 = sext i32 %33 to i64
|
||||
%ptroffset42 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext41
|
||||
%34 = load i32, ptr %ptroffset42, align 4
|
||||
store i32 %34, ptr %y38, align 4
|
||||
%35 = load i32, ptr %i37, align 4
|
||||
%36 = load i32, ptr %y38, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.7, i32 %35, i32 %36)
|
||||
%37 = load i32, ptr %.anon24, align 4
|
||||
%addnsw33 = add nsw i32 %37, 1
|
||||
store i32 %addnsw33, ptr %.anon24, align 4
|
||||
br label %loop.cond25
|
||||
%37 = load i32, ptr %.anon33, align 4
|
||||
%addnsw43 = add nsw i32 %37, 1
|
||||
store i32 %addnsw43, ptr %.anon33, align 4
|
||||
br label %loop.cond34
|
||||
|
||||
loop.exit34: ; preds = %loop.cond25
|
||||
store i32 0, ptr %.anon35, align 4
|
||||
br label %loop.cond36
|
||||
loop.exit44: ; preds = %loop.cond34
|
||||
%neq45 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq45)
|
||||
store i32 0, ptr %.anon46, align 4
|
||||
br label %loop.cond47
|
||||
|
||||
loop.cond36: ; preds = %loop.body38, %loop.exit34
|
||||
%38 = load i32, ptr %.anon35, align 4
|
||||
%lt37 = icmp slt i32 %38, 3
|
||||
br i1 %lt37, label %loop.body38, label %loop.exit46
|
||||
loop.cond47: ; preds = %loop.body49, %loop.exit44
|
||||
%38 = load i32, ptr %.anon46, align 4
|
||||
%lt48 = icmp slt i32 %38, 3
|
||||
br i1 %lt48, label %loop.body49, label %loop.exit58
|
||||
|
||||
loop.body38: ; preds = %loop.cond36
|
||||
%39 = load i32, ptr %.anon35, align 4
|
||||
store i32 %39, ptr %i39, align 4
|
||||
%40 = load i32, ptr %.anon35, align 4
|
||||
store i32 %40, ptr %a41, align 4
|
||||
%41 = load i32, ptr %a41, align 4
|
||||
%sext42 = sext i32 %41 to i64
|
||||
%ptroffset43 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext42
|
||||
%42 = load i32, ptr %ptroffset43, align 4
|
||||
store i32 %42, ptr %y40, align 4
|
||||
%43 = load i32, ptr %i39, align 4
|
||||
%44 = load i32, ptr %y40, align 4
|
||||
loop.body49: ; preds = %loop.cond47
|
||||
%39 = load i32, ptr %.anon46, align 4
|
||||
store i32 %39, ptr %i50, align 4
|
||||
%40 = load i32, ptr %.anon46, align 4
|
||||
store i32 %40, ptr %a52, align 4
|
||||
%neq53 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq53)
|
||||
%41 = load i32, ptr %a52, align 4
|
||||
%sext54 = sext i32 %41 to i64
|
||||
%ptroffset55 = getelementptr inbounds [4 x i8], ptr %x, i64 %sext54
|
||||
%42 = load i32, ptr %ptroffset55, align 4
|
||||
store i32 %42, ptr %y51, align 4
|
||||
%43 = load i32, ptr %i50, align 4
|
||||
%44 = load i32, ptr %y51, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.8, i32 %43, i32 %44)
|
||||
%45 = load i32, ptr %i39, align 4
|
||||
%add44 = add i32 %45, 1
|
||||
store i32 %add44, ptr %i39, align 4
|
||||
%46 = load i32, ptr %.anon35, align 4
|
||||
%addnsw45 = add nsw i32 %46, 1
|
||||
store i32 %addnsw45, ptr %.anon35, align 4
|
||||
br label %loop.cond36
|
||||
%45 = load i32, ptr %i50, align 4
|
||||
%add56 = add i32 %45, 1
|
||||
store i32 %add56, ptr %i50, align 4
|
||||
%46 = load i32, ptr %.anon46, align 4
|
||||
%addnsw57 = add nsw i32 %46, 1
|
||||
store i32 %addnsw57, ptr %.anon46, align 4
|
||||
br label %loop.cond47
|
||||
|
||||
loop.exit46: ; preds = %loop.cond36
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon47, ptr align 16 @.__const.9, i32 20, i1 false)
|
||||
store i64 0, ptr %.anon48, align 8
|
||||
br label %loop.cond49
|
||||
loop.exit58: ; preds = %loop.cond47
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %.anon59, ptr align 16 @.__const.9, i32 20, i1 false)
|
||||
store i64 0, ptr %.anon60, align 8
|
||||
br label %loop.cond61
|
||||
|
||||
loop.cond49: ; preds = %loop.body50, %loop.exit46
|
||||
%47 = load i64, ptr %.anon48, align 8
|
||||
loop.cond61: ; preds = %loop.body62, %loop.exit58
|
||||
%47 = load i64, ptr %.anon60, align 8
|
||||
%gt = icmp ugt i64 5, %47
|
||||
br i1 %gt, label %loop.body50, label %loop.exit55
|
||||
br i1 %gt, label %loop.body62, label %loop.exit67
|
||||
|
||||
loop.body50: ; preds = %loop.cond49
|
||||
%48 = load i64, ptr %.anon48, align 8
|
||||
store i64 %48, ptr %i51, align 8
|
||||
%49 = load i64, ptr %.anon48, align 8
|
||||
%ptroffset53 = getelementptr inbounds [4 x i8], ptr %.anon47, i64 %49
|
||||
%50 = load i32, ptr %ptroffset53, align 4
|
||||
store i32 %50, ptr %y52, align 4
|
||||
%51 = load i64, ptr %i51, align 8
|
||||
%52 = load i32, ptr %y52, align 4
|
||||
loop.body62: ; preds = %loop.cond61
|
||||
%48 = load i64, ptr %.anon60, align 8
|
||||
store i64 %48, ptr %i63, align 8
|
||||
%49 = load i64, ptr %.anon60, align 8
|
||||
%ptroffset65 = getelementptr inbounds [4 x i8], ptr %.anon59, i64 %49
|
||||
%50 = load i32, ptr %ptroffset65, align 4
|
||||
store i32 %50, ptr %y64, align 4
|
||||
%51 = load i64, ptr %i63, align 8
|
||||
%52 = load i32, ptr %y64, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.10, i64 %51, i32 %52)
|
||||
%53 = load i64, ptr %i51, align 8
|
||||
%add54 = add i64 %53, 1
|
||||
store i64 %add54, ptr %i51, align 8
|
||||
%54 = load i64, ptr %.anon48, align 8
|
||||
%53 = load i64, ptr %i63, align 8
|
||||
%add66 = add i64 %53, 1
|
||||
store i64 %add66, ptr %i63, align 8
|
||||
%54 = load i64, ptr %.anon60, align 8
|
||||
%addnuw = add nuw i64 %54, 1
|
||||
store i64 %addnuw, ptr %.anon48, align 8
|
||||
br label %loop.cond49
|
||||
store i64 %addnuw, ptr %.anon60, align 8
|
||||
br label %loop.cond61
|
||||
|
||||
loop.exit55: ; preds = %loop.cond49
|
||||
call void @foo.getFields(ptr sret([5 x i32]) align 4 %.anon56)
|
||||
store i64 0, ptr %.anon57, align 8
|
||||
br label %loop.cond58
|
||||
loop.exit67: ; preds = %loop.cond61
|
||||
call void @foo.getFields(ptr sret([5 x i32]) align 4 %.anon68)
|
||||
store i64 0, ptr %.anon69, align 8
|
||||
br label %loop.cond70
|
||||
|
||||
loop.cond58: ; preds = %loop.body60, %loop.exit55
|
||||
%55 = load i64, ptr %.anon57, align 8
|
||||
%gt59 = icmp ugt i64 5, %55
|
||||
br i1 %gt59, label %loop.body60, label %loop.exit65
|
||||
loop.cond70: ; preds = %loop.body72, %loop.exit67
|
||||
%55 = load i64, ptr %.anon69, align 8
|
||||
%gt71 = icmp ugt i64 5, %55
|
||||
br i1 %gt71, label %loop.body72, label %loop.exit77
|
||||
|
||||
loop.body60: ; preds = %loop.cond58
|
||||
%56 = load i64, ptr %.anon57, align 8
|
||||
store i64 %56, ptr %i61, align 8
|
||||
%57 = load i64, ptr %.anon57, align 8
|
||||
%ptroffset63 = getelementptr inbounds [4 x i8], ptr %.anon56, i64 %57
|
||||
%58 = load i32, ptr %ptroffset63, align 4
|
||||
store i32 %58, ptr %y62, align 4
|
||||
%59 = load i64, ptr %i61, align 8
|
||||
%60 = load i32, ptr %y62, align 4
|
||||
loop.body72: ; preds = %loop.cond70
|
||||
%56 = load i64, ptr %.anon69, align 8
|
||||
store i64 %56, ptr %i73, align 8
|
||||
%57 = load i64, ptr %.anon69, align 8
|
||||
%ptroffset75 = getelementptr inbounds [4 x i8], ptr %.anon68, i64 %57
|
||||
%58 = load i32, ptr %ptroffset75, align 4
|
||||
store i32 %58, ptr %y74, align 4
|
||||
%59 = load i64, ptr %i73, align 8
|
||||
%60 = load i32, ptr %y74, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.11, i64 %59, i32 %60)
|
||||
%61 = load i64, ptr %.anon57, align 8
|
||||
%addnuw64 = add nuw i64 %61, 1
|
||||
store i64 %addnuw64, ptr %.anon57, align 8
|
||||
br label %loop.cond58
|
||||
%61 = load i64, ptr %.anon69, align 8
|
||||
%addnuw76 = add nuw i64 %61, 1
|
||||
store i64 %addnuw76, ptr %.anon69, align 8
|
||||
br label %loop.cond70
|
||||
|
||||
loop.exit65: ; preds = %loop.cond58
|
||||
loop.exit77: ; preds = %loop.cond70
|
||||
call void @foo.getFields(ptr sret([5 x i32]) align 4 %sretparam)
|
||||
store i64 0, ptr %.anon66, align 8
|
||||
br label %loop.cond67
|
||||
store i64 0, ptr %.anon78, align 8
|
||||
br label %loop.cond79
|
||||
|
||||
loop.cond67: ; preds = %loop.body69, %loop.exit65
|
||||
%62 = load i64, ptr %.anon66, align 8
|
||||
%gt68 = icmp ugt i64 5, %62
|
||||
br i1 %gt68, label %loop.body69, label %loop.exit74
|
||||
loop.cond79: ; preds = %loop.body81, %loop.exit77
|
||||
%62 = load i64, ptr %.anon78, align 8
|
||||
%gt80 = icmp ugt i64 5, %62
|
||||
br i1 %gt80, label %loop.body81, label %loop.exit86
|
||||
|
||||
loop.body69: ; preds = %loop.cond67
|
||||
%63 = load i64, ptr %.anon66, align 8
|
||||
store i64 %63, ptr %i70, align 8
|
||||
%64 = load i64, ptr %.anon66, align 8
|
||||
%ptroffset72 = getelementptr inbounds [4 x i8], ptr %sretparam, i64 %64
|
||||
%65 = load i32, ptr %ptroffset72, align 4
|
||||
store i32 %65, ptr %y71, align 4
|
||||
%66 = load i64, ptr %i70, align 8
|
||||
%67 = load i32, ptr %y71, align 4
|
||||
loop.body81: ; preds = %loop.cond79
|
||||
%63 = load i64, ptr %.anon78, align 8
|
||||
store i64 %63, ptr %i82, align 8
|
||||
%64 = load i64, ptr %.anon78, align 8
|
||||
%ptroffset84 = getelementptr inbounds [4 x i8], ptr %sretparam, i64 %64
|
||||
%65 = load i32, ptr %ptroffset84, align 4
|
||||
store i32 %65, ptr %y83, align 4
|
||||
%66 = load i64, ptr %i82, align 8
|
||||
%67 = load i32, ptr %y83, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.12, i64 %66, i32 %67)
|
||||
%68 = load i64, ptr %.anon66, align 8
|
||||
%addnuw73 = add nuw i64 %68, 1
|
||||
store i64 %addnuw73, ptr %.anon66, align 8
|
||||
br label %loop.cond67
|
||||
%68 = load i64, ptr %.anon78, align 8
|
||||
%addnuw85 = add nuw i64 %68, 1
|
||||
store i64 %addnuw85, ptr %.anon78, align 8
|
||||
br label %loop.cond79
|
||||
|
||||
loop.exit74: ; preds = %loop.cond67
|
||||
%ptradd75 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
loop.exit86: ; preds = %loop.cond79
|
||||
%neq87 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq87)
|
||||
%neq88 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq88)
|
||||
%ptradd89 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
%69 = load i32, ptr %x, align 4
|
||||
%70 = load i32, ptr %ptradd75, align 4
|
||||
%70 = load i32, ptr %ptradd89, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.13, i32 %69, i32 %70)
|
||||
%ptradd77 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
store ptr %ptradd77, ptr %y76, align 8
|
||||
%71 = load ptr, ptr %y76, align 8
|
||||
%neq91 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq91)
|
||||
%ptradd92 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
store ptr %ptradd92, ptr %y90, align 8
|
||||
%71 = load ptr, ptr %y90, align 8
|
||||
%72 = load i32, ptr %71, align 4
|
||||
%add78 = add i32 %72, 1
|
||||
store i32 %add78, ptr %71, align 4
|
||||
%ptradd79 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
%add93 = add i32 %72, 1
|
||||
store i32 %add93, ptr %71, align 4
|
||||
%neq94 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq94)
|
||||
%neq95 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq95)
|
||||
%ptradd96 = getelementptr inbounds i8, ptr %x, i64 4
|
||||
%73 = load i32, ptr %x, align 4
|
||||
%74 = load i32, ptr %ptradd79, align 4
|
||||
%74 = load i32, ptr %ptradd96, align 4
|
||||
call void (ptr, ...) @printf(ptr @.str.14, i32 %73, i32 %74)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ entry:
|
||||
%0 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%1 = insertvalue %"int[]" %0, i64 3, 1
|
||||
store %"int[]" %1, ptr %x, align 8
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%2 = load i64, ptr %ptradd, align 8
|
||||
store i64 0, ptr %.anon, align 8
|
||||
@@ -58,6 +60,8 @@ loop.cond: ; preds = %entry
|
||||
loop.body: ; preds = %loop.cond
|
||||
%4 = load i64, ptr %.anon, align 8
|
||||
store i64 %4, ptr %index, align 8
|
||||
%neq1 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%5 = load ptr, ptr %x, align 8
|
||||
%6 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %6
|
||||
@@ -65,19 +69,17 @@ loop.body: ; preds = %loop.cond
|
||||
store i32 %7, ptr %f, align 4
|
||||
%8 = load i32, ptr %f, align 4
|
||||
%9 = call i32 (ptr, ...) @printf(ptr @.str, i32 %8)
|
||||
br label %loop.body1
|
||||
br label %loop.body2
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
loop.body2: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs:
|
||||
declare i32 @printf(ptr, ...) #0
|
||||
|
||||
; Function Attrs:
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test.main()
|
||||
|
||||
@@ -51,6 +51,8 @@ entry:
|
||||
%0 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%1 = insertvalue %"int[]" %0, i64 3, 1
|
||||
store %"int[]" %1, ptr %x, align 8
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%2 = load i64, ptr %ptradd, align 8
|
||||
store i64 0, ptr %.anon, align 8
|
||||
@@ -64,6 +66,8 @@ loop.cond: ; preds = %entry
|
||||
loop.body: ; preds = %loop.cond
|
||||
%4 = load i64, ptr %.anon, align 8
|
||||
store i64 %4, ptr %index, align 8
|
||||
%neq1 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%5 = load ptr, ptr %x, align 8
|
||||
%6 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %5, i64 %6
|
||||
@@ -71,12 +75,12 @@ loop.body: ; preds = %loop.cond
|
||||
store i32 %7, ptr %f, align 4
|
||||
%8 = load i32, ptr %f, align 4
|
||||
%9 = call i32 (ptr, ...) @printf(ptr @.str, i32 %8)
|
||||
br label %loop.body1
|
||||
br label %loop.body2
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
loop.body2: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ entry:
|
||||
%0 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%1 = insertvalue %"int[]" %0, i64 3, 1
|
||||
store %"int[]" %1, ptr %x, align 8
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%2 = load i64, ptr %ptradd, align 8
|
||||
store i64 %2, ptr %.anon, align 8
|
||||
@@ -61,6 +63,8 @@ loop.body: ; preds = %loop.cond
|
||||
store i64 %subnuw, ptr %.anon, align 8
|
||||
%5 = load i64, ptr %.anon, align 8
|
||||
store i64 %5, ptr %index, align 8
|
||||
%neq1 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%6 = load ptr, ptr %x, align 8
|
||||
%7 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %6, i64 %7
|
||||
@@ -68,12 +72,12 @@ loop.body: ; preds = %loop.cond
|
||||
store i32 %8, ptr %f, align 4
|
||||
%9 = load i32, ptr %f, align 4
|
||||
%10 = call i32 (ptr, ...) @printf(ptr @.str, i32 %9)
|
||||
br label %loop.body1
|
||||
br label %loop.body2
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
loop.body2: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ entry:
|
||||
%0 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%1 = insertvalue %"int[]" %0, i64 3, 1
|
||||
store %"int[]" %1, ptr %x, align 8
|
||||
%neq = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq)
|
||||
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
|
||||
%2 = load i64, ptr %ptradd, align 8
|
||||
store i64 %2, ptr %.anon, align 8
|
||||
@@ -60,6 +62,8 @@ loop.body: ; preds = %loop.cond
|
||||
store i64 %subnuw, ptr %.anon, align 8
|
||||
%5 = load i64, ptr %.anon, align 8
|
||||
store i64 %5, ptr %index, align 8
|
||||
%neq1 = icmp ne ptr %x, null
|
||||
call void @llvm.assume(i1 %neq1)
|
||||
%6 = load ptr, ptr %x, align 8
|
||||
%7 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %6, i64 %7
|
||||
@@ -67,11 +71,11 @@ loop.body: ; preds = %loop.cond
|
||||
store i32 %8, ptr %f, align 4
|
||||
%9 = load i32, ptr %f, align 4
|
||||
%10 = call i32 (ptr, ...) @printf(ptr @.str, i32 %9)
|
||||
br label %loop.body1
|
||||
br label %loop.body2
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
loop.body2: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
15
test/unit/regression/run_temp_mem.c3
Normal file
15
test/unit/regression/run_temp_mem.c3
Normal file
@@ -0,0 +1,15 @@
|
||||
module temp_mem;
|
||||
|
||||
fn void test_realloc() @test
|
||||
{
|
||||
void* mem = tmalloc(10);
|
||||
for (int i = 1; i < 4096 * 32 * 16 * 2; i <<= 1)
|
||||
{
|
||||
mem = mem::trealloc(mem, i);
|
||||
}
|
||||
for (int i = 4096 * 32 * 16 * 2; i > 2; i >>= 1)
|
||||
{
|
||||
mem = mem::trealloc(mem, i);
|
||||
(void)tmalloc(1235);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user