Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -5855,8 +5855,25 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
{
//printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
if (flag)
{
// for partial ordering, value is an irrelevant mockup, just look at the type
m = targ->implicitConvTo(tprm);
#if DMDV2
/* Special rule for partial ordering between bool and non-bool integral types.
* In basic, bool is more specialized than other integers.
* But partial ordering should prefer integer parameters for integer literal arguments.
* So reverse match result in here - bool is less specialized than other integer types.
* See Bugzilla 9999.
*/
Type *tba = targ->toBasetype();
Type *tbp = tprm->toBasetype();
if (tba->ty == Tbool && (tbp->ty != Tbool && tbp->isintegral()))
m = MATCHnomatch;
else if ((tba->ty != Tbool && tba->isintegral()) && tbp->ty == Tbool)
m = MATCHconvert;
else
#endif
m = targ->implicitConvTo(tprm);
}
else
m = arg->implicitConvTo(tprm);
//printf("match %d\n", m);
Expand Down
51 changes: 51 additions & 0 deletions test/runnable/overload.d
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,56 @@ void test9410()
assert(foo(1, S()) == 2); // Fails with: Error: S() is not an lvalue
}

/***************************************************/
// 9999

auto foo9999(bool) { return 1; }
auto foo9999(long) { return 2; }

void test9999()
{
enum int x0 = 0, x1 = 1, x2 = 2;
enum byte b0 = 0, b1 = 1, b2 = 2;

assert(foo9999(true) == 1);
assert(foo9999(false) == 1);
assert(foo9999(0) == 2);
assert(foo9999(1) == 2);
assert(foo9999(2) == 2);
assert(foo9999(x0) == 2);
assert(foo9999(x1) == 2);
assert(foo9999(x2) == 2);
assert(foo9999(b0) == 2);
assert(foo9999(b1) == 2);
assert(foo9999(b2) == 2);
assert(foo9999('\0') == 2);
assert(foo9999('\1') == 2);
assert(foo9999('\2') == 2);

void fooInt(int) {}
void fooLong(long) {}
void fooBool(bool) {}

// bool value matches to integer types
bool f;
fooInt(true);
fooInt(false);
fooInt(f);
fooLong(true);
fooLong(false);
fooLong(f);

// Integer literal 0 and 1 matches to bool
fooBool(0);
fooBool(1);
// from core.stdc.windows.windows
enum : int { FALSE = 0, TRUE = 1 }
fooBool(FALSE);
fooBool(TRUE);
// other integer literals don't match to bool
static assert(!__traits(compiles, fooBool(2)));
}

/***************************************************/

int main()
Expand All @@ -176,6 +226,7 @@ int main()
test8668();
test8943();
test9410();
test9999();

printf("Success\n");
return 0;
Expand Down