From 90c339ebdb513a251e8acf74aa0fd28fddb69d95 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 1 Aug 2025 23:43:18 +0200 Subject: [PATCH] List.remove_at would incorrectly trigger ASAN. --- lib/std/collections/list.c3 | 7 ++++--- releasenotes.md | 2 ++ test/unit/stdlib/collections/list.c3 | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/std/collections/list.c3 b/lib/std/collections/list.c3 index 65369642b..c618e9cef 100644 --- a/lib/std/collections/list.c3 +++ b/lib/std/collections/list.c3 @@ -137,9 +137,10 @@ fn Type? List.pop_first(&self) *> fn void List.remove_at(&self, usz index) { - self.set_size(self.size - 1); - if (!self.size || index == self.size) return; - self.entries[index .. self.size - 1] = self.entries[index + 1 .. self.size]; + usz new_size = self.size - 1; + defer self.set_size(new_size); + if (!new_size || index == new_size) return; + self.entries[index .. new_size - 1] = self.entries[index + 1 .. new_size]; } fn void List.add_all(&self, List* other_list) diff --git a/releasenotes.md b/releasenotes.md index cab93b8a6..f8b2cc771 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -6,6 +6,8 @@ - Support `alias foo = module std::io` module aliasing. ### Fixes +- List.remove_at would incorrectly trigger ASAN. + ### Stdlib changes ## 0.7.4 Change list diff --git a/test/unit/stdlib/collections/list.c3 b/test/unit/stdlib/collections/list.c3 index 000f38757..6e5fcbc1f 100644 --- a/test/unit/stdlib/collections/list.c3 +++ b/test/unit/stdlib/collections/list.c3 @@ -20,6 +20,22 @@ fn void overaligned_type() assert((usz)l.get_ref(2) - (usz)l.get_ref(1) == Overalign.sizeof); } +fn void remove_at() +{ + IntList test; + test.init(mem); + defer test.free(); + test.add_array({ 1, 2, 3, 4 }); + test::eq(test.array_view(), (int[]){ 1, 2, 3, 4 }); + test.remove_at(0); + test::eq(test.array_view(), (int[]){ 2, 3, 4 }); + test.remove_at(1); + test::eq(test.array_view(), (int[]){ 2, 4 }); + test.remove_at(1); + test::eq(test.array_view(), (int[]){ 2 }); + test.remove_at(0); + test::eq(test.array_view(), (int[]){ }); +} fn void delete_contains_index() {