Skip to content

Commit

Permalink
Merge pull request #4729 from 9rnsr/fix14669
Browse files Browse the repository at this point in the history
Issue 14669 - auto attribute on function parameter should be error always
  • Loading branch information
yebblies committed Aug 31, 2015
2 parents d902de1 + fe4e163 commit 2ba1045
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 15 deletions.
2 changes: 2 additions & 0 deletions src/declaration.d
Expand Up @@ -176,6 +176,8 @@ enum STCvolatile = 0x80000000000L;
// destined for volatile in the back end
enum STCreturn = 0x100000000000L;
// 'return ref' for function parameters
enum STCautoref = 0x200000000000L;
// Mark for the already deduced 'auto ref' parameter
extern (C++) __gshared const(StorageClass) STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias | STCout | STCin | STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCnogc | STCpure | STCref | STCtls | STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable);

struct Match
Expand Down
1 change: 1 addition & 0 deletions src/declaration.h
Expand Up @@ -88,6 +88,7 @@ enum PINLINE;
#define STCnogc 0x40000000000LL // @nogc
#define STCvolatile 0x80000000000LL // destined for volatile in the back end
#define STCreturn 0x100000000000LL // 'return ref' for function parameters
#define STCautoref 0x200000000000LL // Mark for the already deduced 'auto ref' parameter

const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias |
Expand Down
19 changes: 11 additions & 8 deletions src/dtemplate.d
Expand Up @@ -6287,19 +6287,22 @@ public:
/* Template functions may have different instantiations based on
* "auto ref" parameters.
*/
if (fargs)
if (auto fd = ti.toAlias().isFuncDeclaration())
{
FuncDeclaration fd = ti.toAlias().isFuncDeclaration();
if (fd && !fd.errors)
if (!fd.errors)
{
Parameters* fparameters = fd.getParameters(null);
size_t nfparams = Parameter.dim(fparameters); // Num function parameters
for (size_t j = 0; j < nfparams && j < fargs.dim; j++)
auto fparameters = fd.getParameters(null);
size_t nfparams = Parameter.dim(fparameters); // Num function parameters
for (size_t j = 0; j < nfparams; j++)
{
Parameter fparam = Parameter.getNth(fparameters, j);
Expression farg = (*fargs)[j];
if (fparam.storageClass & STCauto) // if "auto ref"
if (fparam.storageClass & STCautoref) // if "auto ref"
{
if (!fargs)
goto Lnotequals;
if (fargs.dim <= j)
break;
Expression farg = (*fargs)[j];
if (farg.isLvalue())
{
if (!(fparam.storageClass & STCref))
Expand Down
3 changes: 2 additions & 1 deletion src/expression.d
Expand Up @@ -1522,7 +1522,8 @@ extern (C++) bool functionParameters(Loc loc, Scope* sc, TypeFunction tf, Type t
}
if (p.storageClass & STCref)
{
if (p.storageClass & STCauto && (arg.op == TOKthis || arg.op == TOKsuper))
if (p.storageClass & STCautoref &&
(arg.op == TOKthis || arg.op == TOKsuper))
{
// suppress deprecation message for auto ref parameter
// temporary workaround for Bugzilla 14283
Expand Down
9 changes: 5 additions & 4 deletions src/mtype.d
Expand Up @@ -250,8 +250,7 @@ extern (C++) Type stripDefaultArgs(Type t)
for (size_t j = 0; j < params.dim; j++)
(*params)[j] = (*parameters)[j];
}
StorageClass stc = p.storageClass & (~STCauto); // issue 14656
(*params)[i] = new Parameter(stc, ta, null, null);
(*params)[i] = new Parameter(p.storageClass, ta, null, null);
}
}
}
Expand Down Expand Up @@ -6001,7 +6000,7 @@ public:
*/
if (fparam.storageClass & STCauto)
{
if (fargs && i < fargs.dim)
if (fargs && i < fargs.dim && (fparam.storageClass & STCref))
{
Expression farg = (*fargs)[i];
if (farg.isLvalue())
Expand All @@ -6010,10 +6009,12 @@ public:
}
else
fparam.storageClass &= ~STCref; // value parameter
fparam.storageClass &= ~STCauto; // issue 14656
fparam.storageClass |= STCautoref;
}
else
{
error(loc, "auto can only be used for template function parameters");
error(loc, "'auto' can only be used as part of 'auto ref' for template function parameters");
errors = true;
}
}
Expand Down
43 changes: 43 additions & 0 deletions test/fail_compilation/fail14669.d
@@ -0,0 +1,43 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail14669.d(11): Error: 'auto' can only be used as part of 'auto ref' for template function parameters
fail_compilation/fail14669.d(16): Error: template instance fail14669.foo1!() error instantiating
fail_compilation/fail14669.d(12): Error: 'auto' can only be used as part of 'auto ref' for template function parameters
fail_compilation/fail14669.d(17): Error: template fail14669.foo2 cannot deduce function from argument types !()(int), candidates are:
fail_compilation/fail14669.d(12): fail14669.foo2()(auto int a)
---
*/
void foo1()(auto int a) {}
void foo2()(auto int a) {}

void test1()
{
alias f1 = foo1!();
foo2(1);
}

/*
TEST_OUTPUT:
---
fail_compilation/fail14669.d(29): Error: 'auto' can only be used as part of 'auto ref' for template function parameters
fail_compilation/fail14669.d(38): Error: template instance fail14669.bar1!int error instantiating
fail_compilation/fail14669.d(30): Error: 'auto' can only be used as part of 'auto ref' for template function parameters
fail_compilation/fail14669.d(40): Error: template instance fail14669.bar2!int error instantiating
---
*/
void bar1(T)(auto ref T x) {}
void bar2(T)(auto ref T x) {}

void test2()
{
int n;

bar1(1);
bar1(n);
alias b1 = bar1!(int);

alias b2 = bar2!(int);
bar2(n);
bar2(1);
}
7 changes: 5 additions & 2 deletions test/runnable/functype.d
Expand Up @@ -296,11 +296,14 @@ void test10734()

}

/***************************************************/
// 14656

void test14656()
{
void unaryFun()(auto int a) pure nothrow @safe @nogc {}
//void unaryFun()(auto int a) pure nothrow @safe @nogc {} // changed to invalid by fixing issue 14669
alias Identity(F) = F;
unaryFun!()(41);
//unaryFun!()(41);
static void fun(int n) pure nothrow @safe @nogc {}
alias F = typeof(fun);
assert(Identity!F.stringof == "pure nothrow @nogc @safe void(int)");
Expand Down

0 comments on commit 2ba1045

Please sign in to comment.