Short: Visibility redefinition of a virtual inherit crashes driver
From: Bardioc
Date: 2002-05-30
Type: Bug
State: Done - fixed in 3.2.9-dev.439+440 / 3.3.210+211
Given the following files, the driver crashes when loading "/player":
---------------- living-stats.c -----------------------------------------
#pragma no_clone
private int strength;
public varargs void set_experience(int value, status add) { }
---------------- player-stats.c -----------------------------------------
#pragma no_clone
default private;
virtual inherit "/living-stats";
varargs void set_experience(int value, status add) { }
---------------------- living.c -----------------------------------------
virtual inherit "/living-stats";
---------------------- player.c -----------------------------------------
inherit "/player-stats";
inherit "/living";
-------------------------------------------------------------------------
Problem is that the first inheritance of living-stats::set_experience() is
redefined with a private method; so the second inheritance of that method
causes the compiler to crossdefine the first occurance to the second.
At the same time the code handling the virtual variables found that
living-stats was inherited twice and gave the visible second occurance the
first inherit as environment.
This means we have this inheritance structure:
inherit[0] 'living-stats.c' fun offset 0, var offset 0
inherit[1] 'player-stats.c' fun offset 0, var offset 65535
inherit[2] 'living-stats.c' fun offset 1, var offset 0
inherit[3] 'living.c' fun offset 1, var offset 65535
These functions:
[0] 'set_experience'
flags 94080900 -> 940a0001 (ie: cross defined to function #1)
[1] 'set_experience'
flags 8e000100 -> 8e000000 (ie: inherited from inherit #0)
And these function names:
name [0] 1 'set_experience'
The error is obvious: The visible set_experience() function is inherited from
inherit #2, which holds the proper function index offset; however the compiler
stores it as if it was inherited from inherit #0. Any attempt to resolve the
function will therefore end up with a wrong function index (here: 1 instead of
0) for the original program.
The solution was to modify the inherit-index twiddling in the copy_variables()
method to check if the method is active in the found virtual inherit. If
not, the inherit-index stays as it is. In fact, this check already existed,
but only for the method as it is in the originating program; the check did
not take into account that through the inheritance a visible method might
become cross-defined.