mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 22:03:57 +08:00
re PR d/90079 (SEGV in _aaKeys, _aaValues on 32-bit SPARC)
PR d/90079 libphobos: Fix SEGV in _aaKeys, _aaValues on 32-bit SPARC Merges upstream druntime b43203a1 Reviewed-on: https://github.com/dlang/druntime/pull/2572 From-SVN: r270514
This commit is contained in:
parent
d86bc962ae
commit
c7bfed18df
@ -1,4 +1,4 @@
|
||||
109f0f2e11aaaddd2b158117928e10c3c4688870
|
||||
b43203a134fb5e259ffc1711cc061c6e869b56f6
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the dlang/druntime repository.
|
||||
|
@ -661,12 +661,12 @@ class TypeInfo_AssociativeArray : TypeInfo
|
||||
|
||||
override bool equals(in void* p1, in void* p2) @trusted const
|
||||
{
|
||||
return !!_aaEqual(this, *cast(const void**) p1, *cast(const void**) p2);
|
||||
return !!_aaEqual(this, *cast(const AA*) p1, *cast(const AA*) p2);
|
||||
}
|
||||
|
||||
override hash_t getHash(scope const void* p) nothrow @trusted const
|
||||
{
|
||||
return _aaGetHash(cast(void*)p, this);
|
||||
return _aaGetHash(cast(AA*)p, this);
|
||||
}
|
||||
|
||||
// BUG: need to add the rest of the functions
|
||||
@ -1862,30 +1862,31 @@ extern (C)
|
||||
{
|
||||
// from druntime/src/rt/aaA.d
|
||||
|
||||
// size_t _aaLen(in void* p) pure nothrow @nogc;
|
||||
private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow;
|
||||
private void* _aaGetX(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey, out bool found) pure nothrow;
|
||||
// inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey);
|
||||
inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow;
|
||||
inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow;
|
||||
void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow;
|
||||
void _aaClear(void* p) pure nothrow;
|
||||
private struct AA { void* impl; }
|
||||
// size_t _aaLen(in AA aa) pure nothrow @nogc;
|
||||
private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey) pure nothrow;
|
||||
private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey, out bool found) pure nothrow;
|
||||
// inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
|
||||
inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow;
|
||||
inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
|
||||
void* _aaRehash(AA* paa, in TypeInfo keyti) pure nothrow;
|
||||
void _aaClear(AA aa) pure nothrow;
|
||||
|
||||
// alias _dg_t = extern(D) int delegate(void*);
|
||||
// int _aaApply(void* aa, size_t keysize, _dg_t dg);
|
||||
// int _aaApply(AA aa, size_t keysize, _dg_t dg);
|
||||
|
||||
// alias _dg2_t = extern(D) int delegate(void*, void*);
|
||||
// int _aaApply2(void* aa, size_t keysize, _dg2_t dg);
|
||||
// int _aaApply2(AA aa, size_t keysize, _dg2_t dg);
|
||||
|
||||
private struct AARange { void* impl; size_t idx; }
|
||||
AARange _aaRange(void* aa) pure nothrow @nogc @safe;
|
||||
private struct AARange { AA impl; size_t idx; }
|
||||
AARange _aaRange(AA aa) pure nothrow @nogc @safe;
|
||||
bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
|
||||
void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
|
||||
void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
|
||||
void _aaRangePopFront(ref AARange r) pure nothrow @nogc @safe;
|
||||
|
||||
int _aaEqual(in TypeInfo tiRaw, in void* e1, in void* e2);
|
||||
hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow;
|
||||
int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2);
|
||||
hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow;
|
||||
|
||||
/*
|
||||
_d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
|
||||
@ -1910,13 +1911,13 @@ alias AssociativeArray(Key, Value) = Value[Key];
|
||||
*/
|
||||
void clear(T : Value[Key], Value, Key)(T aa)
|
||||
{
|
||||
_aaClear(*cast(void **) &aa);
|
||||
_aaClear(*cast(AA *) &aa);
|
||||
}
|
||||
|
||||
/* ditto */
|
||||
void clear(T : Value[Key], Value, Key)(T* aa)
|
||||
{
|
||||
_aaClear(*cast(void **) aa);
|
||||
_aaClear(*cast(AA *) aa);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@ -1929,28 +1930,28 @@ void clear(T : Value[Key], Value, Key)(T* aa)
|
||||
*/
|
||||
T rehash(T : Value[Key], Value, Key)(T aa)
|
||||
{
|
||||
_aaRehash(cast(void**)&aa, typeid(Value[Key]));
|
||||
_aaRehash(cast(AA*)&aa, typeid(Value[Key]));
|
||||
return aa;
|
||||
}
|
||||
|
||||
/* ditto */
|
||||
T rehash(T : Value[Key], Value, Key)(T* aa)
|
||||
{
|
||||
_aaRehash(cast(void**)aa, typeid(Value[Key]));
|
||||
_aaRehash(cast(AA*)aa, typeid(Value[Key]));
|
||||
return *aa;
|
||||
}
|
||||
|
||||
/* ditto */
|
||||
T rehash(T : shared Value[Key], Value, Key)(T aa)
|
||||
{
|
||||
_aaRehash(cast(void**)&aa, typeid(Value[Key]));
|
||||
_aaRehash(cast(AA*)&aa, typeid(Value[Key]));
|
||||
return aa;
|
||||
}
|
||||
|
||||
/* ditto */
|
||||
T rehash(T : shared Value[Key], Value, Key)(T* aa)
|
||||
{
|
||||
_aaRehash(cast(void**)aa, typeid(Value[Key]));
|
||||
_aaRehash(cast(AA*)aa, typeid(Value[Key]));
|
||||
return *aa;
|
||||
}
|
||||
|
||||
@ -1977,7 +1978,7 @@ V[K] dup(T : V[K], K, V)(T aa)
|
||||
{
|
||||
import core.stdc.string : memcpy;
|
||||
|
||||
void* pv = _aaGetY(cast(void**)&result, typeid(V[K]), V.sizeof, &k);
|
||||
void* pv = _aaGetY(cast(AA*)&result, typeid(V[K]), V.sizeof, &k);
|
||||
memcpy(pv, &v, V.sizeof);
|
||||
return *cast(V*)pv;
|
||||
}
|
||||
@ -2010,7 +2011,7 @@ private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
|
||||
alias realAA = aa;
|
||||
else
|
||||
const(V[K]) realAA = aa;
|
||||
return _aaRange(() @trusted { return cast(void*)realAA; } ());
|
||||
return _aaRange(() @trusted { return *cast(AA*)&realAA; } ());
|
||||
}
|
||||
|
||||
/***********************************
|
||||
@ -2146,7 +2147,12 @@ auto byKeyValue(T : V[K], K, V)(T* aa) pure nothrow @nogc
|
||||
*/
|
||||
Key[] keys(T : Value[Key], Value, Key)(T aa) @property
|
||||
{
|
||||
auto a = cast(void[])_aaKeys(cast(inout(void)*)aa, Key.sizeof, typeid(Key[]));
|
||||
// ensure we are dealing with a genuine AA.
|
||||
static if (is(const(Value[Key]) == const(T)))
|
||||
alias realAA = aa;
|
||||
else
|
||||
const(Value[Key]) realAA = aa;
|
||||
auto a = cast(void[])_aaKeys(*cast(inout(AA)*)&realAA, Key.sizeof, typeid(Key[]));
|
||||
auto res = *cast(Key[]*)&a;
|
||||
_doPostblit(res);
|
||||
return res;
|
||||
@ -2158,6 +2164,19 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
|
||||
return (*aa).keys;
|
||||
}
|
||||
|
||||
@system unittest
|
||||
{
|
||||
static struct S
|
||||
{
|
||||
string str;
|
||||
void[][string] dict;
|
||||
alias dict this;
|
||||
}
|
||||
|
||||
auto s = S("a");
|
||||
assert(s.keys.length == 0);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* Returns a dynamic array, the elements of which are the values in the
|
||||
* associative array.
|
||||
@ -2168,7 +2187,12 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
|
||||
*/
|
||||
Value[] values(T : Value[Key], Value, Key)(T aa) @property
|
||||
{
|
||||
auto a = cast(void[])_aaValues(cast(inout(void)*)aa, Key.sizeof, Value.sizeof, typeid(Value[]));
|
||||
// ensure we are dealing with a genuine AA.
|
||||
static if (is(const(Value[Key]) == const(T)))
|
||||
alias realAA = aa;
|
||||
else
|
||||
const(Value[Key]) realAA = aa;
|
||||
auto a = cast(void[])_aaValues(*cast(inout(AA)*)&realAA, Key.sizeof, Value.sizeof, typeid(Value[]));
|
||||
auto res = *cast(Value[]*)&a;
|
||||
_doPostblit(res);
|
||||
return res;
|
||||
@ -2180,6 +2204,19 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property
|
||||
return (*aa).values;
|
||||
}
|
||||
|
||||
@system unittest
|
||||
{
|
||||
static struct S
|
||||
{
|
||||
string str;
|
||||
void[][string] dict;
|
||||
alias dict this;
|
||||
}
|
||||
|
||||
auto s = S("a");
|
||||
assert(s.values.length == 0);
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* Looks up key; if it exists returns corresponding value else evaluates and
|
||||
* returns defaultValue.
|
||||
@ -2220,12 +2257,12 @@ ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
|
||||
{
|
||||
auto p = () @trusted
|
||||
{
|
||||
return cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
} ();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto p = cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
}
|
||||
return found ? *p : (*p = value);
|
||||
}
|
||||
@ -2276,12 +2313,12 @@ if (isCreateOperation!(C, V) && isUpdateOperation!(U, V))
|
||||
{
|
||||
auto p = () @trusted
|
||||
{
|
||||
return cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
return cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
} ();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto p = cast(V*) _aaGetX(cast(void**) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
auto p = cast(V*) _aaGetX(cast(AA*) &aa, typeid(V[K]), V.sizeof, &key, found);
|
||||
}
|
||||
if (!found)
|
||||
*p = create();
|
||||
@ -3879,3 +3916,30 @@ unittest
|
||||
scope arr = [S(&p)];
|
||||
auto a = arr.dup; // dup does escape
|
||||
}
|
||||
|
||||
// compiler frontend lowers dynamic array comparison to this
|
||||
bool __ArrayEq(T1, T2)(T1[] a, T2[] b)
|
||||
{
|
||||
if (a.length != b.length)
|
||||
return false;
|
||||
foreach (size_t i; 0 .. a.length)
|
||||
{
|
||||
if (a[i] != b[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// compiler frontend lowers struct array postblitting to this
|
||||
void __ArrayPostblit(T)(T[] a)
|
||||
{
|
||||
foreach (ref T e; a)
|
||||
e.__xpostblit();
|
||||
}
|
||||
|
||||
// compiler frontend lowers dynamic array deconstruction to this
|
||||
void __ArrayDtor(T)(T[] a)
|
||||
{
|
||||
foreach_reverse (ref T e; a)
|
||||
e.__xdtor();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user