Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add return scope to realloc #8116

Merged
merged 1 commit into from
Jun 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 33 additions & 27 deletions std/internal/cstring.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
}
4 changes: 2 additions & 2 deletions std/internal/memory.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
2 changes: 1 addition & 1 deletion std/uni/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down