@@ -5082,9 +5082,17 @@ struct RefCounted(T, RefCountedAutoInitialize autoInit =
50825082 RefCountedAutoInitialize.yes)
50835083if (! is (T == class ) && !(is(T == interface)))
50845084{
5085+ extern (C ) private pure nothrow @nogc static // TODO remove pure when https://issues.dlang.org/show_bug.cgi?id=15862 has been fixed
5086+ {
5087+ pragma (mangle, " free" ) void pureFree( void * ptr );
5088+ pragma (mangle, " gc_addRange" ) void pureGcAddRange( in void * p, size_t sz, const TypeInfo ti = null );
5089+ pragma (mangle, " gc_removeRange" ) void pureGcRemoveRange( in void * p );
5090+ }
5091+
50855092 // / $(D RefCounted) storage implementation.
50865093 struct RefCountedStore
50875094 {
5095+ import core.memory : pureMalloc;
50885096 private struct Impl
50895097 {
50905098 T _payload;
@@ -5096,31 +5104,27 @@ if (!is(T == class) && !(is(T == interface)))
50965104 private void initialize (A... )(auto ref A args)
50975105 {
50985106 import core.exception : onOutOfMemoryError;
5099- import core.memory : GC ;
5100- import core.stdc.stdlib : malloc;
51015107 import std.conv : emplace;
51025108
5103- _store = cast (Impl* )malloc (Impl.sizeof);
5109+ _store = cast (Impl* )pureMalloc (Impl.sizeof);
51045110 if (_store is null )
51055111 onOutOfMemoryError();
51065112 static if (hasIndirections! T)
5107- GC .addRange (&_store._payload, T.sizeof);
5113+ pureGcAddRange (&_store._payload, T.sizeof);
51085114 emplace(&_store._payload, args);
51095115 _store._count = 1 ;
51105116 }
51115117
51125118 private void move (ref T source)
51135119 {
51145120 import core.exception : onOutOfMemoryError;
5115- import core.memory : GC ;
5116- import core.stdc.stdlib : malloc;
51175121 import core.stdc.string : memcpy, memset;
51185122
5119- _store = cast (Impl* )malloc (Impl.sizeof);
5123+ _store = cast (Impl* )pureMalloc (Impl.sizeof);
51205124 if (_store is null )
51215125 onOutOfMemoryError();
51225126 static if (hasIndirections! T)
5123- GC .addRange (&_store._payload, T.sizeof);
5127+ pureGcAddRange (&_store._payload, T.sizeof);
51245128
51255129 // Can't use std.algorithm.move(source, _store._payload)
51265130 // here because it requires the target to be initialized.
@@ -5233,11 +5237,10 @@ to deallocate the corresponding resource.
52335237 .destroy (_refCounted._store._payload);
52345238 static if (hasIndirections! T)
52355239 {
5236- import core.memory : GC ;
5237- GC .removeRange(&_refCounted._store._payload);
5240+ pureGcRemoveRange(&_refCounted._store._payload);
52385241 }
5239- import core.stdc.stdlib : free;
5240- free (_refCounted._store);
5242+
5243+ pureFree (_refCounted._store);
52415244 _refCounted._store = null ;
52425245 }
52435246
@@ -5322,7 +5325,7 @@ assert(refCountedStore.isInitialized)).
53225325}
53235326
53245327// /
5325- @system unittest
5328+ pure @system nothrow @nogc unittest
53265329{
53275330 // A pair of an $(D int) and a $(D size_t) - the latter being the
53285331 // reference count - will be dynamically allocated
@@ -5336,7 +5339,7 @@ assert(refCountedStore.isInitialized)).
53365339 // the pair will be freed when rc1 and rc2 go out of scope
53375340}
53385341
5339- @system unittest
5342+ pure @system unittest
53405343{
53415344 RefCounted! int * p;
53425345 {
@@ -5375,7 +5378,7 @@ assert(refCountedStore.isInitialized)).
53755378 assert (a.x._refCounted._store._count == 2 , " BUG 4356 still unfixed" );
53765379}
53775380
5378- @system unittest
5381+ pure @system nothrow @nogc unittest
53795382{
53805383 import std.algorithm.mutation : swap;
53815384
@@ -5384,7 +5387,7 @@ assert(refCountedStore.isInitialized)).
53845387}
53855388
53865389// 6606
5387- @safe unittest
5390+ @safe pure nothrow @nogc unittest
53885391{
53895392 union U {
53905393 size_t i;
@@ -5399,7 +5402,7 @@ assert(refCountedStore.isInitialized)).
53995402}
54005403
54015404// 6436
5402- @system unittest
5405+ @system pure unittest
54035406{
54045407 struct S { this (ref int val) { assert (val == 3 ); ++ val; } }
54055408
@@ -5408,7 +5411,15 @@ assert(refCountedStore.isInitialized)).
54085411 assert (val == 4 );
54095412}
54105413
5411- @system unittest
5414+ // gc_addRange coverage
5415+ @system pure unittest
5416+ {
5417+ struct S { int * p; }
5418+
5419+ auto s = RefCounted! S(null );
5420+ }
5421+
5422+ @system pure nothrow @nogc unittest
54125423{
54135424 RefCounted! int a;
54145425 a = 5 ; // This should not assert
@@ -5417,6 +5428,8 @@ assert(refCountedStore.isInitialized)).
54175428 RefCounted! int b;
54185429 b = a; // This should not assert either
54195430 assert (b == 5 );
5431+
5432+ RefCounted! (int * ) c;
54205433}
54215434
54225435/**
0 commit comments