Bug 7335 – sometimes the OUT - block have undefined class members-acces

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2012-01-21T09:21:35Z
Last change time
2019-11-18T16:58:45Z
Assigned to
No Owner
Creator
devbai

Comments

Comment #0 by devbai — 2012-01-21T09:21:35Z
Hallo, there are possible situations, that the OUT-Block of a methode have not the 'exact' value of a member. With other words the members seem to be undefiend. The following programm show to situations. One them the OUT-block have correct acces to the member - onother withot the correct values. here the programm: ************** import std.stdio; class BasisClass { protected int mValue = 10; public void setValue( int newValue) in { writeln("checking IN BasisClass.setValue (do Nothing)"); } out { writeln("checking OUT BasisClass.setValue (value : " , mValue, ")"); assert(mValue < 100 && mValue > -100); // <= assert will pass; because the use newValue in the in-block writeln(" ... passed"); } body { mValue = newValue; } } class SubClassA : BasisClass { override public void setValue( int newValue) in { // will not checked because super.IN-check will pass writeln("checking IN SubClassA.setValue (do Nothing)"); } out { writeln("checking OUT SubClassA.setValue (value : " , mValue, ")"); } body { mValue = newValue; } } class SubClassB : BasisClass { override public void setValue( int newValue) in { // will not checked because super.IN-check will pass writeln("checking IN SubClassB.setValue (do Nothing)"); int a = newValue; //<<<<<<<<<<<< The only diffrence to SubClassA } out { writeln("checking OUT SubClassB.setValue (mValue : " , mValue, ")"); } body { mValue = newValue; } } public static void main () { writeln("*** START ***"); writeln("\nSubClass A:"); BasisClass aObject = new SubClassA(); aObject.setValue(3); writeln("\nSubClass B:"); BasisClass bObject = new SubClassB(); bObject.setValue(3); // <<<<< will crash because undefinet mValue in the // BasisClass.setValue().out-block. writeln("\n*** END ***"); } ************** compilee with DMD64 D Compiler v2.057 will show this output: ************** core.exception.AssertError@TestAppBugNoMembersInOutBlock(13): Assertion failure ---------------- ./(_d_assertm+0x2a) [0x44830a] ./() [0x444e3a] ./(void TestAppBugNoMembersInOutBlock.BasisClass.setValue(int).void __ensure()+0x4d) [0x444c0d] ./(void TestAppBugNoMembersInOutBlock.SubClassB.setValue(int)+0x48) [0x444d14] ./(_Dmain+0x7f) [0x444e07] ./(extern (C) int rt.dmain2.main(int, char**).void runMain()+0x17) [0x44893f] ./(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x4484e6] ./(extern (C) int rt.dmain2.main(int, char**).void runAll()+0x42) [0x448992] ./(extern (C) int rt.dmain2.main(int, char**).void tryExec(scope void delegate())+0x2a) [0x4484e6] ./(main+0xd3) [0x448477] /lib/libc.so.6(__libc_start_main+0xfe) [0x7f85995ecd8e] ---------------- *** START *** SubClass A: checking IN BasisClass.setValue (do Nothing) checking OUT BasisClass.setValue (value : 3) ... passed checking OUT SubClassA.setValue (value : 3) SubClass B: checking IN BasisClass.setValue (do Nothing) checking OUT BasisClass.setValue (value : 1074641200) ************** as seen the ClassB-Out don't have correct acces to the member
Comment #1 by bugzilla — 2012-01-24T14:32:40Z
A somewhat simplified example: ---------------------- import core.stdc.stdio; class A { int mValue = 10; void setValue( int newValue) in { printf("A.setValue.in()\n"); } out { printf("A.setValue.Out(value = %d)\n", mValue); } body { mValue = newValue; } } class B : A { override void setValue( int newValue) in { // not checked because super.IN-check will pass printf("B.setValue.in()\n"); } out { printf("B.setValue.Out(value = %d)\n", mValue); } body { mValue = newValue; } } class C : A { override void setValue( int newValue) in { // not checked because super.IN-check will pass printf("C.setValue.in()\n"); int a = newValue; // The only difference to B } out { printf("C.setValue.Out(value = %d)\n", mValue); } body { mValue = newValue; } } void main() { printf("B:\n"); A aObject = new B(); aObject.setValue(3); printf("\nC:\n"); A bObject = new C(); bObject.setValue(3); // <<<<< will crash because undefined mValue in the // A.setValue().out-block. } -------------------- The output is: B: A.setValue.in() A.setValue.Out(value = 3) B.setValue.Out(value = 3) C: A.setValue.in() A.setValue.Out(value = 9772960) C.setValue.Out(value = 3) ---------------------- I suspect the problem is the stack layout is not correct on the call to A.setValue.in().
Comment #2 by github-bugzilla — 2012-01-24T21:34:28Z
Commit pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/ff560efacfe87778a6e753626a9ade965a361a00 fix Issue 7335 - sometimes the OUT - block have undefined class members-acces
Comment #3 by github-bugzilla — 2012-01-24T21:34:45Z
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/983c58a904e2dd85b8d9b93bf8176c21efd8e18d fix Issue 7335 - sometimes the OUT - block have undefined class members-acces
Comment #4 by bugzilla — 2012-01-24T21:46:28Z
*** Issue 7336 has been marked as a duplicate of this issue. ***
Comment #5 by bugzilla — 2012-01-25T12:38:42Z
*** Issue 7117 has been marked as a duplicate of this issue. ***
Comment #6 by bugzilla — 2012-01-25T12:41:12Z
*** Issue 4648 has been marked as a duplicate of this issue. ***
Comment #7 by bugzilla — 2012-01-25T13:40:21Z
*** Issue 4685 has been marked as a duplicate of this issue. ***
Comment #8 by bugzilla — 2012-01-25T13:41:45Z
*** Issue 6108 has been marked as a duplicate of this issue. ***
Comment #9 by dlang-bot — 2019-11-18T16:58:45Z
dlang/dmd pull request #10353 "Move special handling of __require and __ensure to FuncDeclaration.needsClosure." was merged into master: - 6b3cfc11a19470fddaa24cb0b67cd38096ae6175 by Iain Buclaw: Add test for issue 7335 https://github.com/dlang/dmd/pull/10353