diff --git a/src/func.c b/src/func.c index 7a2d45d94907..8f6b91afab8b 100644 --- a/src/func.c +++ b/src/func.c @@ -177,6 +177,9 @@ void FuncDeclaration::semantic(Scope *sc) if (StructDeclaration *sd = ad->isStructDeclaration()) sd->makeNested(); } + // Remove prefix storage classes silently. + if ((storage_class & STC_TYPECTOR) && !(ad || isNested())) + storage_class &= ~STC_TYPECTOR; //printf("function storage_class = x%llx, sc->stc = x%llx, %x\n", storage_class, sc->stc, Declaration::isFinal()); @@ -227,6 +230,14 @@ void FuncDeclaration::semantic(Scope *sc) sc->linkage = linkage; + if (!tf->isNaked() && !(isThis() || isNested())) + { + OutBuffer buf; + MODtoBuffer(&buf, tf->mod); + error("without 'this' cannot be %s", buf.toChars()); + tf->mod = 0; // remove qualifiers + } + /* Apply const, immutable, wild and shared storage class * to the function type. Do this before type semantic. */ @@ -313,13 +324,6 @@ void FuncDeclaration::semantic(Scope *sc) if (isOverride() && !isVirtual()) error("cannot override a non-virtual function"); - if (!f->isNaked() && !(isThis() || isNested())) - { - OutBuffer buf; - MODtoBuffer(&buf, f->mod); - error("without 'this' cannot be %s", buf.toChars()); - } - if (isAbstract() && isFinal()) error("cannot be both final and abstract"); #if 0 diff --git a/test/compilable/test10150.d b/test/compilable/test10150.d new file mode 100644 index 000000000000..ba6cc5146a5b --- /dev/null +++ b/test/compilable/test10150.d @@ -0,0 +1,36 @@ +// REQUIRED_ARGS: -o- +// PERMUTE_ARGS: + +void foo() {} +alias F = typeof(foo); + +class C +{ + const static void fc() {} + immutable static void fi() {} + inout static void fw() {} + shared static void fs() {} + shared const static void fsc() {} + shared inout static void fsw() {} + + static assert(is(typeof(fc) == F)); + static assert(is(typeof(fi) == F)); + static assert(is(typeof(fw) == F)); + static assert(is(typeof(fs) == F)); + static assert(is(typeof(fsc) == F)); + static assert(is(typeof(fsw) == F)); +} + +const { void fc() {} } +immutable { void fi() {} } +inout { void fw() {} } +shared { void fs() {} } +shared const { void fsc() {} } +shared inout { void fsw() {} } + +static assert(is(typeof(fc) == F)); +static assert(is(typeof(fi) == F)); +static assert(is(typeof(fw) == F)); +static assert(is(typeof(fs) == F)); +static assert(is(typeof(fsc) == F)); +static assert(is(typeof(fsw) == F)); diff --git a/test/fail_compilation/fail9199.d b/test/fail_compilation/fail9199.d index 8ca6d7bb32b0..00a87c39907d 100644 --- a/test/fail_compilation/fail9199.d +++ b/test/fail_compilation/fail9199.d @@ -1,3 +1,4 @@ +// REQUIRED_ARGS: -o- /* TEST_OUTPUT: --- @@ -9,10 +10,31 @@ fail_compilation/fail9199.d(17): Error: function fail9199.fsc without 'this' can fail_compilation/fail9199.d(18): Error: function fail9199.fsw without 'this' cannot be shared inout --- */ - void fc() const {} void fi() immutable {} void fw() inout {} void fs() shared {} void fsc() shared const {} void fsw() shared inout {} + +/* +TEST_OUTPUT: +--- +fail_compilation/fail9199.d(33): Error: function fail9199.C.fc without 'this' cannot be const +fail_compilation/fail9199.d(34): Error: function fail9199.C.fi without 'this' cannot be immutable +fail_compilation/fail9199.d(35): Error: function fail9199.C.fw without 'this' cannot be inout +fail_compilation/fail9199.d(36): Error: function fail9199.C.fs without 'this' cannot be shared +fail_compilation/fail9199.d(37): Error: function fail9199.C.fsc without 'this' cannot be shared const +fail_compilation/fail9199.d(38): Error: function fail9199.C.fsw without 'this' cannot be shared inout +--- +*/ +class C +{ + static void fc() const {} + static void fi() immutable {} + static void fw() inout {} + static void fs() shared {} + static void fsc() shared const {} + static void fsw() shared inout {} +} +