Compiler trap in Real64 op ADR(x)

Compiler trap in Real64 op ADR(x)

Postby luowy » Fri Jul 24, 2020 8:33 am

This is an example that leads to a compiler trap:
Code: Select all
MODULE TestBugs;

   IMPORT SYSTEM;
   
   PROCEDURE Do();
      VAR
      r: REAL;
      x: INTEGER;
   BEGIN
      r := r+ SYSTEM.ADR(x);
   END Do;

END TestBugs.
luowy
 
Posts: 72
Joined: Thu Dec 17, 2015 1:32 pm

Re: Compiler trap in Real64 op ADR(x)

Postby adimetrius » Fri Jul 24, 2020 9:24 pm

Suggested temporary fix:
DevCPL486 wrote: PROCEDURE GenFLoad* (VAR src: Item);
VAR f: BYTE; mf: INTEGER;
BEGIN
IF src.mode = Con THEN (* predefined constants *)
DevCPE.GenByte(0D9H); DevCPE.GenByte(0E8H + src.offset)
ELSIF src.form = Int64 THEN
DevCPE.GenByte(0DFH); GenCExt(28H, src)
ELSE
f := src.form; IF src.form = Pointer THEN src.form := Int32 END; CheckForm(src.form, mf); src.form := f;
DevCPE.GenByte(0D9H + mf); GenCExt(0, src)
END
END GenFLoad;


Why:
A simpler offending program is
Code: Select all
VAR r: Real; x: INTEGER;
r := SYSTEM.ADR(x)

The front-end of the compiler inserts a conversion function application because this assignment has an implicit type conversion, and also SYSTEM.ADR is represented as a convertion function application, as well. Thus, after the front-end, this statement looks something like:
r := CONV(CONV(x, Pointer), Real64)
The procedure CheckForm, called from GenFLoad, checks that requested conversion is ok, and traps otherwise.
From looking at the text of CheckForm, my guess is that the possibility of Pointer->Real64 conversion, which is totally permissible under the language rules, was nonetheless forgotten by the authors of CheckForm, being obviously a very rare case.
Code: Select all
   PROCEDURE CheckForm (form: BYTE; VAR mf: INTEGER);
   BEGIN
      IF form = Real32 THEN mf := 0
      ELSIF form = Real64 THEN mf := 4
      ELSIF form = Int32 THEN mf := 2
      ELSE ASSERT(form = Int16); mf := 6
      END
   END CheckForm;

CheckForm is called from many places, so I hesitated to change it; rather, I made a workaround for a more specific case: GenFLoad generates code to load a floating-point value, and my fix tricks CheckForm to think that it's presented with an Int32. If my guess is right, CheckForm might be amended after some testing.

Testing
Here is the simple test I used:
Code: Select all
MODULE TmpLuowy;

   IMPORT SYSTEM;
 
   VAR r, s: REAL; x: INTEGER;

   PROCEDURE Do* ();
   BEGIN
      s := SYSTEM.ADR(x);
      x := SYSTEM.ADR(x);
      r := 0;
      r := r + SYSTEM.ADR(x)
   END Do;

END TmpLuowy.


Here are the global variables after a call to TmpLuowy.Do:
Code: Select all
   .r   REAL   -173993812.0
   .s   REAL   -173993812.0
   .x   INTEGER   -173993812

Looks good to me!
User avatar
adimetrius
 
Posts: 35
Joined: Sun Aug 04, 2019 1:02 pm

Re: Compiler trap in Real64 op ADR(x)

Postby luowy » Sat Jul 25, 2020 12:05 pm

adimetrius wrote:Suggested temporary fix:

thanks your work!
yes, the bug is in the bakckend, your fixup worked well;
I created a discussion post on the center board https://forum.blackboxframework.org/viewtopic.php?f=40&t=790
luowy
 
Posts: 72
Joined: Thu Dec 17, 2015 1:32 pm

Re: Compiler trap in Real64 op ADR(x)

Postby adimetrius » Sat Jul 25, 2020 1:11 pm

:D
User avatar
adimetrius
 
Posts: 35
Joined: Sun Aug 04, 2019 1:02 pm

Re: Compiler trap in Real64 op ADR(x)

Postby luowy » Tue Jul 28, 2020 9:16 am

another choice:
DevCPC486.ConvMove
Code: Select all
    ELSE (* not sysval *) (* int -> float *)
        IF y.form =Pointer THEN y.form:=Int32 END;(*add this line*)         
        IF y.mode = Reg THEN Push(y) END;

or DevCPC486.GetAdr:
Code: Select all
   x.form := Int32(*Pointer*); x.typ := DevCPT.int32typ(*anyptrtyp*);
   Assert(x, hint, stop);

I prefer first one.
luowy
 
Posts: 72
Joined: Thu Dec 17, 2015 1:32 pm

Re: Compiler trap in Real64 op ADR(x)

Postby Robert » Tue Jul 28, 2020 9:46 am

luowy wrote:I created a discussion post on the center board https://forum.blackboxframework.org/viewtopic.php?f=40&t=790


The discussion is now at https://forum.blackboxframework.org/vie ... 7313#p7313 .
User avatar
Robert
 
Posts: 159
Joined: Sat Sep 28, 2013 11:04 am
Location: Edinburgh, Scotland

Re: Compiler trap in Real64 op ADR(x)

Postby adimetrius » Tue Jul 28, 2020 10:55 am

For a permanent correction, why not amend CheckForm?

It would be the most 'straight' logic: CheckForm checks that the format of data is correct. It is correct to convert a Pointer to a Real64, and that't what CheckForm should return. Amending other procedures looks as a workaround to me.
Code: Select all
   PROCEDURE CheckForm (form: BYTE; VAR mf: INTEGER);
   BEGIN
      IF form = Real32 THEN mf := 0
      ELSIF form = Real64 THEN mf := 4
      ELSIF form = Int32 THEN mf := 2
      ELSIF form = Pointer THEN mf := 2       (* this is the addition *)
      ELSE ASSERT(form = Int16); mf := 6
      END
   END CheckForm;


P.S. It seems I can't post at the other discussion page
User avatar
adimetrius
 
Posts: 35
Joined: Sun Aug 04, 2019 1:02 pm

Re: Compiler trap in Real64 op ADR(x)

Postby luowy » Tue Jul 28, 2020 11:11 am

The earlier is the better, the DevCPL is lower than DevCPC,
it's better to correct it whithin the frontend instead of the backend.
This is just my opinion, Not a rule;

adimetrius wrote:P.S. It seems I can't post at the other discussion page
the center forum need a membership, You need to apply for one, you can ask Ivan how to do;
luowy
 
Posts: 72
Joined: Thu Dec 17, 2015 1:32 pm

Re: Compiler trap in Real64 op ADR(x)

Postby adimetrius » Tue Jul 28, 2020 3:52 pm

I'm pretty sure both DevCPL and DevCPC are in the backend.
User avatar
adimetrius
 
Posts: 35
Joined: Sun Aug 04, 2019 1:02 pm

Re: Compiler trap in Real64 op ADR(x)

Postby luowy » Tue Jul 28, 2020 4:15 pm

adimetrius wrote:I'm pretty sure both DevCPL and DevCPC are in the backend.
you are right .
luowy
 
Posts: 72
Joined: Thu Dec 17, 2015 1:32 pm

Next

Return to Bug

Who is online

Users browsing this forum: No registered users and 2 guests