From 79fa02c5ef1d72250d8e910a6a1fcdd691cc6fcf Mon Sep 17 00:00:00 2001 From: Emmankoko Date: Tue, 3 Sep 2024 07:41:43 +0000 Subject: [PATCH] destroy leaked bytes after lifetime ends --- dub.json | 1 + source/stdcpp/list.d | 16 ++++++++++++++++ source/stdcpp/set.d | 10 +++++++++- source/stdcpp/vector.d | 2 ++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/dub.json b/dub.json index 7b4c890..74c14be 100644 --- a/dub.json +++ b/dub.json @@ -16,6 +16,7 @@ "lflags-posix": [ "-lstdc++" ], "lflags-linux": [ "--export-dynamic" ], "lflags-osx": [ "-export_dynamic" ], + "dflags" : [ "-fsanitize=address" ], "preGenerateCommands-posix": [ "$PACKAGE_DIR/extras/cxx-wrapper.sh test", ], diff --git a/source/stdcpp/list.d b/source/stdcpp/list.d index c86267e..26d57c8 100644 --- a/source/stdcpp/list.d +++ b/source/stdcpp/list.d @@ -154,6 +154,8 @@ extern(C++, class) struct list(Type, Allocator) void sort(U)(U comp); + ~this(); + private struct node { node* prev; @@ -277,6 +279,11 @@ extern(C++, class) struct list(Type, Allocator) size_type unique(U)(U p); + ~this() + { + _List_base!(value_type, allocator_type)._M_clear(); + } + private struct node { node* prev; @@ -576,3 +583,12 @@ version (CppRuntime_Clang) void clear() nothrow; } } + +version (CppRuntime_Gcc) +{ + extern(C++, class) struct _List_base(T, Alloc) + { + /* so we can call it on the type */ + static void _M_clear() nothrow; + } +} \ No newline at end of file diff --git a/source/stdcpp/set.d b/source/stdcpp/set.d index e33433a..1eb81c4 100644 --- a/source/stdcpp/set.d +++ b/source/stdcpp/set.d @@ -55,7 +55,7 @@ extern(C++, class) struct set(Key, compare, Alloc) /// this(ref const set!(Key) __x, ref const allocator!(Key)); /// - allocator_type get_allocator() const nothrow; + allocator_type get_allocator() const nothrow; /// size_type size() const nothrow; /// @@ -203,5 +203,13 @@ version (CppRuntime_Gcc) inout(pointer) end() inout nothrow; inout(pointer) find(const ref _Key __k) inout; + + /* + * clang on linux only emits the base object dtor(D2) + * so we can safely force mangle it to that + * since the complete dtor(D1) calls D2 in its stack frame + */ + pragma(mangle, "_ZNSt8_Rb_treeIiiSt9_IdentityIiESt4lessIiESaIiEED2Ev") + ~this(); } } diff --git a/source/stdcpp/vector.d b/source/stdcpp/vector.d index 9a6f302..e878c58 100644 --- a/source/stdcpp/vector.d +++ b/source/stdcpp/vector.d @@ -840,6 +840,8 @@ extern(D): extern(C++) pointer begin() nothrow; extern(C++) pointer end() nothrow; + + extern(C++) ~this(); } else version (CppRuntime_Clang) {