[ooc-compiler] Is this allowed?
Brought to you by:
mva
|
From: Stewart G. <sgr...@ip...> - 2001-10-09 06:14:20
|
Hi Folks,
I got some surprising behaviour from OOC. I'm not sure whether this is a bug
or not.
In the following example, Op is a procedure that returns a result and an
error code (like Files.New). If Check finds an error, it prints an error
message and terminates the program.
PROCEDURE Test;
VAR
res : Error;
obj : Object;
BEGIN
obj := Op(-1, res);
Check(res);
obj.Show
END Test;
In the code produced by OOC, the dereference of obj is checked before the
call to Check so the program generates a NIL dereference instead of
terminating in a controlled way.
void TestBug2__Test(void) {
register int i0, i1;
TestBug2__Error res;
i0 = (int)TestBug2__Op((short int)-1, (TestBug2__Error *)(int)&res);
if (!i0) _deref_of_nil(_P(844));
i1 = *(int*)(i0-4);
i1 = (int)((_Type)i1)->tbprocs[0];
TestBug2__Check((TestBug2__Error)(int)res);
((_TBP_TestBug2__ObjectDesc_Show)i1)((TestBug2__Object)i0);
}
Presumably the compiler knows that there is no dependence between Check(res)
and the value of obj. I suppose that the only way around this problem is to
manually insert a dependency. For example, the problem could be reframed as:
IF Check(res) THEN
obj.Show
END;
Is the original transformation legitimate? To me, it seems that checking the
dereference first is disallowing a "side effect" of Check which is the
orderly termination of the program.
A simplified example is attached.
Cheers,
Stewart |