Skip to content

Commit

Permalink
Disallow conflicting parameter strage classes
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Sep 4, 2015
1 parent 8f03ee4 commit 76913e6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 59 deletions.
10 changes: 9 additions & 1 deletion src/mtype.d
Expand Up @@ -5991,8 +5991,16 @@ public:
StorageClass stc = fparam.storageClass | narg.storageClass;
StorageClass stc1 = fparam.storageClass & (STCref | STCout | STClazy);
StorageClass stc2 = narg.storageClass & (STCref | STCout | STClazy);
if (stc1 && stc1 != stc2)
if (stc1 && stc2 && stc1 != stc2)
{
OutBuffer buf1; stcToBuffer(&buf1, stc1 | ((stc1 & STCref) ? (fparam.storageClass & STCauto) : 0));
OutBuffer buf2; stcToBuffer(&buf2, stc2);

error(loc, "incompatible parameter storage classes '%s' and '%s'",
buf1.peekString(), buf2.peekString());
errors = true;
stc = stc1 | (stc & ~(STCref | STCout | STClazy));
}

(*newparams)[j] = new Parameter(
stc, narg.type, narg.ident, narg.defaultArg);
Expand Down
69 changes: 69 additions & 0 deletions test/fail_compilation/fail12744.d
@@ -0,0 +1,69 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail12744.d(38): Error: incompatible parameter storage classes 'ref' and 'out'
fail_compilation/fail12744.d(52): Error: template instance fail12744.bar12744R!(foo12744O) error instantiating
fail_compilation/fail12744.d(38): Error: incompatible parameter storage classes 'ref' and 'lazy'
fail_compilation/fail12744.d(53): Error: template instance fail12744.bar12744R!(foo12744L) error instantiating
fail_compilation/fail12744.d(39): Error: incompatible parameter storage classes 'out' and 'ref'
fail_compilation/fail12744.d(56): Error: template instance fail12744.bar12744O!(foo12744R) error instantiating
fail_compilation/fail12744.d(39): Error: incompatible parameter storage classes 'out' and 'lazy'
fail_compilation/fail12744.d(58): Error: template instance fail12744.bar12744O!(foo12744L) error instantiating
fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes 'lazy' and 'ref'
fail_compilation/fail12744.d(61): Error: template instance fail12744.bar12744L!(foo12744R) error instantiating
fail_compilation/fail12744.d(40): Error: incompatible parameter storage classes 'lazy' and 'out'
fail_compilation/fail12744.d(62): Error: template instance fail12744.bar12744L!(foo12744O) error instantiating
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes 'auto ref' and 'out'
fail_compilation/fail12744.d(67): Error: template fail12744.bar12744A cannot deduce function from argument types !(foo12744O)(int), candidates are:
fail_compilation/fail12744.d(41): fail12744.bar12744A(alias f)(auto ref PTT12744!f args)
fail_compilation/fail12744.d(41): Error: incompatible parameter storage classes 'auto ref' and 'lazy'
fail_compilation/fail12744.d(68): Error: template fail12744.bar12744A cannot deduce function from argument types !(foo12744L)(int), candidates are:
fail_compilation/fail12744.d(41): fail12744.bar12744A(alias f)(auto ref PTT12744!f args)
---
*/
template PTT12744(func...)
{
static if (is(typeof(func[0]) P == function))
alias PTT12744 = P;
else
static assert(0);
}

void foo12744N( int x) {}
void foo12744R( ref int x) {}
void foo12744O( out int x) {}
void foo12744L(lazy int x) {}

void bar12744N(alias f)( PTT12744!f args) {}
void bar12744R(alias f)( ref PTT12744!f args) {}
void bar12744O(alias f)( out PTT12744!f args) {}
void bar12744L(alias f)( lazy PTT12744!f args) {}
void bar12744A(alias f)(auto ref PTT12744!f args) {}

void main()
{
alias bNN = bar12744N!foo12744N;
alias bNR = bar12744N!foo12744R;
alias bNO = bar12744N!foo12744O;
alias bNL = bar12744N!foo12744L;

alias bRN = bar12744R!foo12744N;
alias bRR = bar12744R!foo12744R;
alias bRO = bar12744R!foo12744O; // error
alias bRL = bar12744R!foo12744L; // error

alias bON = bar12744O!foo12744N;
alias bOR = bar12744O!foo12744R; // error
alias bOO = bar12744O!foo12744O;
alias bOL = bar12744O!foo12744L; // error

alias bLN = bar12744L!foo12744N;
alias bLR = bar12744L!foo12744R; // error
alias bLO = bar12744L!foo12744O; // error
alias bLL = bar12744L!foo12744L;

bar12744A!foo12744N(1);
bar12744A!foo12744R(1);
bar12744A!foo12744O(1); // error
bar12744A!foo12744L(1); // error
}
58 changes: 0 additions & 58 deletions test/runnable/functype.d
Expand Up @@ -296,63 +296,6 @@ void test10734()

}

/***************************************************/
// 12744

template PTT12744(func...)
{
static if (is(typeof(func[0]) P == function))
alias PTT12744 = P;
else
static assert(0);
}

void foo12744(int w, ref int x, out int y, lazy int z) {}

void bar12744a()(auto ref PTT12744!foo12744 args) {}
void bar12744b ( ref PTT12744!foo12744 args) {}
void bar12744c ( out PTT12744!foo12744 args) {}
void bar12744d ( lazy PTT12744!foo12744 args) {}
void bar12744e ( PTT12744!foo12744 args) {}

void test12744()
{
int v() { assert(0); }
int w, x, y, z;

// all parameters become 'auto ref'
bar12744a(w, x, y, z);
bar12744a(1, 2, 3, 4);

// all parameters become 'ref'
static assert(is(typeof(&bar12744b) ==
void function(ref int, ref int, ref int, ref int)));
bar12744b(w, x, y, z);
static assert(!__traits(compiles, bar12744b(1, z, y, z)));
static assert(!__traits(compiles, bar12744b(w, 2, y, z)));
static assert(!__traits(compiles, bar12744b(w, z, 3, z)));
static assert(!__traits(compiles, bar12744b(w, z, y, 4)));

// all parameters become 'out'
static assert(is(typeof(&bar12744c) ==
void function(out int, out int, out int, out int)));
w = x = y = z = 1;
bar12744c(w, x, y, z);
assert(!x && !y && !y && !z);
static assert(!__traits(compiles, bar12744c(1, z, y, z)));
static assert(!__traits(compiles, bar12744c(w, 2, y, z)));
static assert(!__traits(compiles, bar12744c(w, z, 3, z)));
static assert(!__traits(compiles, bar12744c(w, z, y, 4)));

// all parameters become 'lazy'
static assert(is(typeof(&bar12744d) ==
void function(lazy int, lazy int, lazy int, lazy int)));
bar12744d(v, v, v, v);

static assert(is(typeof(&bar12744e) ==
void function(int w, ref int x, out int y, lazy int z)));
}

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

Expand Down Expand Up @@ -388,7 +331,6 @@ int main()
test3646();
test3866();
test8579();
test12744();
test14210();
test14656();
test14656_ref();
Expand Down

0 comments on commit 76913e6

Please sign in to comment.