From f39aa1a41e3751ba5a99bda7e9bcd94a6d04aa18 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 9 Nov 2023 11:08:36 +0100 Subject: [PATCH] Add location tracking for memory allocations. --- lib/std/collections/bitset.c3 | 4 +- lib/std/collections/list.c3 | 4 +- lib/std/collections/map.c3 | 8 +- lib/std/collections/object.c3 | 4 +- lib/std/collections/priorityqueue.c3 | 4 +- lib/std/core/dstring.c3 | 46 ++--- lib/std/core/mem.c3 | 66 ++++-- lib/std/core/mem_allocator.c3 | 90 ++++---- lib/std/core/mem_tracked.c3 | 194 ------------------ lib/std/core/string.c3 | 60 +++--- lib/std/io/stream/bytebuffer.c3 | 8 +- src/compiler/sema_expr.c | 12 +- src/compiler/sema_stmts.c | 1 + src/version.h | 2 +- test/test_suite/errors/error_regression_2.c3t | 12 +- test/test_suite/stdlib/map.c3t | 8 +- 16 files changed, 185 insertions(+), 338 deletions(-) delete mode 100644 lib/std/core/mem_tracked.c3 diff --git a/lib/std/collections/bitset.c3 b/lib/std/collections/bitset.c3 index ec0c35c74..554081897 100644 --- a/lib/std/collections/bitset.c3 +++ b/lib/std/collections/bitset.c3 @@ -86,9 +86,9 @@ struct GrowableBitSet * @param initial_capacity * @param [&inout] allocator "The allocator to use, defaults to the heap allocator" **/ -fn GrowableBitSet* GrowableBitSet.init_new(&self, usz initial_capacity = 1, Allocator* allocator = mem::heap()) +fn GrowableBitSet* GrowableBitSet.init_new(&self, usz initial_capacity = 1, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - self.data.init_new(initial_capacity, allocator); + self.data.init_new(initial_capacity, allocator, env); return self; } diff --git a/lib/std/collections/list.c3 b/lib/std/collections/list.c3 index 3dc3bfc31..c7e37cd2a 100644 --- a/lib/std/collections/list.c3 +++ b/lib/std/collections/list.c3 @@ -22,14 +22,14 @@ struct List (Printable) * @param initial_capacity "The initial capacity to reserve" * @param [&inout] allocator "The allocator to use, defaults to the heap allocator" **/ -fn List* List.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap()) +fn List* List.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { self.allocator = allocator; self.size = 0; if (initial_capacity > 0) { initial_capacity = math::next_power_of_2(initial_capacity); - self.entries = allocator.alloc_aligned(Type.sizeof * initial_capacity, .alignment = Type[1].alignof)!!; + self.entries = allocator.alloc_aligned(Type.sizeof * initial_capacity, .alignment = Type[1].alignof, .env = env)!!; } else { diff --git a/lib/std/collections/map.c3 b/lib/std/collections/map.c3 index 53930d7d6..105f511cf 100644 --- a/lib/std/collections/map.c3 +++ b/lib/std/collections/map.c3 @@ -26,13 +26,13 @@ struct HashMap * @require !map.allocator "Map was already initialized" * @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum" **/ -fn HashMap* HashMap.init_new(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::heap()) +fn HashMap* HashMap.init_new(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { capacity = math::next_power_of_2(capacity); map.allocator = allocator; map.load_factor = load_factor; map.threshold = (uint)(capacity * load_factor); - map.table = allocator.new_zero_array(Entry*, capacity); + map.table = allocator.new_zero_array(Entry*, capacity, .env = env); return map; } @@ -62,9 +62,9 @@ fn bool HashMap.is_initialized(&map) * @param [&inout] allocator "The allocator to use" * @param [&in] other_map "The map to copy from." **/ -fn HashMap* HashMap.init_new_from_map(&self, HashMap* other_map, Allocator* allocator = mem::heap()) +fn HashMap* HashMap.init_new_from_map(&self, HashMap* other_map, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - self.init_new(other_map.table.len, other_map.load_factor, allocator); + self.init_new(other_map.table.len, other_map.load_factor, allocator, env); self.put_all_for_create(other_map); return self; } diff --git a/lib/std/collections/object.c3 b/lib/std/collections/object.c3 index abc3d4053..cb3a4c45f 100644 --- a/lib/std/collections/object.c3 +++ b/lib/std/collections/object.c3 @@ -78,9 +78,9 @@ fn usz! Object.to_format(&self, Formatter* formatter) @dynamic } } -fn Object* new_obj(Allocator* allocator) +fn Object* new_obj(Allocator* allocator, TrackingEnv* env = mem::get_tracking_env()) { - Object* o = allocator.new(Object); + Object* o = allocator.new(Object, .env = env); *o = { .allocator = allocator, .type = void.typeid }; return o; } diff --git a/lib/std/collections/priorityqueue.c3 b/lib/std/collections/priorityqueue.c3 index a6410a119..fd125c44d 100644 --- a/lib/std/collections/priorityqueue.c3 +++ b/lib/std/collections/priorityqueue.c3 @@ -36,9 +36,9 @@ struct PrivatePriorityQueue (Printable) Heap heap; } -fn void PrivatePriorityQueue.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap()) @inline +fn void PrivatePriorityQueue.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) @inline { - self.heap.init_new(initial_capacity, allocator); + self.heap.init_new(initial_capacity, allocator, .env = env); } fn void PrivatePriorityQueue.init_temp(&self, usz initial_capacity = 16) @inline diff --git a/lib/std/core/dstring.c3 b/lib/std/core/dstring.c3 index 14e406356..a2db4dd33 100644 --- a/lib/std/core/dstring.c3 +++ b/lib/std/core/dstring.c3 @@ -8,10 +8,10 @@ const usz MIN_CAPACITY @private = 16; /** * @require !self.data() "String already initialized" **/ -fn DString DString.init_new(&self, usz capacity = MIN_CAPACITY, Allocator* allocator = mem::heap()) +fn DString DString.init_new(&self, usz capacity = MIN_CAPACITY, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY; - StringData* data = allocator.new(StringData, .end_padding = capacity); + StringData* data = allocator.new(StringData, .end_padding = capacity, .env = env); data.allocator = allocator; data.len = 0; data.capacity = capacity; @@ -27,17 +27,17 @@ fn DString DString.init_temp(&self, usz capacity = MIN_CAPACITY) return *self; } -fn DString new_with_capacity(usz capacity, Allocator* allocator = mem::heap()) +fn DString new_with_capacity(usz capacity, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - return DString{}.init_new(capacity, allocator); + return DString{}.init_new(capacity, allocator, .env = env); } fn DString temp_with_capacity(usz capacity) => new_with_capacity(capacity, mem::temp()) @inline; -fn DString new(String c = "", Allocator* allocator = mem::heap()) +fn DString new(String c = "", Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len = c.len; - StringData* data = (StringData*)new_with_capacity(len, allocator); + StringData* data = (StringData*)new_with_capacity(len, allocator, env); if (len) { data.len = len; @@ -48,10 +48,10 @@ fn DString new(String c = "", Allocator* allocator = mem::heap()) fn DString temp_new(String s = "") => new(s, mem::temp()) @inline; -fn DString DString.new_concat(self, DString b, Allocator* allocator = mem::heap()) +fn DString DString.new_concat(self, DString b, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { DString string; - string.init_new(self.len() + b.len(), allocator); + string.init_new(self.len() + b.len(), allocator, env); string.append(self); string.append(b); return string; @@ -148,37 +148,37 @@ fn void DString.append_char32(&self, Char32 c) fn DString DString.tcopy(&self) => self.copy(mem::temp()); -fn DString DString.copy(self, Allocator* allocator = null) +fn DString DString.copy(self, Allocator* allocator = null, TrackingEnv* env = mem::get_tracking_env()) { if (!self) { - if (allocator) return new_with_capacity(0, allocator); + if (allocator) return new_with_capacity(0, allocator, env); return (DString)null; } StringData* data = self.data(); if (!allocator) allocator = mem::heap(); - DString new_string = new_with_capacity(data.capacity, allocator); + DString new_string = new_with_capacity(data.capacity, allocator, env); mem::copy((char*)new_string.data(), (char*)data, StringData.sizeof + data.len); return new_string; } -fn ZString DString.copy_zstr(self, Allocator* allocator = mem::heap()) +fn ZString DString.copy_zstr(self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz str_len = self.len(); if (!str_len) { - return (ZString)allocator.calloc(1); + return (ZString)allocator.calloc(1, env); } - char* zstr = allocator.alloc(str_len + 1); + char* zstr = allocator.alloc(str_len + 1, env); StringData* data = self.data(); mem::copy(zstr, &data.chars, str_len); zstr[str_len] = 0; return (ZString)zstr; } -fn String DString.copy_str(self, Allocator* allocator = mem::heap()) +fn String DString.copy_str(self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - return (String)self.copy_zstr(allocator)[:self.len()]; + return (String)self.copy_zstr(allocator, env)[:self.len()]; } fn String DString.tcopy_str(self) => self.copy_str(mem::temp()) @inline; @@ -240,9 +240,9 @@ fn void DString.append_chars(&self, String str) data.len += other_len; } -fn Char32[] DString.copy_utf32(&self, Allocator* allocator = mem::heap()) +fn Char32[] DString.copy_utf32(&self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - return self.str_view().to_new_utf32(allocator) @inline!!; + return self.str_view().to_new_utf32(allocator, env) @inline!!; } fn void DString.append_string(&self, DString str) @@ -354,7 +354,7 @@ fn usz! DString.appendfn(&self, String format, args...) @maydiscard return len + 1; } -fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap()) +fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { if (!s.len) return (DString)null; usz total_size = joiner.len * s.len; @@ -362,7 +362,7 @@ fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap( { total_size += str.len; } - DString res = new_with_capacity(total_size, allocator); + DString res = new_with_capacity(total_size, allocator, env); res.append(s[0]); foreach (String* &str : s[1..]) { @@ -384,12 +384,12 @@ fn StringData* DString.data(self) @inline @private return (StringData*)self; } -fn void DString.reserve(&self, usz addition) +fn void DString.reserve(&self, usz addition, TrackingEnv* env = mem::get_tracking_env()) { StringData* data = self.data(); if (!data) { - *self = dstring::new_with_capacity(addition); + *self = dstring::new_with_capacity(addition, .env = env); return; } usz len = data.len + addition; @@ -398,7 +398,7 @@ fn void DString.reserve(&self, usz addition) if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY; while (new_capacity < len) new_capacity *= 2; data.capacity = new_capacity; - *self = (DString)data.allocator.realloc(data, StringData.sizeof + new_capacity); + *self = (DString)data.allocator.realloc(data, StringData.sizeof + new_capacity, env); } fn usz! DString.read_from_stream(&self, InStream* reader) diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index c5b412224..72f8128fa 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -385,6 +385,20 @@ macro void @scoped(Allocator* allocator; @body()) @body(); } +macro void @report_heap_allocs_in_scope(;@body()) +{ + TrackingAllocator tracker; + tracker.init(thread_allocator); + Allocator* old_allocator = thread_allocator; + thread_allocator = &tracker; + defer + { + thread_allocator = old_allocator; + tracker.print_report(); + tracker.free(); + } + @body(); +} macro void @stack_mem(usz $size; @body(Allocator* mem)) @builtin { @@ -494,11 +508,21 @@ fn void initialize_wasm_mem() @init(1) @private thread_allocator = &wasm_allocator; } -module std::core::mem @if(!env::TRACK_MEMORY); +module std::core::mem; -macro @clone(value) @builtin + +macro TrackingEnv* get_tracking_env() { - return mem::heap().clone(value); + $if env::TRACK_MEMORY: + return &&TrackingEnv { $$FILE, $$FUNC, $$LINE }; + $else + return null; + $endif +} + +macro @clone(value, TrackingEnv* env = mem::get_tracking_env()) @builtin +{ + return mem::heap().clone(value, env); } macro @tclone(value) @builtin @@ -506,24 +530,24 @@ macro @tclone(value) @builtin return mem::temp().clone(value); } -fn void* malloc(usz size) @builtin @inline +fn void* malloc(usz size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline { - return mem::heap().alloc(size); + return mem::heap().alloc(size, env); } -fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline +fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline { - return temp().acquire(size, false, alignment, offset, null)!!; + return temp().acquire(size, false, alignment, offset, env)!!; } -macro new($Type) +macro new($Type, TrackingEnv* env = mem::get_tracking_env()) { - return heap().new($Type); + return heap().new($Type, .env = env); } -macro new_clear($Type) +macro new_clear($Type, TrackingEnv* env = mem::get_tracking_env()) { - return heap().new_clear($Type); + return heap().new_clear($Type, env); } macro new_temp($Type) @@ -536,9 +560,9 @@ macro new_temp_clear($Type) return tcalloc($Type.sizeof); } -macro new_array($Type, usz elements) +macro new_array($Type, usz elements, TrackingEnv* env = mem::get_tracking_env()) { - return heap().new_array($Type, elements); + return heap().new_array($Type, elements, .env = env); } macro temp_array($Type, usz elements) @@ -546,9 +570,9 @@ macro temp_array($Type, usz elements) return (($Type*)tmalloc($Type.sizeof * elements, $Type.alignof))[:elements]; } -macro new_zero_array($Type, usz elements) +macro new_zero_array($Type, usz elements, TrackingEnv* env = mem::get_tracking_env()) { - return heap().new_zero_array($Type, elements); + return heap().new_zero_array($Type, elements, env); } macro temp_zero_array($Type, usz elements) @@ -556,9 +580,9 @@ macro temp_zero_array($Type, usz elements) return (($Type*)tcalloc($Type.sizeof * elements, $Type.alignof))[:elements]; } -fn void* calloc(usz size) @builtin @inline +fn void* calloc(usz size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline { - return heap().calloc(size); + return heap().calloc(size, env); } fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline @@ -566,14 +590,14 @@ fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline return temp().acquire(size, false, alignment, offset, null)!!; } -fn void* realloc(void *ptr, usz new_size) @builtin @inline +fn void* realloc(void *ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline { - return heap().realloc(ptr, new_size); + return heap().realloc(ptr, new_size, env); } -fn void free(void* ptr) @builtin @inline +fn void free(void* ptr, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline { - heap().free(ptr); + heap().free(ptr, env); } fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin @inline diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index 347f11032..84fdf642c 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -9,6 +9,8 @@ struct TrackingEnv String function; uint line; } + + interface Allocator { fn void reset(usz mark) @optional; @@ -103,116 +105,120 @@ fn usz alignment_for_allocation(usz alignment) @inline @private return alignment < mem::DEFAULT_MEM_ALIGNMENT ? alignment = mem::DEFAULT_MEM_ALIGNMENT : alignment; } -module std::core::mem::allocator @if(!env::TRACK_MEMORY); - // Allocator "functions" -macro void*! Allocator.alloc_checked(&self, usz size) +macro void*! Allocator.alloc_checked(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) { $if env::TESTING: - char* data = self.acquire(size, false, 0, 0, null)!; + char* data = self.acquire(size, false, 0, 0, env)!; mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT); return data; $else - return self.acquire(size, false, 0, 0, null); + return self.acquire(size, false, 0, 0, env); $endif } -macro void*! Allocator.calloc_checked(&self, usz size) => self.acquire(size, true, 0, 0, null); -macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size) => self.resize(ptr, new_size, 0, 0, null); +macro void*! Allocator.calloc_checked(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) +{ + return self.acquire(size, true, 0, 0, env); +} +macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env()) +{ + return self.resize(ptr, new_size, 0, 0, env); +} -macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0) +macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) { - return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size]!!; + return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, env))[:size]!!; } -macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0) +macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) { - return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size]; + return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, env))[:size]; } -macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0) +macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) { - return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size]!!; + return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, env))[:size]!!; } -macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0) +macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) { - return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size]; + return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, env))[:size]; } -macro Allocator.new(&self, $Type, usz end_padding = 0) @nodiscard +macro Allocator.new(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return ($Type*)self.alloc_checked($Type.sizeof + end_padding)!!; + return ($Type*)self.alloc_checked($Type.sizeof + end_padding, env)!!; } -macro Allocator.new_checked(&self, $Type, usz end_padding = 0) @nodiscard +macro Allocator.new_checked(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return ($Type*)self.alloc_checked($Type.sizeof + end_padding); + return ($Type*)self.alloc_checked($Type.sizeof + end_padding, env); } -macro Allocator.new_clear(&self, $Type, usz end_padding = 0) @nodiscard +macro Allocator.new_clear(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return ($Type*)self.calloc_checked($Type.sizeof + end_padding)!!; + return ($Type*)self.calloc_checked($Type.sizeof + end_padding, env)!!; } -macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0) @nodiscard +macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return ($Type*)self.calloc_checked($Type.sizeof + end_padding); + return ($Type*)self.calloc_checked($Type.sizeof + end_padding, env); } -macro Allocator.clone(&self, value) +macro Allocator.clone(&self, value, TrackingEnv* env = mem::get_tracking_env()) { - var x = self.alloc($typeof(value)); + var x = self.alloc($typeof(value), env); *x = value; return x; } -macro void* Allocator.alloc(&self, usz size) @nodiscard +macro void* Allocator.alloc(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return self.alloc_checked(size)!!; + return self.alloc_checked(size, env)!!; } -macro void* Allocator.calloc(&self, usz size) @nodiscard +macro void* Allocator.calloc(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return self.acquire(size, true, 0, 0, null)!!; + return self.acquire(size, true, 0, 0, env)!!; } -macro void* Allocator.realloc(&self, void* ptr, usz new_size) @nodiscard +macro void* Allocator.realloc(&self, void* ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard { - return self.resize(ptr, new_size, 0, 0, null)!!; + return self.resize(ptr, new_size, 0, 0, env)!!; } -macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0) +macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0, TrackingEnv* env = mem::get_tracking_env()) { $if env::TESTING: - char* data = self.acquire(size, false, alignment, offset, null)!; + char* data = self.acquire(size, false, alignment, offset, env)!; mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT); return data; $else - return self.acquire(size, false, alignment, offset, null); + return self.acquire(size, false, alignment, offset, env); $endif } -macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0) +macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0, TrackingEnv* env = mem::get_tracking_env()) { - return self.acquire(size, true, alignment, offset, null); + return self.acquire(size, true, alignment, offset, env); } -macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0) +macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0, TrackingEnv* env = mem::get_tracking_env()) { - return self.resize(ptr, new_size, alignment, offset, null); + return self.resize(ptr, new_size, alignment, offset, env); } -macro void Allocator.free(&self, void* ptr) +macro void Allocator.free(&self, void* ptr, TrackingEnv* env = mem::get_tracking_env()) { $if env::TESTING: if (ptr) ((char*)ptr)[0] = 0xBA; $endif - self.release(ptr, false, null); + self.release(ptr, false, env); } -macro void Allocator.free_aligned(&self, void* ptr) +macro void Allocator.free_aligned(&self, void* ptr, TrackingEnv* env = mem::get_tracking_env()) { $if env::TESTING: if (ptr) ((char*)ptr)[0] = 0xBA; $endif - self.release(ptr, true, null); + self.release(ptr, true, env); } diff --git a/lib/std/core/mem_tracked.c3 b/lib/std/core/mem_tracked.c3 deleted file mode 100644 index 9cf9fbb78..000000000 --- a/lib/std/core/mem_tracked.c3 +++ /dev/null @@ -1,194 +0,0 @@ -module std::core::mem @if(env::TRACK_MEMORY); - -macro @clone(value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin -{ - return mem::heap().clone(value, .file = file, .func = func, .line = line); -} - -macro @tclone(value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin -{ - return mem::temp().clone(value, .file = file, .func = func, .line = line); -} - -fn void* malloc(usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return mem::heap().alloc(size, .file = file, .func = func, .line = line); -} - -fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return temp().acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!!; -} - -macro new($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return heap().new($Type, .file = file, .func = func, .line = line); -} - -macro new_clear($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return heap().new_clear($Type, .file = file, .func = func, .line = line); -} - -macro new_temp($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return tmalloc($Type.sizeof, .file = file, .func = func, .line = line); -} - -macro new_temp_clear($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return tcalloc($Type.sizeof, .file = file, .func = func, .line = line); -} - -macro new_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return heap().new_array($Type, elements, .file = file, .func = func, .line = line); -} - -macro temp_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)tmalloc($Type.sizeof * elements, $Type.alignof, .file = file, .func = func, .line = line))[:elements]; -} - -macro new_zero_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return heap().new_zero_array($Type, elements, .file = file, .func = func, .line = line); -} - -macro temp_zero_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)tcalloc($Type.sizeof * elements, $Type.alignof, .file = file, .func = func, .line = line))[:elements]; -} - -fn void* calloc(usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return heap().calloc(size, .file = file, .func = func, .line = line); -} - -fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return temp().acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!!; -} - -fn void* realloc(void *ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return heap().realloc(ptr, new_size, .file = file, .func = func, .line = line); -} - -fn void free(void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - heap().free(ptr, .file = file, .func = func, .line = line); -} - -fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline -{ - return temp().resize(ptr, size, alignment, 0, .env = &&TrackingEnv{ file, func, line})!!; -} - -module std::core::mem::allocator @if(env::TRACK_MEMORY); - -macro void*! Allocator.alloc_checked(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - char* data = self.acquire(size, false, 0, 0, .env = &&TrackingEnv{ file, func, line})!; - mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT); - return data; -} - -macro void*! Allocator.calloc_checked(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return self.acquire(size, true, 0, 0, .env = &&TrackingEnv{ file, func, line}); -} -macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return self.resize(ptr, new_size, 0, 0, .env = &&TrackingEnv{ file, func, line}); -} - -macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]!!; -} - -macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]; -} - -macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]!!; -} - -macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]; -} - -macro Allocator.new(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return ($Type*)self.alloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line)!!; -} - -macro Allocator.new_checked(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return ($Type*)self.alloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line); -} - -macro Allocator.new_clear(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return ($Type*)self.calloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line)!!; -} - -macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return ($Type*)self.calloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line); -} - -macro Allocator.clone(&self, value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - var x = self.alloc($typeof(value), .file = file, .func = func, .line = line); - *x = value; - return x; -} - -macro void* Allocator.alloc(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return self.alloc_checked(size, .file = file, .func = func, .line = line)!!; -} -macro void* Allocator.calloc(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return self.acquire(size, true, 0, 0, .env = &&TrackingEnv{ file, func, line})!!; -} -macro void* Allocator.realloc(&self, void* ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard -{ - return self.resize(ptr, new_size, 0, 0, .env = &&TrackingEnv{ file, func, line})!!; -} -macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - $if env::TESTING: - char* data = self.acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!; - mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT); - return data; - $else - return self.acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line}); - $endif -} -macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return self.acquire(size, true, alignment, offset, .env = &&TrackingEnv{ file, func, line}); -} -macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - return self.resize(ptr, new_size, alignment, offset, .env = &&TrackingEnv{ file, func, line}); -} - -macro void Allocator.free(&self, void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - if (ptr) ((char*)ptr)[0] = 0xBA; - self.release(ptr, false, .env = &&TrackingEnv{ file, func, line}); -} - -macro void Allocator.free_aligned(&self, void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) -{ - if (ptr) ((char*)ptr)[0] = 0xBA; - self.release(ptr, true, .env = &&TrackingEnv{ file, func, line}); -} \ No newline at end of file diff --git a/lib/std/core/string.c3 b/lib/std/core/string.c3 index aa8ea42f5..3800cf1f2 100644 --- a/lib/std/core/string.c3 +++ b/lib/std/core/string.c3 @@ -38,13 +38,13 @@ macro String tformat(String fmt, ...) return str.str_view(); } -macro String new_format(String fmt, ..., Allocator* allocator = mem::heap()) +macro String new_format(String fmt, ..., Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { @pool(allocator) { DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); str.appendf(fmt, $vasplat()); - return str.copy_str(allocator); + return str.copy_str(allocator, env); }; } @@ -55,11 +55,11 @@ macro bool char_in_set(char c, String set) return false; } -fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap()) +fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { if (!s) { - return (String)allocator.new_zero_array(char, 2)[:0]; + return (String)allocator.new_zero_array(char, 2, .env = env)[:0]; } usz total_size = joiner.len * s.len; @@ -76,7 +76,7 @@ fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap() res.append(joiner); res.append(*str); } - return res.copy_str(allocator); + return res.copy_str(allocator, env); }; } @@ -153,11 +153,11 @@ fn String String.strip_end(string, String needle) * @require needle.len > 0 "The needle must be at least 1 character long" * @ensure return.len > 0 **/ -fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap()) +fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz capacity = 16; usz i = 0; - String* holder = allocator.new_array(String, capacity); + String* holder = allocator.new_array(String, capacity, .env = env); bool no_more = false; while (!no_more) { @@ -176,7 +176,7 @@ fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = m if (i == capacity) { capacity *= 2; - holder = allocator.realloc(holder, String.sizeof * capacity); + holder = allocator.realloc(holder, String.sizeof * capacity, env); } holder[i++] = res; } @@ -312,19 +312,19 @@ fn usz ZString.len(str) } -fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap()) +fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len = s.len; - char* str = allocator.alloc(len + 1); + char* str = allocator.alloc(len + 1, env); mem::copy(str, s.ptr, len); str[len] = 0; return (ZString)str; } -fn String String.concat(s1, String s2, Allocator* allocator = mem::heap()) +fn String String.concat(s1, String s2, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz full_len = s1.len + s2.len; - char* str = allocator.alloc(full_len + 1); + char* str = allocator.alloc(full_len + 1, env); usz s1_len = s1.len; mem::copy(str, s1.ptr, s1_len); mem::copy(str + s1_len, s2.ptr, s2.len); @@ -337,27 +337,27 @@ fn String String.tconcat(s1, String s2) => s1.concat(s2, mem::temp()); fn ZString String.zstr_tcopy(s) => s.zstr_copy(mem::temp()) @inline; -fn String String.copy(s, Allocator* allocator = mem::heap()) +fn String String.copy(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len = s.len; - char* str = allocator.alloc(len + 1); + char* str = allocator.alloc(len + 1, env); mem::copy(str, s.ptr, len); str[len] = 0; return (String)str[:len]; } -fn void String.free(&s, Allocator* allocator = mem::heap()) +fn void String.free(&s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { if (!s.len) return; - allocator.free(s.ptr); + allocator.free(s.ptr, env); *s = ""; } fn String String.tcopy(s) => s.copy(mem::temp()) @inline; -fn String ZString.copy(z, Allocator* allocator = mem::temp()) +fn String ZString.copy(z, Allocator* allocator = mem::temp(), TrackingEnv* env = mem::get_tracking_env()) { - return z.str_view().copy(allocator) @inline; + return z.str_view().copy(allocator, env) @inline; } fn String ZString.tcopy(z) @@ -371,10 +371,10 @@ fn String ZString.tcopy(z) * @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence" * @return! AllocationFailure "If allocation of the string fails" **/ -fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap()) +fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len16 = conv::utf16len_for_utf8(s); - Char16* data = allocator.new_array_checked(Char16, len16 + 1)!; + Char16* data = allocator.new_array_checked(Char16, len16 + 1, .env = env)!; conv::utf8to16_unsafe(s, data)!; data[len16] = 0; return data[:len16]; @@ -391,9 +391,9 @@ fn Char16[]! String.to_temp_utf16(s) return s.to_new_utf16(mem::temp()); } -fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap()) +fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { - return (WString)s.to_new_utf16(allocator).ptr; + return (WString)s.to_new_utf16(allocator, env).ptr; } fn WString! String.to_temp_wstring(s) @@ -401,10 +401,10 @@ fn WString! String.to_temp_wstring(s) return (WString)s.to_temp_utf16().ptr; } -fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap()) +fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz codepoints = conv::utf8_codepoints(s); - Char32* data = allocator.new_array(Char32, codepoints + 1); + Char32* data = allocator.new_array(Char32, codepoints + 1, .env = env); conv::utf8to32_unsafe(s, data)!; data[codepoints] = 0; return data[:codepoints]; @@ -449,32 +449,32 @@ fn String String.temp_ascii_to_upper(s) return s.new_ascii_to_upper(mem::temp()); } -fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap()) +fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len = conv::utf8len_for_utf32(utf32); - char* data = allocator.alloc_checked(len + 1)!; + char* data = allocator.alloc_checked(len + 1, env)!; defer catch allocator.free(data); conv::utf32to8_unsafe(utf32, data); data[len] = 0; return (String)data[:len]; } -fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap()) +fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz len = conv::utf8len_for_utf16(utf16); - char* data = allocator.alloc_checked(len + 1)!; + char* data = allocator.alloc_checked(len + 1, env)!; defer catch allocator.free(data); conv::utf16to8_unsafe(utf16, data)!; data[len] = 0; return (String)data[:len]; } -fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap()) +fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { usz utf16_len; while (wstring[utf16_len] != 0) utf16_len++; Char16[] utf16 = wstring[:utf16_len]; - return new_from_utf16(utf16, allocator); + return new_from_utf16(utf16, allocator, env); } fn String! temp_from_wstring(WString wstring) => new_from_wstring(wstring, mem::temp()) @inline; diff --git a/lib/std/io/stream/bytebuffer.c3 b/lib/std/io/stream/bytebuffer.c3 index 0338483f9..4ac5d6370 100644 --- a/lib/std/io/stream/bytebuffer.c3 +++ b/lib/std/io/stream/bytebuffer.c3 @@ -16,11 +16,11 @@ struct ByteBuffer (InStream, OutStream) * max_read defines how many bytes might be kept before its internal buffer is shrinked. * @require self.bytes.len == 0 "Buffer already initialized." **/ -fn ByteBuffer*! ByteBuffer.init_new(&self, usz max_read, usz initial_capacity = 16, Allocator* allocator = mem::heap()) +fn ByteBuffer*! ByteBuffer.init_new(&self, usz max_read, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) { *self = { .allocator = allocator, .max_read = max_read }; initial_capacity = max(initial_capacity, 16); - self.grow(initial_capacity)!; + self.grow(initial_capacity, env)!; return self; } @@ -128,10 +128,10 @@ fn usz! ByteBuffer.available(&self) @inline @dynamic return self.write_idx - self.read_idx; } -fn void! ByteBuffer.grow(&self, usz n) +fn void! ByteBuffer.grow(&self, usz n, TrackingEnv* env = mem::get_tracking_env()) { n = math::next_power_of_2(n); - char* p = self.allocator.realloc_aligned(self.bytes, n, .alignment = char.alignof)!; + char* p = self.allocator.realloc_aligned(self.bytes, n, .alignment = char.alignof, .env = env)!; self.bytes = p[:n]; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index f348ace00..ff5ccaa83 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1305,7 +1305,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee, SemaContext *new_context = context_transform_for_eval(context, &default_context, param->unit); bool success; SCOPE_START - new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : init_expr->span.row; + new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : call->span.row; success = sema_analyse_expr_rhs(new_context, param->type, arg, true, no_match_ref); SCOPE_END; sema_context_destroy(&default_context); @@ -6783,9 +6783,19 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * expr_rewrite_to_string(expr, date_get()); return true; case BUILTIN_DEF_FILE: + if (context->call_env.current_function) + { + expr_rewrite_to_string(expr, context->call_env.current_function->unit->file->name); + return true; + } expr_rewrite_to_string(expr, context->compilation_unit->file->name); return true; case BUILTIN_DEF_FILEPATH: + if (context->call_env.current_function) + { + expr_rewrite_to_string(expr, context->call_env.current_function->unit->file->full_path); + return true; + } expr_rewrite_to_string(expr, context->compilation_unit->file->full_path); return true; case BUILTIN_DEF_MODULE: diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index e52458176..8d3f96f98 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -3028,6 +3028,7 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func) Signature *signature = &func->func_decl.signature; FunctionPrototype *prototype = func->type->function.prototype; assert(prototype); + context->original_inline_line = 0; context->call_env = (CallEnv) { .current_function = func, .kind = CALL_ENV_FUNCTION, diff --git a/src/version.h b/src/version.h index 8cd16cb2c..ef15131e0 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.698" +#define COMPILER_VERSION "0.4.699" diff --git a/test/test_suite/errors/error_regression_2.c3t b/test/test_suite/errors/error_regression_2.c3t index c7e9bff29..14e2fb728 100644 --- a/test/test_suite/errors/error_regression_2.c3t +++ b/test/test_suite/errors/error_regression_2.c3t @@ -332,7 +332,7 @@ if.then7: ; preds = %if.exit4 %15 = getelementptr inbounds %Doc, ptr %literal9, i32 0, i32 0 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal10, ptr align 8 @.__const.5, i32 8, i1 false) call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value, ptr align 8 %literal10, i32 8, i1 false) - %16 = call ptr @std.core.mem.malloc(i64 8) #3 + %16 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3 store ptr %16, ptr %temp, align 8 %17 = load ptr, ptr %temp, align 8 %not = icmp eq ptr %17, null @@ -371,7 +371,7 @@ if.then16: ; preds = %if.exit13 store ptr null, ptr %literal20, align 8 %26 = getelementptr inbounds %Head, ptr %literal20, i32 0, i32 0 store %"char[]" zeroinitializer, ptr %value22, align 8 - %27 = call ptr @std.core.mem.malloc(i64 16) #3 + %27 = call ptr @std.core.mem.malloc(i64 16, ptr null) #3 store ptr %27, ptr %temp23, align 8 %28 = load ptr, ptr %temp23, align 8 %not24 = icmp eq ptr %28, null @@ -394,7 +394,7 @@ noerr_block28: ; preds = %if.exit26 %31 = load ptr, ptr %temp23, align 8 store ptr %31, ptr %26, align 8 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value29, ptr align 8 %literal20, i32 8, i1 false) - %32 = call ptr @std.core.mem.malloc(i64 8) #3 + %32 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3 store ptr %32, ptr %temp30, align 8 %33 = load ptr, ptr %temp30, align 8 %not31 = icmp eq ptr %33, null @@ -430,7 +430,7 @@ if.exit36: ; preds = %if.exit13 store i64 %sext, ptr %len, align 8 %42 = load i64, ptr %len, align 8 %add = add i64 %42, 1 - %43 = call ptr @std.core.mem.malloc(i64 %add) #3 + %43 = call ptr @std.core.mem.malloc(i64 %add, ptr null) #3 store ptr %43, ptr %str, align 8 %44 = load ptr, ptr %str, align 8 %not37 = icmp eq ptr %44, null @@ -461,7 +461,7 @@ if.exit39: ; preds = %if.exit36 %57 = insertvalue %"char[]" undef, ptr %ptroffset47, 0 %58 = insertvalue %"char[]" %57, i64 %size, 1 store %"char[]" %58, ptr %value48, align 8 - %59 = call ptr @std.core.mem.malloc(i64 16) #3 + %59 = call ptr @std.core.mem.malloc(i64 16, ptr null) #3 store ptr %59, ptr %temp49, align 8 %60 = load ptr, ptr %temp49, align 8 %not50 = icmp eq ptr %60, null @@ -484,7 +484,7 @@ noerr_block54: ; preds = %if.exit52 %63 = load ptr, ptr %temp49, align 8 store ptr %63, ptr %53, align 8 call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value55, ptr align 8 %literal45, i32 8, i1 false) - %64 = call ptr @std.core.mem.malloc(i64 8) #3 + %64 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3 store ptr %64, ptr %temp56, align 8 %65 = load ptr, ptr %temp56, align 8 %not57 = icmp eq ptr %65, null diff --git a/test/test_suite/stdlib/map.c3t b/test/test_suite/stdlib/map.c3t index fd233b689..2dee1d6f6 100644 --- a/test/test_suite/stdlib/map.c3t +++ b/test/test_suite/stdlib/map.c3t @@ -66,7 +66,7 @@ entry: %lo = load i64, ptr %3, align 8 %4 = getelementptr inbounds { i64, ptr }, ptr %allocator, i32 0, i32 1 %hi = load ptr, ptr %4, align 8 - %5 = call ptr @std.core.dstring.new_with_capacity(i64 128, i64 %lo, ptr %hi) + %5 = call ptr @std.core.dstring.new_with_capacity(i64 128, i64 %lo, ptr %hi, ptr null) store ptr %5, ptr %s, align 8 %6 = getelementptr inbounds %Foo, ptr %0, i32 0, i32 0 %7 = insertvalue %"any*" undef, ptr %6, 0 @@ -133,7 +133,7 @@ entry: call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 48, i1 false) %lo = load i64, ptr @std.core.mem.thread_allocator, align 8 %hi = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8 - %0 = call ptr @"std.collections.map$int$test.Foo$.HashMap.init_new"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi) + %0 = call ptr @"std.collections.map$int$test.Foo$.HashMap.init_new"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi, ptr null) %1 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2 %2 = insertvalue %"any*" undef, ptr %1, 0 %3 = insertvalue %"any*" %2, i64 ptrtoint (ptr @"$ct.uint" to i64), 1 @@ -213,7 +213,7 @@ after_check14: ; preds = %entry, %after_check call void @llvm.memset.p0.i64(ptr align 8 %map2, i8 0, i64 48, i1 false) %lo33 = load i64, ptr @std.core.mem.thread_allocator, align 8 %hi34 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8 - %48 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34) + %48 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34, ptr null) %49 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 4, double 1.300000e+00) %50 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.300000e+00) store i8 %50, ptr %taddr36, align 1 @@ -266,7 +266,7 @@ if.exit: ; preds = %if.then, %after_che call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 48, i1 false) %lo59 = load i64, ptr @std.core.mem.thread_allocator, align 8 %hi60 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8 - %76 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60) + %76 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60, ptr null) %77 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00) %78 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00) %lo62 = load i64, ptr @std.core.mem.thread_allocator, align 8