From 8f03ee45f9df1a0fdcca492cac575ab0d0b3fff0 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 3 Sep 2015 18:53:06 +0900 Subject: [PATCH] fix Issue 12744 - auto ref crashes DMD on ASSERT --- src/mtype.d | 20 +++++++++++--- test/runnable/functype.d | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/mtype.d b/src/mtype.d index ea3a6f377bc0..c98a96ee2ae9 100644 --- a/src/mtype.d +++ b/src/mtype.d @@ -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; @@ -5983,7 +5985,17 @@ 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 && stc1 != stc2) + stc = stc1 | (stc & ~(STCref | STCout | STClazy)); + + (*newparams)[j] = new Parameter( + stc, narg.type, narg.ident, narg.defaultArg); } fparam.type = new TypeTuple(newparams); } @@ -6009,7 +6021,7 @@ public: } else fparam.storageClass &= ~STCref; // value parameter - fparam.storageClass &= ~STCauto; // issue 14656 + fparam.storageClass &= ~STCauto; // Bugzilla 14656 fparam.storageClass |= STCautoref; } else diff --git a/test/runnable/functype.d b/test/runnable/functype.d index 8030545ab79a..ddde438ee1ef 100644 --- a/test/runnable/functype.d +++ b/test/runnable/functype.d @@ -296,6 +296,63 @@ 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 @@ -331,6 +388,7 @@ int main() test3646(); test3866(); test8579(); + test12744(); test14210(); test14656(); test14656_ref();