mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 13:59:28 +02:00
* RTTI fix for alignment-sensitive targets:
* typinfo.pp: the newly introduced records were added into {$PACKRECORDS 1} area of effect, which effectively made all records packed, entirely defeating FPC_REQUIRES_PROPER_ALIGNMENT purpose. * added alignment between TProcedureParam records, adjusted TProcedureSignature.GetParam() appropriately. * ncgrtti.pas: added two missing alignments and removed a redundant one. * tests/test/trtti9.pp: modified to use TProcedureSignature.GetParam() and endian-independent check for parameter flags. git-svn-id: trunk@24562 -
This commit is contained in:
parent
371deafcdc
commit
23cb216435
@ -612,6 +612,8 @@ implementation
|
||||
else
|
||||
break;
|
||||
end;
|
||||
if (tf_requires_proper_alignment in target_info.flags) then
|
||||
current_asmdata.asmlists[al_rtti].InsertAfter(cai_align.Create(sizeof(TConstPtrUInt)),lastai);
|
||||
{ dimension count }
|
||||
current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_8bit(dimcount),lastai);
|
||||
{ last dimension element type }
|
||||
@ -738,6 +740,7 @@ implementation
|
||||
begin
|
||||
{ write flags for current parameter }
|
||||
write_param_flag(parasym);
|
||||
maybe_write_align;
|
||||
{ write param type }
|
||||
write_rtti_reference(parasym.vardef,fullrtti);
|
||||
{ write name of current parameter }
|
||||
@ -814,7 +817,7 @@ implementation
|
||||
|
||||
{ flags }
|
||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
|
||||
maybe_write_align;
|
||||
//maybe_write_align; // aligning between bytes is not necessary
|
||||
{ write calling convention }
|
||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption]));
|
||||
maybe_write_align;
|
||||
@ -822,9 +825,11 @@ implementation
|
||||
write_rtti_reference(def.returndef,fullrtti);
|
||||
{ write parameter count }
|
||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
|
||||
maybe_write_align;
|
||||
for i:=0 to def.paras.count-1 do
|
||||
write_procedure_param(tparavarsym(def.paras[i]));
|
||||
begin
|
||||
maybe_write_align;
|
||||
write_procedure_param(tparavarsym(def.paras[i]));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -113,6 +113,7 @@ unit typinfo;
|
||||
PTypeInfo = ^TTypeInfo;
|
||||
PPTypeInfo = ^PTypeInfo;
|
||||
|
||||
{$PACKRECORDS C}
|
||||
// members of TTypeData
|
||||
TArrayTypeData =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
@ -160,7 +161,6 @@ unit typinfo;
|
||||
function GetParam(ParamIndex: Integer): PProcedureParam;
|
||||
end;
|
||||
|
||||
{$PACKRECORDS C}
|
||||
PTypeData = ^TTypeData;
|
||||
TTypeData =
|
||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||
@ -2056,7 +2056,7 @@ begin
|
||||
Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
|
||||
while ParamIndex > 0 do
|
||||
begin
|
||||
Result := PProcedureParam(PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar));
|
||||
Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
|
||||
dec(ParamIndex);
|
||||
end;
|
||||
end;
|
||||
|
@ -9,9 +9,9 @@ type
|
||||
PProcedureParam = ^TProcedureParam;
|
||||
TProc = procedure(var A: Integer; S: String); stdcall;
|
||||
|
||||
function TestParam(Param: PProcedureParam; Flags: Byte; ParamType: Pointer; Name: ShortString): Boolean;
|
||||
function TestParam(Param: PProcedureParam; Flags: TParamFlags; ParamType: Pointer; Name: ShortString): Boolean;
|
||||
begin
|
||||
Result := (Param^.Flags = Flags) and (Param^.ParamType = ParamType) and (Param^.Name = Name);
|
||||
Result := (Param^.Flags = PByte(@Flags)^) and (Param^.ParamType = ParamType) and (Param^.Name = Name);
|
||||
end;
|
||||
|
||||
var
|
||||
@ -29,10 +29,10 @@ begin
|
||||
halt(3);
|
||||
if Data^.ProcSig.ParamCount <> 2 then
|
||||
halt(4);
|
||||
Param := PProcedureParam(PAnsiChar(@Data^.ProcSig.Flags) + SizeOf(TProcedureSignature));
|
||||
if not TestParam(Param, 1, TypeInfo(Integer), 'A') then
|
||||
Param := Data^.ProcSig.GetParam(0);
|
||||
if not TestParam(Param, [pfVar], TypeInfo(Integer), 'A') then
|
||||
halt(5);
|
||||
Param := PProcedureParam(PAnsiChar(@Param^.Name) + (Length(Param^.Name) + 1) * SizeOf(AnsiChar));
|
||||
if not TestParam(Param, 0, TypeInfo(String), 'S') then
|
||||
Param := Data^.ProcSig.GetParam(1);
|
||||
if not TestParam(Param, [], TypeInfo(String), 'S') then
|
||||
halt(6);
|
||||
end.
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user