From b1bc840ec8ad7db897585df56608e10f9853b75e Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 13 Jan 2022 19:38:22 -0600 Subject: [PATCH] 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. --- Parser.pas | 17 ++------------ Symbol.pas | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cc.notes | 4 ++++ 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/Parser.pas b/Parser.pas index 050d1d6..3920302 100644 --- a/Parser.pas +++ b/Parser.pas @@ -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 diff --git a/Symbol.pas b/Symbol.pas index d4f7588..c834cda 100644 --- a/Symbol.pas +++ b/Symbol.pas @@ -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}; diff --git a/cc.notes b/cc.notes index 6e77d47..97027ec 100644 --- a/cc.notes +++ b/cc.notes @@ -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.