From 4af52deaba5a24130695a48c132f8e7d46236859 Mon Sep 17 00:00:00 2001 From: k-hara Date: Mon, 9 Sep 2013 14:54:27 +0900 Subject: [PATCH] fix Issue 10980 - static initialization of immutable structs with disabled postblit fails --- src/declaration.c | 21 ++++----------- test/fail_compilation/fail10980.d | 44 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 test/fail_compilation/fail10980.d diff --git a/src/declaration.c b/src/declaration.c index e2cd17fc4141..760d84b7ed28 100644 --- a/src/declaration.c +++ b/src/declaration.c @@ -1657,28 +1657,17 @@ void VarDeclaration::semantic(Scope *sc) * because the postblit doesn't get run on the initialization of w. */ if (ti->ty == Tstruct) - { StructDeclaration *sd = ((TypeStruct *)ti)->sym; + { + StructDeclaration *sd = ((TypeStruct *)ti)->sym; /* Look to see if initializer involves a copy constructor * (which implies a postblit) */ if (sd->cpctor && // there is a copy constructor - tb->equals(ti)) // rvalue is the same struct + tb->toDsymbol(NULL) == sd) // exp is the same struct { // The only allowable initializer is a (non-copy) constructor - if (exp->op == TOKcall) - { - CallExp *ce = (CallExp *)exp; - if (ce->e1->op == TOKdotvar) - { - DotVarExp *dve = (DotVarExp *)ce->e1; - if (dve->var->isCtorDeclaration()) - goto LNoCopyConstruction; - } - } - error("of type struct %s uses this(this), which is not allowed in static initialization", tb->toChars()); - - LNoCopyConstruction: - ; + if (exp->isLvalue()) + error("of type struct %s uses this(this), which is not allowed in static initialization", tb->toChars()); } } ei->exp = exp; diff --git a/test/fail_compilation/fail10980.d b/test/fail_compilation/fail10980.d new file mode 100644 index 000000000000..eb50de34ebe0 --- /dev/null +++ b/test/fail_compilation/fail10980.d @@ -0,0 +1,44 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail10980.d(22): Error: variable fail10980.s1b of type struct immutable(S1) uses this(this), which is not allowed in static initialization +fail_compilation/fail10980.d(28): Error: variable fail10980.s1d of type struct immutable(S1) uses this(this), which is not allowed in static initialization +fail_compilation/fail10980.d(27): Error: static variable s1x cannot be read at compile time +fail_compilation/fail10980.d(28): called from here: bar1() +fail_compilation/fail10980.d(38): Error: variable fail10980.s2b of type struct immutable(S2) uses this(this), which is not allowed in static initialization +fail_compilation/fail10980.d(44): Error: variable fail10980.s2d of type struct immutable(S2) uses this(this), which is not allowed in static initialization +fail_compilation/fail10980.d(43): Error: static variable s2x cannot be read at compile time +fail_compilation/fail10980.d(44): called from here: bar2() +--- +*/ + +struct S1 +{ + this(int) immutable {} + this(this) {} +} +alias immutable(S1) IS1; +static immutable S1 s1a = IS1(1); // OK +static immutable S1 s1b = s1a; // NG + +S1 foo1() { S1 s1x; S1 s1y = s1x; return s1y; } +static immutable S1 s1c = foo1(); // OK + +ref S1 bar1() { static S1 s1x; return s1x; } +static immutable S1 s1d = bar1(); // NG + + +struct S2 +{ + int val; + this(this) {} +} +alias immutable(S2) IS2; +static immutable S2 s2a = IS2(1); // OK +static immutable S2 s2b = s2a; // NG + +S2 foo2() { S2 s2x; S2 s2y = s2x; return s2y; } +static immutable S2 s2c = foo2(); // OK + +ref S2 bar2() { static S2 s2x; return s2x; } +static immutable S2 s2d = bar2(); // NG