Reverse order of parameters for pascal function pointer types.

The parameters of the underlying function type were not being reversed when applying the "pascal" qualifier to a function pointer type. This resulted in the parameters not being in the expected order when a call was made using such a function pointer. This could result in spurious errors in some cases or inappropriate parameter conversions in others.

This fixes #75.
This commit is contained in:
Stephen Heumann 2022-01-13 19:38:22 -06:00
parent 3acf5844c2
commit b1bc840ec8
3 changed files with 72 additions and 15 deletions

View File

@ -3945,21 +3945,8 @@ else {if not isFunction then} begin
Error(142);
if not SkipDeclarator then
repeat
if isPascal then begin
tp := variable^.itype;
while tp <> nil do
case tp^.kind of
scalarType,
enumType,
enumConst,
definedType,
structType,
unionType: begin tp := nil; Error(94); end;
arrayType: tp := tp^.atype;
pointerType: tp := tp^.pType;
functionType: begin tp^.isPascal := true; tp := nil; end;
end; {case}
end; {if}
if isPascal then
variable^.itype := MakePascalType(variable^.itype);
if isInline then
Error(119);
if isNoreturn then

View File

@ -172,6 +172,16 @@ function LabelToDisp (lab: integer): integer; extern;
{ lab - label number }
function MakePascalType (origType: typePtr): typePtr;
{ make a version of a type with the pascal qualifier applied }
{ }
{ parameters: }
{ origType - the original type }
{ }
{ returns: pointer to the pascal-qualified type }
function MakeQualifiedType (origType: typePtr; qualifiers: typeQualifierSet):
typePtr;
@ -1684,6 +1694,62 @@ constCharPtr^.qualifiers := [tqConst];
end; {InitSymbol}
function MakePascalType {origType: typePtr): typePtr};
{ make a version of a type with the pascal qualifier applied }
{ }
{ parameters: }
{ origType - the original type }
{ }
{ returns: pointer to the pascal-qualified type }
var
pascalType: typePtr; {the modified type}
tp,tp2: typePtr; {work pointers}
p1,p2,p3: parameterPtr; {for reversing prototyped parameters}
begin {MakePascalType}
pascalType := pointer(Malloc(sizeof(typeRecord)));
pascalType^ := origType^;
MakePascalType := pascalType;
tp := pascalType;
while tp <> nil do
case tp^.kind of
arrayType,
pointerType: begin
tp2 := pointer(Malloc(sizeof(typeRecord)));
tp2^ := tp^.pType^;
tp^.pType := tp2;
tp := tp2;
end;
functionType: begin
if not tp^.isPascal then begin
{reverse the parameter list}
p1 := tp^.parameterList;
if p1 <> nil then begin
p2 := nil;
while p1 <> nil do begin
p3 := pointer(Malloc(sizeof(parameterRecord)));
p3^ := p1^;
p1 := p1^.next;
p3^.next := p2;
p2 := p3;
end; {while}
tp^.parameterList := p2;
end; {if}
tp^.isPascal := true;
end; {if}
tp := nil;
end;
otherwise: begin
Error(94);
MakePascalType := origType;
tp := nil;
end;
end; {case}
end; {MakePascalType}
function MakeQualifiedType {origType: typePtr; qualifiers: typeQualifierSet):
typePtr};

View File

@ -1699,6 +1699,10 @@ int foo(int[42]);
173. sizeof could give the wrong value if the type contained a nested use of a type name within an array length expression, e.g. sizeof(short[(long)50]).
174. Certain calls using a pascal-qualified function pointer would not work properly. They could cause either incorrect code generation or spurious compiler errors, depending on the parameter types.
(Chris Vavruska)
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.