Bug 3731 – Derived class implicitly convertible to base class with arbitrary change of constancy

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-01-20T12:44:00Z
Last change time
2012-07-18T02:59:09Z
Keywords
accepts-invalid, pull
Assigned to
yebblies
Creator
tomeksowi
Blocks
2573

Comments

Comment #0 by tomeksowi — 2010-01-20T12:44:48Z
This merrily compiles: class Zmienna { int a; this(int a) { this.a = a; } } immutable class Stala : Zmienna { this(int a) { super(a); } } void main() { auto st = new Stala(5); Zmienna zm = st; zm.a = 666; // st.a = 666; // fails assert (st.a == 666); } The above shows that an immutable class shouldn't be allowed to derive from mutable classes. Unfortunately it won't work because Object is not (and can't be) immutable. Not sure how to bite this one, perhaps make an opt out that says mutable parents with no fields are OK? Or an exception only for Object?
Comment #1 by schveiguy — 2010-01-21T05:43:28Z
The solution would be to make it illegal to have a mutable class reference to the base class. In your example, this line should be an error: Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna)
Comment #2 by tomeksowi — 2010-01-21T11:03:00Z
(In reply to comment #1) > The solution would be to make it illegal to have a mutable class reference to > the base class. > > In your example, this line should be an error: > > Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna) Thanks, that makes sense.
Comment #3 by yebblies — 2011-06-13T22:59:03Z
Comment #4 by k.hara.pg — 2011-09-16T03:24:37Z
I think issue 3731 is same as issue 5080, and the yebblies patch is a bit better than mine. See also Don and Steven's comments in 5080.
Comment #5 by yebblies — 2011-12-12T21:23:28Z
*** Issue 6863 has been marked as a duplicate of this issue. ***
Comment #6 by github-bugzilla — 2012-01-27T20:24:11Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/7bed81961aefc5327b57be0862514b78d84355db The fix for issue 3731 shows a couple of places in phobos that rely on this bug. std.xml is going away, so work around the issue for now (all problems are caused by opEquals and opCmp not being const correct) and in std.datetime, AA values must be rebindable. https://github.com/D-Programming-Language/phobos/commit/472c2a984391a97fd6fda5b77d082e184b828c87 Merge pull request #408 from yebblies/issue3731 Remove implicit casts to mutable super class
Comment #7 by yebblies — 2012-01-30T18:13:15Z
*** Issue 5080 has been marked as a duplicate of this issue. ***
Comment #8 by code — 2012-03-04T05:19:41Z
*** Issue 7636 has been marked as a duplicate of this issue. ***
Comment #9 by smjg — 2012-03-25T07:52:59Z
(In reply to comment #1) > The solution would be to make it illegal to have a mutable class reference to > the base class. No, because a Zmienna is perfectly allowed to be mutable. It's Stala that isn't. > In your example, this line should be an error: > > Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna) Correct, since because Stala is immutable, any object reference of type Stala is actually of type immutable(Stala). The bug is that constancy is ignored when converting from a derived class to a base class, as this code shows (DMD 2.058, Win32): ---------- class Base { int x; } class Derived : Base { int y; } void main() { Derived md; const(Derived) cd; immutable(Derived) id; Base mb_md = md; const(Base) cb_md = md; immutable(Base) ib_md = md; // accepts-invalid Base mb_cd = cd; // accepts-invalid const(Base) cb_cd = cd; immutable(Base) ib_cd = cd; // accepts-invalid Base mb_id = id; // accepts-invalid const(Base) cb_id = id; immutable(Base) ib_id = id; }
Comment #10 by schveiguy — 2012-03-26T03:11:50Z
(In reply to comment #9) > (In reply to comment #1) > > The solution would be to make it illegal to have a mutable class reference to > > the base class. > > No, because a Zmienna is perfectly allowed to be mutable. It's Stala that > isn't. I think you misunderstand. I don't mean because Stala exists, Zmienna should be prevented from being mutable, even for cases where Stala is not involved. I mean, it should be illegal to have a mutable Stala reference point at a Zmienna.
Comment #11 by smjg — 2012-03-26T03:57:16Z
(In reply to comment #10) > I think you misunderstand. I don't mean because Stala exists, > Zmienna should be prevented from being mutable, even for cases > where Stala is not involved. I mean, it should be illegal to have > a mutable Stala reference point at a Zmienna. I haven't misunderstood. There's no such thing as a mutable Stala reference. Because Stala is an immutable class, any reference to a Stala is automatically immutable. See for yourself: ----- void main() { Stala st = new Stala(5); pragma(msg, typeof(st)); // immutable(Stala) st = new Stala(4); // errors, because st is immutable Zmienna zm = st; // accepts-invalid } ----- The bug is that DMD allows the implicit conversion of immutable(Stala) to Zmienna. It's just mb_id in my last example.
Comment #12 by schveiguy — 2012-03-26T04:13:21Z
(In reply to comment #11) > (In reply to comment #10) > > I think you misunderstand. I don't mean because Stala exists, > > Zmienna should be prevented from being mutable, even for cases > > where Stala is not involved. I mean, it should be illegal to have > > a mutable Stala reference point at a Zmienna. > > I haven't misunderstood. There's no such thing as a mutable Stala reference. Gahh! maybe it's the names in this one :) I meant to say this instead of the last sentence above: "I mean, it should be illegal to have a mutable Zmienna reference point at a Stala" Sorry.
Comment #13 by schveiguy — 2012-04-16T05:30:03Z
*** Issue 7920 has been marked as a duplicate of this issue. ***
Comment #14 by schveiguy — 2012-04-19T04:52:11Z
*** Issue 7939 has been marked as a duplicate of this issue. ***
Comment #15 by github-bugzilla — 2012-07-18T00:08:12Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/65f12c80d383bd655aec1f53510fd4ae201b3b79 Fix Issue 3731 - Can implicitly cast an immutable reference to a derived class to a mutable reference to a base class. Ensure the modifier conversion is valid before allowing an implicit conversion to a base class. https://github.com/D-Programming-Language/dmd/commit/bf982fac38051e34d365d972ff847983cb73848a Merge pull request #125 from yebblies/issue3731 Issue 3731 - Can implicitly cast an immutable reference to a derived class