From 9c932d39fd256dbaed1f89197de35ac2e5810562 Mon Sep 17 00:00:00 2001 From: dkorpel Date: Sat, 29 May 2021 14:18:15 +0200 Subject: [PATCH] add return scope to realloc --- std/internal/cstring.d | 60 +++++++++++++++++++++++------------------- std/internal/memory.d | 4 +-- std/uni/package.d | 2 +- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/std/internal/cstring.d b/std/internal/cstring.d index 718305bd2c7..a61ee81cc45 100644 --- a/std/internal/cstring.d +++ b/std/internal/cstring.d @@ -145,7 +145,10 @@ if (isSomeChar!To && (isInputRange!From || isSomeString!From) && { if (i + 1 == p.length) { - heapBuffer = trustedRealloc(p, strLength, heapBuffer is null); + if (heapBuffer is null) + heapBuffer = trustedReallocStack(p, strLength); + else + heapBuffer = trustedRealloc(heapBuffer); p = heapBuffer; } p[i++] = c; @@ -269,38 +272,41 @@ private: static TempCStringBuffer trustedVoidInit() { TempCStringBuffer res = void; return res; } } -private To[] trustedRealloc(To)(scope To[] buf, size_t strLength, bool bufIsOnStack) +private To[] trustedRealloc(To)(return scope To[] buf) @trusted @nogc pure nothrow { pragma(inline, false); // because it's rarely called + import std.internal.memory : enforceRealloc; - import std.internal.memory : enforceMalloc, enforceRealloc; - - size_t newlen = buf.length * 3 / 2; - - if (bufIsOnStack) - { - if (newlen <= strLength) - newlen = strLength + 1; // +1 for terminating 0 - auto ptr = cast(To*) enforceMalloc(newlen * To.sizeof); - ptr[0 .. buf.length] = buf[]; - return ptr[0 .. newlen]; - } - else + const size_t newlen = buf.length * 3 / 2; + if (buf.length >= size_t.max / (2 * To.sizeof)) { - if (buf.length >= size_t.max / (2 * To.sizeof)) + version (D_Exceptions) { - version (D_Exceptions) - { - import core.exception : onOutOfMemoryError; - onOutOfMemoryError(); - } - else - { - assert(0, "Memory allocation failed"); - } + import core.exception : onOutOfMemoryError; + onOutOfMemoryError(); + } + else + { + assert(0, "Memory allocation failed"); } - auto ptr = cast(To*) enforceRealloc(buf.ptr, newlen * To.sizeof); - return ptr[0 .. newlen]; } + auto ptr = cast(To*) enforceRealloc(buf.ptr, newlen * To.sizeof); + return ptr[0 .. newlen]; + +} + +private To[] trustedReallocStack(To)(scope To[] buf, size_t strLength) + @trusted @nogc pure nothrow +{ + pragma(inline, false); // because it's rarely called + + import std.internal.memory : enforceMalloc; + + size_t newlen = buf.length * 3 / 2; + if (newlen <= strLength) + newlen = strLength + 1; // +1 for terminating 0 + auto ptr = cast(To*) enforceMalloc(newlen * To.sizeof); + ptr[0 .. buf.length] = buf[]; + return ptr[0 .. newlen]; } diff --git a/std/internal/memory.d b/std/internal/memory.d index a8b677d4b3b..991cd685b73 100644 --- a/std/internal/memory.d +++ b/std/internal/memory.d @@ -42,7 +42,7 @@ void* enforceCalloc()(size_t nmemb, size_t size) @nogc nothrow pure @safe } // ditto -void* enforceRealloc()(void* ptr, size_t size) @nogc nothrow pure @system +void* enforceRealloc()(return scope void* ptr, size_t size) @nogc nothrow pure @system { auto result = fakePureRealloc(ptr, size); if (!result) mixin(allocationFailed); @@ -54,5 +54,5 @@ extern (C) @nogc nothrow pure private { pragma(mangle, "malloc") void* fakePureMalloc(size_t) @safe; pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size) @safe; - pragma(mangle, "realloc") void* fakePureRealloc(void* ptr, size_t size) @system; + pragma(mangle, "realloc") void* fakePureRealloc(return scope void* ptr, size_t size) @system; } diff --git a/std/uni/package.d b/std/uni/package.d index b52ba78d7c7..318bcb32a6f 100644 --- a/std/uni/package.d +++ b/std/uni/package.d @@ -1819,7 +1819,7 @@ alias sharSwitchLowerBound = sharMethod!switchUniformLowerBound; return ptr[0 .. size]; } - static T[] realloc(T)(scope T[] arr, size_t size) @trusted + static T[] realloc(T)(return scope T[] arr, size_t size) @trusted { import std.internal.memory : enforceRealloc; if (!size)