Skip to content

Commit

Permalink
Merge pull request #5032 from 9rnsr/fix12744
Browse files Browse the repository at this point in the history
Issue 12744 - auto ref crashes DMD on ASSERT
  • Loading branch information
WalterBright committed Sep 4, 2015
2 parents 68650c1 + 76913e6 commit 37ee74a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/mtype.d
Expand Up @@ -5884,10 +5884,12 @@ public:
error(loc, "cannot have parameter of function type %s", fparam.type.toChars());
errors = true;
}
else if (!(fparam.storageClass & (STCref | STCout)) && (t.ty == Tstruct || t.ty == Tsarray || t.ty == Tenum))
else if (!(fparam.storageClass & (STCref | STCout)) &&
(t.ty == Tstruct || t.ty == Tsarray || t.ty == Tenum))
{
Type tb2 = t.baseElemOf();
if (tb2.ty == Tstruct && !(cast(TypeStruct)tb2).sym.members || tb2.ty == Tenum && !(cast(TypeEnum)tb2).sym.memtype)
if (tb2.ty == Tstruct && !(cast(TypeStruct)tb2).sym.members ||
tb2.ty == Tenum && !(cast(TypeEnum)tb2).sym.memtype)
{
error(loc, "cannot have parameter of opaque type %s by value", fparam.type.toChars());
errors = true;
Expand Down Expand Up @@ -5983,7 +5985,25 @@ public:
for (size_t j = 0; j < tdim; j++)
{
Parameter narg = (*tt.arguments)[j];
(*newparams)[j] = new Parameter(narg.storageClass | fparam.storageClass, narg.type, narg.ident, narg.defaultArg);

// Bugzilla 12744: If the storage classes of narg
// conflict with the ones in fparam, it's ignored.
StorageClass stc = fparam.storageClass | narg.storageClass;
StorageClass stc1 = fparam.storageClass & (STCref | STCout | STClazy);
StorageClass stc2 = narg.storageClass & (STCref | STCout | STClazy);
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);
}
fparam.type = new TypeTuple(newparams);
}
Expand All @@ -6009,7 +6029,7 @@ public:
}
else
fparam.storageClass &= ~STCref; // value parameter
fparam.storageClass &= ~STCauto; // issue 14656
fparam.storageClass &= ~STCauto; // Bugzilla 14656
fparam.storageClass |= STCautoref;
}
else
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
}

0 comments on commit 37ee74a

Please sign in to comment.