Commit c7bfed18 by Iain Buclaw

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
parent d86bc962
109f0f2e11aaaddd2b158117928e10c3c4688870 b43203a134fb5e259ffc1711cc061c6e869b56f6
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository. merge done from the dlang/druntime repository.
...@@ -661,12 +661,12 @@ class TypeInfo_AssociativeArray : TypeInfo ...@@ -661,12 +661,12 @@ class TypeInfo_AssociativeArray : TypeInfo
override bool equals(in void* p1, in void* p2) @trusted const 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 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 // BUG: need to add the rest of the functions
...@@ -1862,30 +1862,31 @@ extern (C) ...@@ -1862,30 +1862,31 @@ extern (C)
{ {
// from druntime/src/rt/aaA.d // from druntime/src/rt/aaA.d
// size_t _aaLen(in void* p) pure nothrow @nogc; private struct AA { void* impl; }
private void* _aaGetY(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey) pure nothrow; // size_t _aaLen(in AA aa) pure nothrow @nogc;
private void* _aaGetX(void** paa, const TypeInfo_AssociativeArray ti, in size_t valuesize, in void* pkey, out bool found) pure nothrow; private void* _aaGetY(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey) pure nothrow;
// inout(void)* _aaGetRvalueX(inout void* p, in TypeInfo keyti, in size_t valuesize, in void* pkey); private void* _aaGetX(AA* paa, const TypeInfo_AssociativeArray ti, in size_t valsz, in void* pkey, out bool found) pure nothrow;
inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow; // inout(void)* _aaGetRvalueX(inout AA aa, in TypeInfo keyti, in size_t valsz, in void* pkey);
inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow; inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow;
void* _aaRehash(void** pp, in TypeInfo keyti) pure nothrow; inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow;
void _aaClear(void* p) 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*); // 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*); // 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; } private struct AARange { AA impl; size_t idx; }
AARange _aaRange(void* aa) pure nothrow @nogc @safe; AARange _aaRange(AA aa) pure nothrow @nogc @safe;
bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe; bool _aaRangeEmpty(AARange r) pure nothrow @nogc @safe;
void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe; void* _aaRangeFrontKey(AARange r) pure nothrow @nogc @safe;
void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe; void* _aaRangeFrontValue(AARange r) pure nothrow @nogc @safe;
void _aaRangePopFront(ref 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); int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2);
hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow; hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow;
/* /*
_d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code. _d_assocarrayliteralTX marked as pure, because aaLiteral can be called from pure code.
...@@ -1910,13 +1911,13 @@ alias AssociativeArray(Key, Value) = Value[Key]; ...@@ -1910,13 +1911,13 @@ alias AssociativeArray(Key, Value) = Value[Key];
*/ */
void clear(T : Value[Key], Value, Key)(T aa) void clear(T : Value[Key], Value, Key)(T aa)
{ {
_aaClear(*cast(void **) &aa); _aaClear(*cast(AA *) &aa);
} }
/* ditto */ /* ditto */
void clear(T : Value[Key], Value, Key)(T* aa) 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) ...@@ -1929,28 +1930,28 @@ void clear(T : Value[Key], Value, Key)(T* aa)
*/ */
T rehash(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; return aa;
} }
/* ditto */ /* ditto */
T rehash(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; return *aa;
} }
/* ditto */ /* ditto */
T rehash(T : shared Value[Key], Value, Key)(T aa) 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; return aa;
} }
/* ditto */ /* ditto */
T rehash(T : shared Value[Key], Value, Key)(T* aa) 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; return *aa;
} }
...@@ -1977,7 +1978,7 @@ V[K] dup(T : V[K], K, V)(T aa) ...@@ -1977,7 +1978,7 @@ V[K] dup(T : V[K], K, V)(T aa)
{ {
import core.stdc.string : memcpy; 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); memcpy(pv, &v, V.sizeof);
return *cast(V*)pv; return *cast(V*)pv;
} }
...@@ -2010,7 +2011,7 @@ private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe ...@@ -2010,7 +2011,7 @@ private AARange _aaToRange(T: V[K], K, V)(ref T aa) pure nothrow @nogc @safe
alias realAA = aa; alias realAA = aa;
else else
const(V[K]) realAA = aa; 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 ...@@ -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 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; auto res = *cast(Key[]*)&a;
_doPostblit(res); _doPostblit(res);
return res; return res;
...@@ -2158,6 +2164,19 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property ...@@ -2158,6 +2164,19 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
return (*aa).keys; 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 * Returns a dynamic array, the elements of which are the values in the
* associative array. * associative array.
...@@ -2168,7 +2187,12 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property ...@@ -2168,7 +2187,12 @@ Key[] keys(T : Value[Key], Value, Key)(T *aa) @property
*/ */
Value[] values(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; auto res = *cast(Value[]*)&a;
_doPostblit(res); _doPostblit(res);
return res; return res;
...@@ -2180,6 +2204,19 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property ...@@ -2180,6 +2204,19 @@ Value[] values(T : Value[Key], Value, Key)(T *aa) @property
return (*aa).values; 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 * Looks up key; if it exists returns corresponding value else evaluates and
* returns defaultValue. * returns defaultValue.
...@@ -2220,12 +2257,12 @@ ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init) ...@@ -2220,12 +2257,12 @@ ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
{ {
auto p = () @trusted 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 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); return found ? *p : (*p = value);
} }
...@@ -2276,12 +2313,12 @@ if (isCreateOperation!(C, V) && isUpdateOperation!(U, V)) ...@@ -2276,12 +2313,12 @@ if (isCreateOperation!(C, V) && isUpdateOperation!(U, V))
{ {
auto p = () @trusted 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 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) if (!found)
*p = create(); *p = create();
...@@ -3879,3 +3916,30 @@ unittest ...@@ -3879,3 +3916,30 @@ unittest
scope arr = [S(&p)]; scope arr = [S(&p)];
auto a = arr.dup; // dup does escape 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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment