Skip to content

Commit

Permalink
Merge pull request #3757 from 9rnsr/fix13114
Browse files Browse the repository at this point in the history
Issue 13114 - old opCmp requirement for AA keys should be detected for classes
  • Loading branch information
WalterBright committed Jul 13, 2014
2 parents 2ca83ba + 411fbfe commit 1efe1ad
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/mtype.c
Expand Up @@ -4809,6 +4809,39 @@ printf("index->ito->ito = x%x\n", index->ito->ito);
*/
}
}
else if (tbase->ty == Tclass)
{
ClassDeclaration *cd = ((TypeClass *)tbase)->sym;
if (cd->scope)
cd->semantic(NULL);

if (!ClassDeclaration::object)
{
error(Loc(), "missing or corrupt object.d");
fatal();
}

static FuncDeclaration *feq = NULL;
static FuncDeclaration *fcmp = NULL;
static FuncDeclaration *fhash = NULL;
if (!feq) feq = search_function(ClassDeclaration::object, Id::eq)->isFuncDeclaration();
if (!fcmp) fcmp = search_function(ClassDeclaration::object, Id::cmp)->isFuncDeclaration();
if (!fhash) fhash = search_function(ClassDeclaration::object, Id::tohash)->isFuncDeclaration();
assert(fcmp && feq && fhash);

if (cd->vtbl[feq ->vtblIndex] == feq)
{
#if 1
if (cd->vtbl[fcmp->vtblIndex] != fcmp)
{
const char *s = (index->toBasetype()->ty != Tclass) ? "bottom of " : "";
error(loc, "%sAA key type %s now requires equality rather than comparison",
s, cd->toChars());
errorSupplemental(loc, "Please override Object.opEquals and toHash.");
}
#endif
}
}
next = next->semantic(loc,sc)->merge2();
transitive();

Expand Down
41 changes: 41 additions & 0 deletions test/fail_compilation/diag13074.d
Expand Up @@ -32,3 +32,44 @@ void main()
arr[s3] = true;
arr[s4] = true;
}

/*
TEST_OUTPUT:
---
fail_compilation/diag13074.d(70): Error: AA key type C now requires equality rather than comparison
fail_compilation/diag13074.d(70): Please override Object.opEquals and toHash.
---
*/
class C
{
int x;
int y;
this(int x, int y)
{
this.x = x; this.y = y;
}

override int opCmp(Object other)
{
if (auto o = cast(C)other)
return x < o.x ? -1 : x > o.x ? 1 : 0;
return -1;
}
override hash_t toHash() const
{
return x;
}
}

void test13114()
{
const c1 = new C(1,1);
const c2 = new C(1,2);
const c3 = new C(2,1);
const c4 = new C(2,2);
bool[const(C)] arr;
arr[c1] = true;
arr[c2] = true;
arr[c3] = true;
arr[c4] = true;
}

0 comments on commit 1efe1ad

Please sign in to comment.