mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-01 21:50:18 +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
|
else
|
||||||
break;
|
break;
|
||||||
end;
|
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 }
|
{ dimension count }
|
||||||
current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_8bit(dimcount),lastai);
|
current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_8bit(dimcount),lastai);
|
||||||
{ last dimension element type }
|
{ last dimension element type }
|
||||||
@ -738,6 +740,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ write flags for current parameter }
|
{ write flags for current parameter }
|
||||||
write_param_flag(parasym);
|
write_param_flag(parasym);
|
||||||
|
maybe_write_align;
|
||||||
{ write param type }
|
{ write param type }
|
||||||
write_rtti_reference(parasym.vardef,fullrtti);
|
write_rtti_reference(parasym.vardef,fullrtti);
|
||||||
{ write name of current parameter }
|
{ write name of current parameter }
|
||||||
@ -814,7 +817,7 @@ implementation
|
|||||||
|
|
||||||
{ flags }
|
{ flags }
|
||||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
|
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 }
|
{ write calling convention }
|
||||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption]));
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption]));
|
||||||
maybe_write_align;
|
maybe_write_align;
|
||||||
@ -822,9 +825,11 @@ implementation
|
|||||||
write_rtti_reference(def.returndef,fullrtti);
|
write_rtti_reference(def.returndef,fullrtti);
|
||||||
{ write parameter count }
|
{ write parameter count }
|
||||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
|
||||||
maybe_write_align;
|
|
||||||
for i:=0 to def.paras.count-1 do
|
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;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ unit typinfo;
|
|||||||
PTypeInfo = ^TTypeInfo;
|
PTypeInfo = ^TTypeInfo;
|
||||||
PPTypeInfo = ^PTypeInfo;
|
PPTypeInfo = ^PTypeInfo;
|
||||||
|
|
||||||
|
{$PACKRECORDS C}
|
||||||
// members of TTypeData
|
// members of TTypeData
|
||||||
TArrayTypeData =
|
TArrayTypeData =
|
||||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
@ -160,7 +161,6 @@ unit typinfo;
|
|||||||
function GetParam(ParamIndex: Integer): PProcedureParam;
|
function GetParam(ParamIndex: Integer): PProcedureParam;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$PACKRECORDS C}
|
|
||||||
PTypeData = ^TTypeData;
|
PTypeData = ^TTypeData;
|
||||||
TTypeData =
|
TTypeData =
|
||||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
@ -2056,7 +2056,7 @@ begin
|
|||||||
Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
|
Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
|
||||||
while ParamIndex > 0 do
|
while ParamIndex > 0 do
|
||||||
begin
|
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);
|
dec(ParamIndex);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -9,9 +9,9 @@ type
|
|||||||
PProcedureParam = ^TProcedureParam;
|
PProcedureParam = ^TProcedureParam;
|
||||||
TProc = procedure(var A: Integer; S: String); stdcall;
|
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
|
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;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -29,10 +29,10 @@ begin
|
|||||||
halt(3);
|
halt(3);
|
||||||
if Data^.ProcSig.ParamCount <> 2 then
|
if Data^.ProcSig.ParamCount <> 2 then
|
||||||
halt(4);
|
halt(4);
|
||||||
Param := PProcedureParam(PAnsiChar(@Data^.ProcSig.Flags) + SizeOf(TProcedureSignature));
|
Param := Data^.ProcSig.GetParam(0);
|
||||||
if not TestParam(Param, 1, TypeInfo(Integer), 'A') then
|
if not TestParam(Param, [pfVar], TypeInfo(Integer), 'A') then
|
||||||
halt(5);
|
halt(5);
|
||||||
Param := PProcedureParam(PAnsiChar(@Param^.Name) + (Length(Param^.Name) + 1) * SizeOf(AnsiChar));
|
Param := Data^.ProcSig.GetParam(1);
|
||||||
if not TestParam(Param, 0, TypeInfo(String), 'S') then
|
if not TestParam(Param, [], TypeInfo(String), 'S') then
|
||||||
halt(6);
|
halt(6);
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user