Skip to content

Commit

Permalink
Merge pull request #2071 from 9rnsr/fix10150
Browse files Browse the repository at this point in the history
[enh][REG2.063a] Issue 10150 - Prefix method 'this' qualifiers should be just ignored anytime
  • Loading branch information
WalterBright committed May 24, 2013
2 parents bb9a2a9 + 958abf2 commit 091cb6e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
18 changes: 11 additions & 7 deletions src/func.c
Expand Up @@ -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());

Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions 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));
24 changes: 23 additions & 1 deletion test/fail_compilation/fail9199.d
@@ -1,3 +1,4 @@
// REQUIRED_ARGS: -o-
/*
TEST_OUTPUT:
---
Expand All @@ -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 {}
}

0 comments on commit 091cb6e

Please sign in to comment.