Page 1 of 1
VAR [nil] for tagged structural parameters
Posted: Sat Jan 15, 2022 1:56 pm
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:
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:
The result of its work:
Re: VAR [nil] for tagged structural parameters
Posted: Sat Jan 15, 2022 9:48 pm
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)
Re: VAR [nil] for tagged structural parameters
Posted: Sat Jan 15, 2022 10:03 pm
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?
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.
Re: VAR [nil] for tagged structural parameters
Posted: Thu Jan 20, 2022 2:29 pm
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;