Skip to content
This repository has been archived by the owner on Jun 20, 2019. It is now read-only.

Commit

Permalink
Remove IN_GCC code for xopCmp/xopEquals in compiler and library
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed Dec 31, 2017
1 parent e50fa4c commit 1fc3411
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 22 deletions.
4 changes: 0 additions & 4 deletions gcc/d/dfrontend/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,11 +664,7 @@ FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc)
fop->generated = true;
Expression *e1 = new IdentifierExp(loc, Id::p);
Expression *e2 = new IdentifierExp(loc, Id::q);
#ifdef IN_GCC
Expression *e = new CallExp(loc, new DotIdExp(loc, e1, Id::cmp), e2);
#else
Expression *e = new CallExp(loc, new DotIdExp(loc, e2, Id::cmp), e1);
#endif

fop->fbody = new ReturnStatement(loc, e);

Expand Down
53 changes: 53 additions & 0 deletions gcc/testsuite/gdc.test/runnable/test5854.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
struct S1
{
long x1, x2;

int opCmp(ref const S1 s) const
{
if (x2 - s.x2 != 0)
return x2 < s.x2 ? -1 : 1;

return x1 < s.x1 ? -1 : x1 == s.x1 ? 0 : 1;
}
}

struct S2
{
long x1, x2;

int opCmp(in S2 s) const
{
if (x2 - s.x2 != 0)
return x2 < s.x2 ? -1 : 1;

return x1 < s.x1 ? -1 : x1 == s.x1 ? 0 : 1;
}
}

extern (C) int structcmp(T)(scope T a, scope T b)
{
extern (C) int cmp(scope const void* p1, scope const void* p2, scope void* ti)
{
return (cast(TypeInfo)ti).compare(p1, p2);
}
return cmp(&a, &b, cast(void*)typeid(T));
}

void test5854()
{
alias Tuple(T...) = T;

foreach (T; Tuple!(S1, S2))
{
assert(T(1, 3).structcmp(T(4, 4)) == -1);
assert(T(1, 3).structcmp(T(4, 3)) == -1);
assert(T(4, 3).structcmp(T(4, 3)) == 0);
assert(T(5, 3).structcmp(T(4, 3)) == 1);
assert(T(5, 4).structcmp(T(4, 3)) == 1);
}
}

void main()
{
test5854();
}
35 changes: 17 additions & 18 deletions libphobos/libdruntime/object.d
Original file line number Diff line number Diff line change
Expand Up @@ -1145,12 +1145,7 @@ class TypeInfo_Struct : TypeInfo
return false;
else if (xopEquals)
{
version(GNU)
{ // BUG: GDC and DMD use different calling conventions
return (*xopEquals)(p2, p1);
}
else
return (*xopEquals)(p1, p2);
return (*xopEquals)(p1, p2);
}
else if (p1 == p2)
return true;
Expand All @@ -1171,14 +1166,7 @@ class TypeInfo_Struct : TypeInfo
if (!p2)
return true;
else if (xopCmp)
{
version(GNU)
{ // BUG: GDC and DMD use different calling conventions
return (*xopCmp)(p1, p2);
}
else
return (*xopCmp)(p2, p1);
}
return (*xopCmp)(p1, p2);
else
// BUG: relies on the GC not moving objects
return memcmp(p1, p2, initializer().length);
Expand Down Expand Up @@ -1225,10 +1213,21 @@ class TypeInfo_Struct : TypeInfo

@safe pure nothrow
{
size_t function(in void*) xtoHash;
bool function(in void*, in void*) xopEquals;
int function(in void*, in void*) xopCmp;
string function(in void*) xtoString;
size_t function(in void*) xtoHash;
/* The xopEquals and xopCmp function pointers usually point to the struct's
* opEquals and opCmp methods. If the method doesn't take its single
* argument by reference, the front-end injects a static __xopEquals/
* __xopCmp function (taking 2 arguments, lhs `p` and rhs `q`).
*
* In the method case, lhs `p` is the `this` argument and must be passed
* as first argument before rhs `q`.
* Enforce this arguments order by marking the pointed-to functions as
* using the C calling convention, for which the arguments are never
* reversed (contrary to `extern (D)`).
*/
extern (C) bool function(in void*, in void*) xopEquals;
extern (C) int function(in void*, in void*) xopCmp;
string function(in void*) xtoString;

enum StructFlags : uint
{
Expand Down

0 comments on commit 1fc3411

Please sign in to comment.