fixing compiler crash on dynamic array to static array assignment

the crash was introduced in aed9134e: when the rhs of an array assignment
is a pointer-dereferenced dynamic array (e.g. s^), the rhs node has no
named obj, so obj is nil. the dynArr branch in OPV was calling OPC.Len
which dereferences obj immediately, causing a segfault in the compiler.

OPV already has a Len() procedure that handles Nderef nodes by generating
ptr->len[dim] instead of relying on a named obj. switching to that call
fixes the crash and generates correct bounds-checked C code.

removing the err(113) workaround in OPB.CheckAssign that was suppressing
the crash by rejecting valid oberon-07 assignments.

fixes issue #55.
This commit is contained in:
Norayr Chilingarian 2026-07-09 23:16:59 +04:00
parent 7ffdb0859b
commit 851aadcaf4
2 changed files with 1 additions and 20 deletions

View file

@ -893,25 +893,6 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
IF x = y THEN (* ok *) IF x = y THEN (* ok *)
ELSIF (y.comp = OPT.Array) & (y.BaseTyp = x.BaseTyp) & (y.n <= x.n) THEN (* OK by Oberon-07/2013 *) ELSIF (y.comp = OPT.Array) & (y.BaseTyp = x.BaseTyp) & (y.n <= x.n) THEN (* OK by Oberon-07/2013 *)
ELSIF (y.comp = OPT.DynArr) & (y.BaseTyp = x.BaseTyp) THEN (* OK by Oberon-07/2013, length tested at runtime *) ELSIF (y.comp = OPT.DynArr) & (y.BaseTyp = x.BaseTyp) THEN (* OK by Oberon-07/2013, length tested at runtime *)
err(113)
(* if no error issued the compiler will crash later
in OPC.CompleteIdent because NIL will be passed to it
from OPC.Len
which is called from OPV.stat
OPV.stat gets n: OPT.node
where both n^.left.obj and n^.right.obj are NIL.
n^.right.obj is then passed to OPC.Len
at this point, in this ELSIF body
x^.comp = OPT.Array
x^.strobj.name=
y^.strobj is NIL already!
it's interesting that OPT.InStruct functions
Sarr case is entered, but not Sdarr
issuing error for now to eliminate compiler crash.
*)
ELSIF x^.BaseTyp = OPT.chartyp THEN (* Assign to (static) ARRAY OF CHAR *) ELSIF x^.BaseTyp = OPT.chartyp THEN (* Assign to (static) ARRAY OF CHAR *)
IF g = OPT.String THEN (*check length of string*) IF g = OPT.String THEN (*check length of string*)
IF ynode^.conval^.intval2 > x^.n THEN err(114) END IF ynode^.conval^.intval2 > x^.n THEN err(114) END

View file

@ -798,7 +798,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
ELSIF r.typ.comp = OPT.DynArr THEN ELSIF r.typ.comp = OPT.DynArr THEN
(* Dynamic array to array copy *) (* Dynamic array to array copy *)
OPM.WriteString("__X("); OPM.WriteString("__X(");
OPC.Len(r.obj, r.typ, 0); OPM.WriteString(" * "); OPM.WriteInt(r.typ.BaseTyp.size); Len(r, 0); OPM.WriteString(" * "); OPM.WriteInt(r.typ.BaseTyp.size);
OPM.WriteString(", "); OPM.WriteString(", ");
OPM.WriteInt(l.typ.size+1); (* _X validates 0 .. n-1 so we need top+1. *) OPM.WriteInt(l.typ.size+1); (* _X validates 0 .. n-1 so we need top+1. *)
OPM.Write(")") OPM.Write(")")