Skip to content

Commit 9c13e9b

Browse files
committed
breaking changes to std.mem.Allocator interface API
Before, allocator implementations had to provide `allocFn`, `reallocFn`, and `freeFn`. Now, they must provide only `reallocFn` and `shrinkFn`. Reallocating from a zero length slice is allocation, and shrinking to a zero length slice is freeing. When the new memory size is less than or equal to the previous allocation size, `reallocFn` now has the option to return `error.OutOfMemory` to indicate that the allocator would not be able to take advantage of the new size. For more details see #1306. This commit closes #1306. This commit paves the way to solving #2009. This commit also introduces a memory leak to all coroutines. There is an issue where a coroutine calls the function and it frees its own stack frame, but then the return value of `shrinkFn` is a slice, which is implemented as an sret struct. Writing to the return pointer causes invalid memory write. We could work around it by having a global helper function which has a void return type and calling that instead. But instead this hack will suffice until I rework coroutines to be non-allocating. Basically coroutines are not supported right now until they are reworked as in #1194.
1 parent 4090fe8 commit 9c13e9b

19 files changed

+374
-253
lines changed

src-self-hosted/ir.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ pub const Builder = struct {
13641364

13651365
if (str_token[0] == 'c') {
13661366
// first we add a null
1367-
buf = try irb.comp.gpa().realloc(u8, buf, buf.len + 1);
1367+
buf = try irb.comp.gpa().realloc(buf, buf.len + 1);
13681368
buf[buf.len - 1] = 0;
13691369

13701370
// next make an array value

src/all_types.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,7 +3356,7 @@ struct IrInstructionCoroPromise {
33563356
struct IrInstructionCoroAllocHelper {
33573357
IrInstruction base;
33583358

3359-
IrInstruction *alloc_fn;
3359+
IrInstruction *realloc_fn;
33603360
IrInstruction *coro_size;
33613361
};
33623362

@@ -3481,8 +3481,8 @@ static const size_t stack_trace_ptr_count = 32;
34813481
#define RETURN_ADDRESSES_FIELD_NAME "return_addresses"
34823482
#define ERR_RET_TRACE_FIELD_NAME "err_ret_trace"
34833483
#define RESULT_FIELD_NAME "result"
3484-
#define ASYNC_ALLOC_FIELD_NAME "allocFn"
3485-
#define ASYNC_FREE_FIELD_NAME "freeFn"
3484+
#define ASYNC_REALLOC_FIELD_NAME "reallocFn"
3485+
#define ASYNC_SHRINK_FIELD_NAME "shrinkFn"
34863486
#define ATOMIC_STATE_FIELD_NAME "atomic_state"
34873487
// these point to data belonging to the awaiter
34883488
#define ERR_RET_TRACE_PTR_FIELD_NAME "err_ret_trace_ptr"

src/analyze.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3707,9 +3707,11 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
37073707

37083708
ZigVar *existing_var = find_variable(g, parent_scope, name, nullptr);
37093709
if (existing_var && !existing_var->shadowable) {
3710-
ErrorMsg *msg = add_node_error(g, source_node,
3711-
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3712-
add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3710+
if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
3711+
ErrorMsg *msg = add_node_error(g, source_node,
3712+
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3713+
add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3714+
}
37133715
variable_entry->var_type = g->builtin_types.entry_invalid;
37143716
} else {
37153717
ZigType *type;

src/codegen.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5177,7 +5177,7 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
51775177
LLVMValueRef sret_ptr = LLVMBuildAlloca(g->builder, LLVMGetElementType(alloc_fn_arg_types[0]), "");
51785178

51795179
size_t next_arg = 0;
5180-
LLVMValueRef alloc_fn_val = LLVMGetParam(fn_val, next_arg);
5180+
LLVMValueRef realloc_fn_val = LLVMGetParam(fn_val, next_arg);
51815181
next_arg += 1;
51825182

51835183
LLVMValueRef stack_trace_val;
@@ -5195,15 +5195,22 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
51955195
LLVMValueRef alignment_val = LLVMConstInt(g->builtin_types.entry_u29->type_ref,
51965196
get_coro_frame_align_bytes(g), false);
51975197

5198+
ConstExprValue *zero_array = create_const_str_lit(g, buf_create_from_str(""));
5199+
ConstExprValue *undef_slice_zero = create_const_slice(g, zero_array, 0, 0, false);
5200+
render_const_val(g, undef_slice_zero, "");
5201+
render_const_val_global(g, undef_slice_zero, "");
5202+
51985203
ZigList<LLVMValueRef> args = {};
51995204
args.append(sret_ptr);
52005205
if (g->have_err_ret_tracing) {
52015206
args.append(stack_trace_val);
52025207
}
52035208
args.append(allocator_val);
5209+
args.append(undef_slice_zero->global_refs->llvm_global);
5210+
args.append(LLVMGetUndef(g->builtin_types.entry_u29->type_ref));
52045211
args.append(coro_size);
52055212
args.append(alignment_val);
5206-
LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, alloc_fn_val, args.items, args.length,
5213+
LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, realloc_fn_val, args.items, args.length,
52075214
get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
52085215
set_call_instr_sret(g, call_instruction);
52095216
LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, sret_ptr, err_union_err_index, "");
@@ -5239,14 +5246,14 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
52395246
static LLVMValueRef ir_render_coro_alloc_helper(CodeGen *g, IrExecutable *executable,
52405247
IrInstructionCoroAllocHelper *instruction)
52415248
{
5242-
LLVMValueRef alloc_fn = ir_llvm_value(g, instruction->alloc_fn);
5249+
LLVMValueRef realloc_fn = ir_llvm_value(g, instruction->realloc_fn);
52435250
LLVMValueRef coro_size = ir_llvm_value(g, instruction->coro_size);
5244-
LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(alloc_fn), instruction->alloc_fn->value.type);
5251+
LLVMValueRef fn_val = get_coro_alloc_helper_fn_val(g, LLVMTypeOf(realloc_fn), instruction->realloc_fn->value.type);
52455252
size_t err_code_ptr_arg_index = get_async_err_code_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
52465253
size_t allocator_arg_index = get_async_allocator_arg_index(g, &g->cur_fn->type_entry->data.fn.fn_type_id);
52475254

52485255
ZigList<LLVMValueRef> params = {};
5249-
params.append(alloc_fn);
5256+
params.append(realloc_fn);
52505257
uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, g->cur_fn);
52515258
if (err_ret_trace_arg_index != UINT32_MAX) {
52525259
params.append(LLVMGetParam(g->cur_fn_val, err_ret_trace_arg_index));

src/ir.cpp

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2788,13 +2788,13 @@ static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNod
27882788
}
27892789

27902790
static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node,
2791-
IrInstruction *alloc_fn, IrInstruction *coro_size)
2791+
IrInstruction *realloc_fn, IrInstruction *coro_size)
27922792
{
27932793
IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node);
2794-
instruction->alloc_fn = alloc_fn;
2794+
instruction->realloc_fn = realloc_fn;
27952795
instruction->coro_size = coro_size;
27962796

2797-
ir_ref_instruction(alloc_fn, irb->current_basic_block);
2797+
ir_ref_instruction(realloc_fn, irb->current_basic_block);
27982798
ir_ref_instruction(coro_size, irb->current_basic_block);
27992799

28002800
return &instruction->base;
@@ -3319,9 +3319,11 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
33193319
if (!skip_name_check) {
33203320
ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr);
33213321
if (existing_var && !existing_var->shadowable) {
3322-
ErrorMsg *msg = add_node_error(codegen, node,
3323-
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3324-
add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3322+
if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
3323+
ErrorMsg *msg = add_node_error(codegen, node,
3324+
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3325+
add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3326+
}
33253327
variable_entry->var_type = codegen->builtin_types.entry_invalid;
33263328
} else {
33273329
ZigType *type;
@@ -7506,10 +7508,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
75067508
ImplicitAllocatorIdArg);
75077509
irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false);
75087510
ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr);
7509-
Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
7510-
IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, alloc_field_name);
7511-
IrInstruction *alloc_fn = ir_build_load_ptr(irb, coro_scope, node, alloc_fn_ptr);
7512-
IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, alloc_fn, coro_size);
7511+
Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
7512+
IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name);
7513+
IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr);
7514+
IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size);
75137515
IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr);
75147516
IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError");
75157517
IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk");
@@ -7643,11 +7645,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
76437645
merge_incoming_values[1] = await_handle_in_block;
76447646
IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values);
76457647

7646-
Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME);
7648+
Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);
76477649
IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
76487650
ImplicitAllocatorIdLocalVar);
7649-
IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, free_field_name);
7650-
IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
7651+
IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name);
7652+
IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr);
76517653
IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
76527654
IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
76537655
IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
@@ -7659,11 +7661,20 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
76597661
IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
76607662
IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
76617663
IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false);
7662-
size_t arg_count = 2;
7664+
size_t arg_count = 5;
76637665
IrInstruction **args = allocate<IrInstruction *>(arg_count);
76647666
args[0] = implicit_allocator_ptr; // self
76657667
args[1] = mem_slice; // old_mem
7666-
ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);
7668+
args[2] = ir_build_const_usize(irb, scope, node, 8); // old_align
7669+
// TODO: intentional memory leak here. If this is set to 0 then there is an issue where a coroutine
7670+
// calls the function and it frees its own stack frame, but then the return value is a slice, which
7671+
// is implemented as an sret struct. writing to the return pointer causes invalid memory write.
7672+
// We could work around it by having a global helper function which has a void return type
7673+
// and calling that instead. But instead this hack will suffice until I rework coroutines to be
7674+
// non-allocating. Basically coroutines are not supported right now until they are reworked.
7675+
args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
7676+
args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
7677+
ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);
76677678

76687679
IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
76697680
ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
@@ -13574,32 +13585,31 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
1357413585
static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, ZigType *fn_type,
1357513586
IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst)
1357613587
{
13577-
Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
13578-
//Buf *free_field_name = buf_create_from_str("freeFn");
13588+
Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
1357913589
assert(async_allocator_inst->value.type->id == ZigTypeIdPointer);
1358013590
ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
13581-
IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, alloc_field_name, &call_instruction->base,
13591+
IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
1358213592
async_allocator_inst, container_type);
1358313593
if (type_is_invalid(field_ptr_inst->value.type)) {
1358413594
return ira->codegen->invalid_instruction;
1358513595
}
13586-
ZigType *ptr_to_alloc_fn_type = field_ptr_inst->value.type;
13587-
assert(ptr_to_alloc_fn_type->id == ZigTypeIdPointer);
13596+
ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
13597+
assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer);
1358813598

13589-
ZigType *alloc_fn_type = ptr_to_alloc_fn_type->data.pointer.child_type;
13590-
if (alloc_fn_type->id != ZigTypeIdFn) {
13599+
ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
13600+
if (realloc_fn_type->id != ZigTypeIdFn) {
1359113601
ir_add_error(ira, &call_instruction->base,
13592-
buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name)));
13602+
buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name)));
1359313603
return ira->codegen->invalid_instruction;
1359413604
}
1359513605

13596-
ZigType *alloc_fn_return_type = alloc_fn_type->data.fn.fn_type_id.return_type;
13597-
if (alloc_fn_return_type->id != ZigTypeIdErrorUnion) {
13606+
ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type;
13607+
if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) {
1359813608
ir_add_error(ira, fn_ref,
13599-
buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&alloc_fn_return_type->name)));
13609+
buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name)));
1360013610
return ira->codegen->invalid_instruction;
1360113611
}
13602-
ZigType *alloc_fn_error_set_type = alloc_fn_return_type->data.error_union.err_set_type;
13612+
ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type;
1360313613
ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
1360413614
ZigType *promise_type = get_promise_type(ira->codegen, return_type);
1360513615
ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
@@ -22033,16 +22043,16 @@ static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInst
2203322043
}
2203422044

2203522045
static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) {
22036-
IrInstruction *alloc_fn = instruction->alloc_fn->child;
22037-
if (type_is_invalid(alloc_fn->value.type))
22046+
IrInstruction *realloc_fn = instruction->realloc_fn->child;
22047+
if (type_is_invalid(realloc_fn->value.type))
2203822048
return ira->codegen->invalid_instruction;
2203922049

2204022050
IrInstruction *coro_size = instruction->coro_size->child;
2204122051
if (type_is_invalid(coro_size->value.type))
2204222052
return ira->codegen->invalid_instruction;
2204322053

2204422054
IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope,
22045-
instruction->base.source_node, alloc_fn, coro_size);
22055+
instruction->base.source_node, realloc_fn, coro_size);
2204622056
ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false);
2204722057
result->value.type = get_optional_type(ira->codegen, u8_ptr_type);
2204822058
return result;

src/ir_print.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,7 @@ static void ir_print_promise_result_type(IrPrint *irp, IrInstructionPromiseResul
12861286

12871287
static void ir_print_coro_alloc_helper(IrPrint *irp, IrInstructionCoroAllocHelper *instruction) {
12881288
fprintf(irp->f, "@coroAllocHelper(");
1289-
ir_print_other_instruction(irp, instruction->alloc_fn);
1289+
ir_print_other_instruction(irp, instruction->realloc_fn);
12901290
fprintf(irp->f, ",");
12911291
ir_print_other_instruction(irp, instruction->coro_size);
12921292
fprintf(irp->f, ")");

std/array_list.zig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
8080
/// The caller owns the returned memory. ArrayList becomes empty.
8181
pub fn toOwnedSlice(self: *Self) []align(A) T {
8282
const allocator = self.allocator;
83-
const result = allocator.alignedShrink(T, A, self.items, self.len);
83+
const result = allocator.shrink(self.items, self.len);
8484
self.* = init(allocator);
8585
return result;
8686
}
@@ -144,6 +144,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
144144
pub fn shrink(self: *Self, new_len: usize) void {
145145
assert(new_len <= self.len);
146146
self.len = new_len;
147+
self.items = self.allocator.realloc(self.items, new_len) catch |e| switch (e) {
148+
error.OutOfMemory => return, // no problem, capacity is still correct then.
149+
};
147150
}
148151

149152
pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
@@ -153,7 +156,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
153156
better_capacity += better_capacity / 2 + 8;
154157
if (better_capacity >= new_capacity) break;
155158
}
156-
self.items = try self.allocator.alignedRealloc(T, A, self.items, better_capacity);
159+
self.items = try self.allocator.realloc(self.items, better_capacity);
157160
}
158161

159162
pub fn addOne(self: *Self) !*T {

std/buffer.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub const Buffer = struct {
5050
/// is safe to `deinit`.
5151
pub fn toOwnedSlice(self: *Buffer) []u8 {
5252
const allocator = self.list.allocator;
53-
const result = allocator.shrink(u8, self.list.items, self.len());
53+
const result = allocator.shrink(self.list.items, self.len());
5454
self.* = initNull(allocator);
5555
return result;
5656
}

std/c.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub extern "c" fn rmdir(path: [*]const u8) c_int;
5353

5454
pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
5555
pub extern "c" fn malloc(usize) ?*c_void;
56-
pub extern "c" fn realloc(*c_void, usize) ?*c_void;
56+
pub extern "c" fn realloc(?*c_void, usize) ?*c_void;
5757
pub extern "c" fn free(*c_void) void;
5858
pub extern "c" fn posix_memalign(memptr: **c_void, alignment: usize, size: usize) c_int;
5959

std/debug.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
10721072
.n_value = symbols_buf[symbol_index - 1].nlist.n_value + last_len,
10731073
};
10741074

1075-
const symbols = allocator.shrink(MachoSymbol, symbols_buf, symbol_index);
1075+
const symbols = allocator.shrink(symbols_buf, symbol_index);
10761076

10771077
// Even though lld emits symbols in ascending order, this debug code
10781078
// should work for programs linked in any valid way.

0 commit comments

Comments
 (0)