From f778e75757fb9a8f987ce796573ac065ce72a218 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 20 Apr 2025 18:31:52 +0200 Subject: [PATCH] Added missing `@clone_aligned` and add checks to `@tclone` --- lib/std/core/mem.c3 | 28 ++++++++++++++++++++++++++++ lib/std/core/mem_allocator.c3 | 20 ++++++++++++++++++++ releasenotes.md | 1 + test/unit/stdlib/mem/clone.c3 | 12 ++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 test/unit/stdlib/mem/clone.c3 diff --git a/lib/std/core/mem.c3 b/lib/std/core/mem.c3 index 3ac40ec3a..fbd3b9154 100644 --- a/lib/std/core/mem.c3 +++ b/lib/std/core/mem.c3 @@ -627,16 +627,44 @@ macro TrackingEnv* get_tracking_env() $endif } +<* + @param value : "The value to clone" + @return "A pointer to the cloned value" + @require $alignof(value) <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'clone_aligned' instead" +*> macro @clone(value) @builtin @nodiscard { return allocator::clone(mem, value); } +<* + @param value : "The value to clone" + @return "A pointer to the cloned value, which must be released using free_aligned" +*> +macro @clone_aligned(value) @builtin @nodiscard +{ + return allocator::clone_aligned(mem, value); +} + +<* + @param value : "The value to clone" + @return "A pointer to the cloned value" + @require $alignof(value) <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'tclone_aligned' instead" +*> macro @tclone(value) @builtin @nodiscard { return tnew($typeof(value), value); } +<* + @param value : "The value to clone" + @return "A pointer to the cloned value" +*> +macro @tclone_aligned(value) @builtin @nodiscard +{ + return allocator::clone_aligned(tmem, value); +} + fn void* malloc(usz size) @builtin @inline @nodiscard { return allocator::malloc(mem, size); diff --git a/lib/std/core/mem_allocator.c3 b/lib/std/core/mem_allocator.c3 index 35a12dbd4..4abbd2fc2 100644 --- a/lib/std/core/mem_allocator.c3 +++ b/lib/std/core/mem_allocator.c3 @@ -283,11 +283,31 @@ macro alloc_array_try(Allocator allocator, $Type, usz elements) @nodiscard return (($Type*)malloc_try(allocator, $Type.sizeof * elements))[:elements]; } +<* + Clone a value. + + @param [&inout] allocator : "The allocator to use to clone" + @param value : "The value to clone" + @return "A pointer to the cloned value" + @require $alignof(value) <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'clone_aligned' instead" +*> macro clone(Allocator allocator, value) @nodiscard { return new(allocator, $typeof(value), value); } +<* + Clone overaligned values. Must be released using free_aligned. + + @param [&inout] allocator : "The allocator to use to clone" + @param value : "The value to clone" + @return "A pointer to the cloned value" +*> +macro clone_aligned(Allocator allocator, value) @nodiscard +{ + return new_aligned(allocator, $typeof(value), value)!!; +} + fn any clone_any(Allocator allocator, any value) @nodiscard { usz size = value.type.sizeof; diff --git a/releasenotes.md b/releasenotes.md index ce86d3dc9..dc123ee3a 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -29,6 +29,7 @@ - Fix broken enum inline -> bool conversions #2094. - `@if` was ignored on attrdef, regression 0.7 #2093. - `@ensure` was not included when the function doesn't return a value #2098. +- Added missing `@clone_aligned` and add checks to `@tclone` ### Stdlib changes - Hash functions for integer vectors and arrays. diff --git a/test/unit/stdlib/mem/clone.c3 b/test/unit/stdlib/mem/clone.c3 new file mode 100644 index 000000000..a385203ce --- /dev/null +++ b/test/unit/stdlib/mem/clone.c3 @@ -0,0 +1,12 @@ +module test; + +fn void clone_test() @test +{ + double x; + void *a = @clone(x); + free(a); + (void)@tclone(x); + a = @clone_aligned(x); + free_aligned(a); + (void)@tclone_aligned(x); +}