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
*** 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