Skip to content

Commit

Permalink
Merge pull request #4714 from 9rnsr/fix2091
Browse files Browse the repository at this point in the history
Issue 2091 - D2 final cannot be applied to variable
  • Loading branch information
WalterBright committed Jun 23, 2015
2 parents d66bf4d + 397752b commit b9864b4
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 162 deletions.
89 changes: 0 additions & 89 deletions src/attrib.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,95 +394,6 @@ Scope *StorageClassDeclaration::newScope(Scope *sc)
return createNewScope(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign, sc->inlining);
}

/*************************************************
* Pick off one of the storage classes from stc,
* and return a pointer to a string representation of it.
* stc is reduced by the one picked.
* tmp[] is a buffer big enough to hold that string.
*/
const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
{
struct SCstring
{
StorageClass stc;
TOK tok;
const char *id;
};

static SCstring table[] =
{
{ STCauto, TOKauto },
{ STCscope, TOKscope },
{ STCstatic, TOKstatic },
{ STCextern, TOKextern },
{ STCconst, TOKconst },
{ STCfinal, TOKfinal },
{ STCabstract, TOKabstract },
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
{ STCoverride, TOKoverride },
{ STClazy, TOKlazy },
{ STCalias, TOKalias },
{ STCout, TOKout },
{ STCin, TOKin },
{ STCmanifest, TOKenum },
{ STCimmutable, TOKimmutable },
{ STCshared, TOKshared },
{ STCnothrow, TOKnothrow },
{ STCwild, TOKwild },
{ STCpure, TOKpure },
{ STCref, TOKref },
{ STCtls },
{ STCgshared, TOKgshared },
{ STCnogc, TOKat, "nogc" },
{ STCproperty, TOKat, "property" },
{ STCsafe, TOKat, "safe" },
{ STCtrusted, TOKat, "trusted" },
{ STCsystem, TOKat, "system" },
{ STCdisable, TOKat, "disable" },
{ 0, TOKreserved }
};

for (int i = 0; table[i].stc; i++)
{
StorageClass tbl = table[i].stc;
assert(tbl & STCStorageClass);
if (stc & tbl)
{
stc &= ~tbl;
if (tbl == STCtls) // TOKtls was removed
return "__thread";

TOK tok = table[i].tok;
if (tok == TOKat)
{
tmp[0] = '@';
strcpy(tmp + 1, table[i].id);
return tmp;
}
else
return Token::toChars(tok);
}
}
//printf("stc = %llx\n", (unsigned long long)stc);
return NULL;
}

void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
{
while (stc)
{
const size_t BUFFER_LEN = 20;
char tmp[BUFFER_LEN];
const char *p = stcToChars(tmp, stc);
if (!p)
break;
assert(strlen(p) < BUFFER_LEN);
buf->writestring(p);
buf->writeByte(' ');
}
}

/********************************* DeprecatedDeclaration ****************************/

DeprecatedDeclaration::DeprecatedDeclaration(Expression *msg, Dsymbols *decl)
Expand Down
2 changes: 0 additions & 2 deletions src/attrib.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ class StorageClassDeclaration : public AttribDeclaration
Scope *newScope(Scope *sc);
bool oneMember(Dsymbol **ps, Identifier *ident);

static const char *stcToChars(char tmp[], StorageClass& stc);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
void accept(Visitor *v) { v->visit(this); }
};

Expand Down
33 changes: 14 additions & 19 deletions src/declaration.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "statement.h"
#include "ctfe.h"
#include "target.h"
#include "hdrgen.h"

/************************************
* Check to see the aggregate type is nested and its context pointer is
Expand Down Expand Up @@ -826,9 +827,10 @@ void VarDeclaration::semantic(Scope *sc)
scope = NULL;
}

/* Pick up storage classes from context, but skip synchronized
/* Pick up storage classes from context, but except synchronized,
* override, abstract, and final.
*/
storage_class |= (sc->stc & ~STCsynchronized);
storage_class |= (sc->stc & ~(STCsynchronized | STCoverride | STCabstract | STCfinal));
if (storage_class & STCextern && init)
error("extern symbols cannot have initializers");

Expand Down Expand Up @@ -1133,24 +1135,17 @@ void VarDeclaration::semantic(Scope *sc)
else if (type->isWild())
storage_class |= STCwild;

if (storage_class & (STCmanifest | STCstatic | STCgshared))
if (StorageClass stc = storage_class & (STCsynchronized | STCoverride | STCabstract | STCfinal))
{
}
else if (isSynchronized())
{
error("variable %s cannot be synchronized", toChars());
}
else if (isOverride())
{
error("override cannot be applied to variable");
}
else if (isAbstract())
{
error("abstract cannot be applied to variable");
}
else if (storage_class & STCfinal)
{
error("final cannot be applied to variable, perhaps you meant const?");
if (stc == STCfinal)
error("cannot be final, perhaps you meant const?");
else
{
OutBuffer buf;
stcToBuffer(&buf, stc);
error("cannot be %s", buf.peekString());
}
storage_class &= ~stc; // strip off
}

if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
Expand Down
Loading

0 comments on commit b9864b4

Please sign in to comment.