Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Fix Issue 19421: Make pureMalloc, etc. usable in BetterC
Browse files Browse the repository at this point in the history
  • Loading branch information
n8sh committed Nov 22, 2018
1 parent 0450507 commit 0e8fe45
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
57 changes: 43 additions & 14 deletions src/core/memory.d
Expand Up @@ -822,35 +822,35 @@ struct GC
* $(LINK2 https://dlang.org/spec/function.html#pure-functions, D's rules for purity),
* which allow for memory allocation under specific circumstances.
*/
void* pureMalloc(size_t size) @trusted pure @nogc nothrow
void* pureMalloc()(size_t size) @trusted pure @nogc nothrow
{
const errnosave = fakePureErrno();
const errnosave = fakePureErrno;
void* ret = fakePureMalloc(size);
fakePureErrno() = errnosave;
fakePureErrno = errnosave;
return ret;
}
/// ditto
void* pureCalloc(size_t nmemb, size_t size) @trusted pure @nogc nothrow
void* pureCalloc()(size_t nmemb, size_t size) @trusted pure @nogc nothrow
{
const errnosave = fakePureErrno();
const errnosave = fakePureErrno;
void* ret = fakePureCalloc(nmemb, size);
fakePureErrno() = errnosave;
fakePureErrno = errnosave;
return ret;
}
/// ditto
void* pureRealloc(void* ptr, size_t size) @system pure @nogc nothrow
void* pureRealloc()(void* ptr, size_t size) @system pure @nogc nothrow
{
const errnosave = fakePureErrno();
const errnosave = fakePureErrno;
void* ret = fakePureRealloc(ptr, size);
fakePureErrno() = errnosave;
fakePureErrno = errnosave;
return ret;
}
/// ditto
void pureFree(void* ptr) @system pure @nogc nothrow
void pureFree()(void* ptr) @system pure @nogc nothrow
{
const errnosave = fakePureErrno();
const errnosave = fakePureErrno;
fakePureFree(ptr);
fakePureErrno() = errnosave;
fakePureErrno = errnosave;
}

///
Expand Down Expand Up @@ -900,6 +900,37 @@ void pureFree(void* ptr) @system pure @nogc nothrow

// locally purified for internal use here only

static import core.stdc.errno;
static if (__traits(getOverloads, core.stdc.errno, "errno").length == 1
&& __traits(getLinkage, core.stdc.errno.errno) == "C")
{
extern(C) pragma(mangle, __traits(identifier, core.stdc.errno.errno))
private ref int fakePureErrno() @nogc nothrow pure @system;
}
else
{
extern(C) private @nogc nothrow pure @system
{
pragma(mangle, __traits(identifier, core.stdc.errno.getErrno))
private int fakePureGetErrno();

pragma(mangle, __traits(identifier, core.stdc.errno.setErrno))
private int fakePureSetErrno(int);
}

private @property int fakePureErrno()() @nogc nothrow pure @system
{
return fakePureGetErrno();
}

private @property void fakePureErrno()(int newValue) @nogc nothrow pure @system
{
fakePureSetErrno(newValue);
}
}

version (D_BetterC) {}
else // TODO: remove this function after Phobos no longer needs it.
extern (C) private @system @nogc nothrow
{
ref int fakePureErrnoImpl()
Expand All @@ -911,8 +942,6 @@ extern (C) private @system @nogc nothrow

extern (C) private pure @system @nogc nothrow
{
pragma(mangle, "fakePureErrnoImpl") ref int fakePureErrno();

pragma(mangle, "malloc") void* fakePureMalloc(size_t);
pragma(mangle, "calloc") void* fakePureCalloc(size_t nmemb, size_t size);
pragma(mangle, "realloc") void* fakePureRealloc(void* ptr, size_t size);
Expand Down
2 changes: 1 addition & 1 deletion test/betterc/Makefile
@@ -1,6 +1,6 @@
include ../common.mak

TESTS:=test18828 test19416
TESTS:=test18828 test19416 test19421

.PHONY: all clean
all: $(addprefix $(ROOT)/,$(addsuffix ,$(TESTS)))
Expand Down
13 changes: 13 additions & 0 deletions test/betterc/src/test19421.d
@@ -0,0 +1,13 @@
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=19421

import core.memory;

extern(C) void main() @nogc nothrow pure
{
auto p = pureMalloc(1);
p = pureRealloc(p, 2);
if (p) pureFree(p);
p = pureCalloc(1, 1);
if (p) pureFree(p);
}

0 comments on commit 0e8fe45

Please sign in to comment.