From 851aadcaf4a397f7b70d414c256aa0dfcdde6372 Mon Sep 17 00:00:00 2001 From: Norayr Chilingarian Date: Thu, 9 Jul 2026 23:16:59 +0400 Subject: [PATCH] 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. --- src/compiler/OPB.Mod | 19 ------------------- src/compiler/OPV.Mod | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/compiler/OPB.Mod b/src/compiler/OPB.Mod index 3ff7fffc..718d9b9e 100644 --- a/src/compiler/OPB.Mod +++ b/src/compiler/OPB.Mod @@ -893,25 +893,6 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *) 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.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 *) IF g = OPT.String THEN (*check length of string*) IF ynode^.conval^.intval2 > x^.n THEN err(114) END diff --git a/src/compiler/OPV.Mod b/src/compiler/OPV.Mod index c6b26c05..abe69fdb 100644 --- a/src/compiler/OPV.Mod +++ b/src/compiler/OPV.Mod @@ -798,7 +798,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96 ELSIF r.typ.comp = OPT.DynArr THEN (* Dynamic array to array copy *) 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.WriteInt(l.typ.size+1); (* _X validates 0 .. n-1 so we need top+1. *) OPM.Write(")")