Skip to content

Commit

Permalink
Merge pull request #4091 from 9rnsr/fix12447
Browse files Browse the repository at this point in the history
Issue 12447 & 11915 & 11916 - fix overload resolution issue around IFTI and out parameter
  • Loading branch information
WalterBright committed Oct 26, 2014
2 parents 230356f + f536d3f commit c6289aa
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 29 deletions.
8 changes: 7 additions & 1 deletion src/mtype.c
Expand Up @@ -5873,7 +5873,13 @@ MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
goto Nomatch;
}
else if (p->storageClass & STCout)
{ if (m && !arg->isLvalue())
{
if (m && !arg->isLvalue())
goto Nomatch;

Type *targb = targ->toBasetype();
Type *tprmb = tprm->toBasetype();
if (!targb->constConv(tprmb))
goto Nomatch;
}
}
Expand Down
30 changes: 21 additions & 9 deletions src/template.c
Expand Up @@ -949,10 +949,15 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,

// Resolve parameter types and 'auto ref's.
tf->fargs = fargs;
unsigned olderrors = global.startGagging();
fd->type = tf->semantic(loc, paramscope);
fd->originalType = fd->type; // for mangling
if (fd->type->ty != Tfunction)
if (global.endGagging(olderrors))
{
assert(fd->type->ty != Tfunction);
goto Lnomatch;
}
assert(fd->type->ty == Tfunction);
fd->originalType = fd->type; // for mangling
}

// TODO: dedtypes => ti->tiargs ?
Expand Down Expand Up @@ -2049,7 +2054,7 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
if (tiargs && tiargs->dim > 0)
return 0;

//printf("fd = %s %s\n", fd->toChars(), fd->type->toChars());
//printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars());
m->anyf = fd;
TypeFunction *tf = (TypeFunction *)fd->type;

Expand Down Expand Up @@ -2294,9 +2299,7 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc,
MATCH mta = (MATCH)(x >> 4);
MATCH mfa = (MATCH)(x & 0xF);
//printf("match:t/f = %d/%d\n", mta, mfa);
if (!fd)
goto Lerror;
if (mfa == MATCHnomatch)
if (!fd || mfa == MATCHnomatch)
continue;

Type *tthis_fd = fd->needThis() ? tthis : NULL;
Expand Down Expand Up @@ -2576,14 +2579,23 @@ FuncDeclaration *TemplateDeclaration::doHeaderInstantiation(
tf->next = NULL;
fd->type = tf;
fd->type = fd->type->addSTC(scx->stc);

unsigned olderrors = global.startGagging();
fd->type = fd->type->semantic(fd->loc, scx);
scx = scx->pop();

if (global.endGagging(olderrors))
{
assert(fd->type->ty != Tfunction);
return NULL;
}
assert(fd->type->ty == Tfunction);

fd->originalType = fd->type; // for mangling
//printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod);
//printf("fd->needThis() = %d\n", fd->needThis());

scx = scx->pop();

return fd->type->ty == Tfunction ? fd : NULL;
return fd;
}

bool TemplateDeclaration::hasStaticCtorOrDtor()
Expand Down
19 changes: 0 additions & 19 deletions test/fail_compilation/ice11857.d

This file was deleted.

47 changes: 47 additions & 0 deletions test/runnable/overload.d
Expand Up @@ -1008,6 +1008,51 @@ void test11785()
input.read(v);
}

/***************************************************/
// 11915

int f11915( int) { return 1; }
int f11915(ref int) { return 2; }

int g11915( int) { return 1; }
int g11915(out int) { return 2; }

void test11915()
{
const int n = 1;
assert(f11915(n) == 1);
assert(g11915(n) == 1);
}

/***************************************************/
// 11916

auto f11916(T)( T) { return 1; }
auto f11916(T)(out T) if (false) { return 2; }

auto g11916(T)( T) { return 1; }
auto g11916(T)(out T) { return 2; }

void test11916()
{
const int c = 1;
int m = 2;

// 'out const int' is invalid function parameter, so (out T) version will be dropped
// from overload candidates before template constraint evaluated.
assert(f11916(c) == 1);

// Both (T) and (out T) have valid signatures with T == int, but the 2nd overload will be
// dropped from overload candidates because of the template constraint.
assert(f11916(m) == 1);

// 'out const int' parameter is invalid, so non-out version is selected.
assert(g11916(c) == 1);

// MATCHconst for (T) version, and MATCHexact for (out T) version.
assert(g11916(m) == 2);
}

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

int main()
Expand Down Expand Up @@ -1039,6 +1084,8 @@ int main()
test10658a();
test10658b();
test11785();
test11915();
test11916();

printf("Success\n");
return 0;
Expand Down
15 changes: 15 additions & 0 deletions test/runnable/template9.d
Expand Up @@ -3388,6 +3388,21 @@ void test12376()
enum x = __traits(compiles, encode12376!2(x));
}

/******************************************/
// 12447

enum test12447(string str) = str; // [1]
string test12447(T...)(T args) if (T.length) { return args[0]; } // [2]

// With [1]: The template parameter str cannot be be deduced -> no match
// With [2]: T is deduced to a type tuple (string), then match to the function call.
static assert(test12447("foo") == "foo");

// With [1]: template parameter str is deduced to "bar", then match.
// With [2]: T is deduced to an expression tuple ("bar"), but it will make invalid the function signature (T args).
// The failure should be masked silently and prefer the 1st version.
static assert(test12447!("bar") == "bar");

/******************************************/
// 12651

Expand Down

0 comments on commit c6289aa

Please sign in to comment.