VAR [nil] for tagged structural parameters

Post Reply
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

VAR [nil] for tagged structural parameters

Post by Zorko »

It is now possible to declare the following parameter:

Code: Select all

MODULE Win; IMPORT SYSTEM;

PROCEDURE Proc (VAR [nil] lpModuleName: ARRAY OF CHAR);
END Proc;

BEGIN
  Proc(NIL)
END Win.
But this makes no sense, since ARRAY is not an untagged pointer, it is a tagged structure with length storage. The same about RECORDs.

How it works, or rather, does not work:

Image

The error is really caught inside DevOPC, and that's very good, but it's the wrong level. It should be caught at the moment of declaration in DevOPP.FormalParameters procedure. The suggested fix:

Image

The result of its work:

Image
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

Re: VAR [nil] for tagged structural parameters

Post by Zorko »

Refinement of corrections (we need to additionally check the tagging of a structure):

Code: Select all

		ELSIF (sys # 0) & ((typ.comp = Record) OR (typ.comp = DynArr)) & ~typ.untagged THEN err(142)
Zorko
Posts: 26
Joined: Tue Sep 17, 2013 10:13 pm
Location: Ukraine
Contact:

Re: VAR [nil] for tagged structural parameters

Post by Zorko »

After this fix, I found one entry in the module WinApi:

Code: Select all

PROCEDURE [stdcall] SetDIBColorTable* (p0: HDC; p1: INTEGER; p2: INTEGER; VAR [nil] p3: ARRAY OF RGBQUAD): INTEGER;
Where RGBQUAD is an untagged record, but p3 is an open tagged array with the length passed to the procedure inside.

For array as a VAR parameter, passed does not actually one value, but two: the array address and its length. Can you tell exactly what will be passed as length if you pass NIL here?

Code: Select all

SetDIBColorTable(0, 1, 2, NIL);
To avoid such an undefined behavior, I propose to redeclare it this way:

Code: Select all

PROCEDURE [stdcall] SetDIBColorTable* (p0: HDC; p1: INTEGER; p2: INTEGER; p3: POINTER TO ARRAY [untagged] OF RGBQUAD): INTEGER;
So, my fix has already helped find one problem and a potential source of errors.
User avatar
adimetrius
Posts: 68
Joined: Sun Aug 04, 2019 1:02 pm

Re: VAR [nil] for tagged structural parameters

Post by adimetrius »

Moving the check up to the front-end of the compiler sounds like a good idea to me.

SetDIBColorTable is definitely a mistake:

PROCEDURE SetDIBColorTable (p0: WinApi.HDC; p1, p2: INTEGER; VAR [nil] p3: ARRAY OF WinApi.RGBQUAD): INTEGER;
UINT SetDIBColorTable(
[in] HDC hdc,
[in] UINT iStart,
[in] UINT cEntries,
[in] const RGBQUAD *prgbq
);
It expects 3 parameters, but BlackBox will pass it four. It's declaration needs to be fixed in MODULE WinApi as follows:
PROCEDURE SetDIBColorTable (p0: WinApi.HDC; p1, p2: INTEGER; IN [nil] p3: ARRAY [untagged] OF WinApi.RGBQUAD): INTEGER;
Post Reply