Skip to content

Commit

Permalink
fix Issue 3449 - const and invariant struct members do not behave acc…
Browse files Browse the repository at this point in the history
…ording to spec
  • Loading branch information
9rnsr committed Oct 5, 2014
1 parent 3a44a88 commit cc2e825
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 57 deletions.
24 changes: 9 additions & 15 deletions src/declaration.c
Expand Up @@ -1112,22 +1112,18 @@ void VarDeclaration::semantic(Scope *sc)
AggregateDeclaration *aad = parent->isAggregateDeclaration();
if (aad)
{
if (storage_class & (STCconst | STCimmutable) && init && !init->isVoidInitializer())
if (global.params.vfield &&
storage_class & (STCconst | STCimmutable) && init && !init->isVoidInitializer())
{
StorageClass stc = storage_class & (STCconst | STCimmutable);
deprecation(loc, "%s field with initializer should be static, __gshared, or an enum",
StorageClassDeclaration::stcToChars(NULL, stc));
if (!tb->isTypeBasic())
storage_class |= STCstatic;
const char *p = loc.toChars();
const char *s = (storage_class & STCimmutable) ? "immutable" : "const";
fprintf(global.stdmsg, "%s: %s.%s is %s field\n", p ? p : "", ad->toPrettyChars(), toChars(), s);
}
else
storage_class |= STCfield;
if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor)
{
storage_class |= STCfield;
if ((tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor))
{
if (!isThisDeclaration() && !init)
aad->noDefaultCtor = true;
}
if (!isThisDeclaration() && !init)
aad->noDefaultCtor = true;
}
}

Expand Down Expand Up @@ -1677,8 +1673,6 @@ AggregateDeclaration *VarDeclaration::isThis()
if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter |
STCtls | STCgshared | STCctfe)))
{
if ((storage_class & (STCconst | STCimmutable | STCwild)) && init)
return NULL;
for (Dsymbol *s = this; s; s = s->parent)
{
ad = s->isMember();
Expand Down
13 changes: 8 additions & 5 deletions src/expression.c
Expand Up @@ -7331,16 +7331,19 @@ Expression *DotVarExp::semantic(Scope *sc)
accessCheck(loc, sc, e1, var);

VarDeclaration *v = var->isVarDeclaration();
Expression *e = expandVar(WANTvalue, v);
if (e)
return e;
if (v && (v->isDataseg() || (v->storage_class & STCmanifest)))
{
Expression *e = expandVar(WANTvalue, v);
if (e)
return e;
}

if (v && v->isDataseg()) // fix bugzilla 8238
{
// (e1, v)
accessCheck(loc, sc, e1, v);
VarExp *ve = new VarExp(loc, v);
e = new CommaExp(loc, e1, ve);
Expression *e = new VarExp(loc, v);
e = new CommaExp(loc, e1, e);
e = e->semantic(sc);
return e;
}
Expand Down
5 changes: 4 additions & 1 deletion src/mars.c
Expand Up @@ -630,7 +630,8 @@ int tryMain(size_t argc, const char *argv[])
{
printf("\
Language changes listed by -transition=id:\n\
=tls do list all variables going into thread local storage\n\
=field,3449 list all non-mutable fields which occupy an object instance\n\
=tls list all variables going into thread local storage\n\
");
return EXIT_FAILURE;
}
Expand All @@ -655,6 +656,8 @@ Language changes listed by -transition=id:\n\
{
if (strcmp(p + 12, "tls") == 0)
global.params.vtls = 1;
if (strcmp(p + 12, "field") == 0)
global.params.vfield = 1;
}
else
goto Lerror;
Expand Down
6 changes: 1 addition & 5 deletions test/compilable/sw_transition_field.d
Expand Up @@ -3,17 +3,13 @@
/*
TEST_OUTPUT:
---
---
*/
/*
---
compilable/sw_transition_field.d(15): sw_transition_field.S1.ix is immutable field
compilable/sw_transition_field.d(16): sw_transition_field.S1.cx is const field
compilable/sw_transition_field.d(21): sw_transition_field.S2!(immutable(int)).S2.f is immutable field
compilable/sw_transition_field.d(21): sw_transition_field.S2!(const(int)).S2.f is const field
---
*/
// REQUIRED_ARGS: -d

struct S1
{
immutable int ix = 1;
Expand Down
3 changes: 1 addition & 2 deletions test/fail_compilation/ice12827.d
@@ -1,8 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice12827.d(11): Deprecation: variable ice12827.Test.i immutable field with initializer should be static, __gshared, or an enum
fail_compilation/ice12827.d(11): Error: circular initialization of i
fail_compilation/ice12827.d(10): Error: circular initialization of i
---
*/

Expand Down
5 changes: 1 addition & 4 deletions test/runnable/test3449.d
Expand Up @@ -2,8 +2,6 @@
/******************************************/
// 3449

version (PULL93)
{
template TypeTuple(T...) { alias TypeTuple = T; }

// If module variable has no explicit initializer,
Expand Down Expand Up @@ -89,7 +87,6 @@ void test3449()
assert(s2.field2 == 10);
}
}
}

/******************************************/
// 10643
Expand All @@ -109,7 +106,7 @@ static assert(S10643.sizeof == int.sizeof * 1000);

int main()
{
version(PULL93) test3449();
test3449();

return 0;
}
25 changes: 0 additions & 25 deletions test/runnable/testconst.d
Expand Up @@ -533,16 +533,8 @@ struct S40

void test40()
{
version (PULL93)
{
assert(S40.sizeof == 8);
assert(S40.init.b == 3);
}
else
{
assert(S40.sizeof == 4);
assert(S40.b == 3);
}
}

/************************************/
Expand Down Expand Up @@ -574,14 +566,7 @@ class C42
{
int a = ctfe() - 2;
const int b;
version (PULL93)
{
enum int c = ctfe();
}
else
{
const int c = ctfe();
}
static const int d;
static const int e = ctfe() + 2;

Expand All @@ -599,14 +584,7 @@ class C42
void test42()
{
printf("%d\n", C42.classinfo.init.length);
version (PULL93)
{
assert(C42.classinfo.init.length == 12 + (void*).sizeof + (void*).sizeof);
}
else
{
assert(C42.classinfo.init.length == 8 + (void*).sizeof + (void*).sizeof);
}
C42 c = new C42;
assert(c.a == 1);
assert(c.b == 2);
Expand All @@ -617,11 +595,8 @@ void test42()
const(int)*p;
p = &c.b;
assert(*p == 2);
version (PULL93)
{
p = &c.c;
assert(*p == 3);
}
p = &c.d;
assert(*p == 4);
p = &c.e;
Expand Down

0 comments on commit cc2e825

Please sign in to comment.