From c210f9bc25588b7eb19e4a8a3a007ca53693a203 Mon Sep 17 00:00:00 2001 From: Mike Date: Sun, 6 Sep 2026 14:29:10 +0300 Subject: [PATCH] helpers: key distinct type aliases by their own identity (fixes upstream#41564) The helper key for a record or object was built from the base structure's symbol table, so several distinct aliases of one record (type TA = type TB) shared a single key and lookup returned the helper registered last for any of them. For a df_unique def build the key from the def's own owner and name; plain aliases keep sharing the structural key. FPC issue: https://gitlab.com/freepascal.org/fpc/source/-/issues/41564 Co-Authored-By: Claude Fable 5.1 --- compiler/symtable.pas | 3 +- tests/webtbs/tw41564.pp | 80 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 tests/webtbs/tw41564.pp diff --git a/compiler/symtable.pas b/compiler/symtable.pas index 2faef4a312b..40747a75723 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -3243,7 +3243,8 @@ if defowner.typ=recorddef then assigned(tstoreddef(def).genericdef) and assigned(def.typesym) then result:=make_mangledname('',tstoreddef(def).genericdef.owner,def.typesym.name) - else if def.typ in [recorddef,objectdef] then + else if (def.typ in [recorddef,objectdef]) and + not (df_unique in def.defoptions) then result:=make_mangledname('',tabstractrecorddef(def).symtable,'') else result:=make_mangledname('',def.owner,def.typesym.name); diff --git a/tests/webtbs/tw41564.pp b/tests/webtbs/tw41564.pp new file mode 100644 index 00000000000..5ea8a976f8b --- /dev/null +++ b/tests/webtbs/tw41564.pp @@ -0,0 +1,80 @@ +program tw41564; + +{$mode delphi} + +type + TBase = record + Value: Integer; + end; + TAlias = TBase; + TFirst = type TBase; + TSecond = type TBase; + + TBaseHelper = record helper for TBase + function Marker: Integer; + class function StaticMarker: Integer; static; + end; + + TFirstHelper = record helper for TFirst + function Marker: Integer; + class function StaticMarker: Integer; static; + end; + + TSecondHelper = record helper for TSecond + function Marker: Integer; + class function StaticMarker: Integer; static; + end; + +function TBaseHelper.Marker: Integer; +begin + Result := 10; +end; + +class function TBaseHelper.StaticMarker: Integer; +begin + Result := 20; +end; + +function TFirstHelper.Marker: Integer; +begin + Result := 11; +end; + +class function TFirstHelper.StaticMarker: Integer; +begin + Result := 21; +end; + +function TSecondHelper.Marker: Integer; +begin + Result := 12; +end; + +class function TSecondHelper.StaticMarker: Integer; +begin + Result := 22; +end; + +var + Base: TBase; + AliasValue: TAlias; + First: TFirst; + Second: TSecond; +begin + if Base.Marker <> 10 then + Halt(1); + if AliasValue.Marker <> 10 then + Halt(2); + if First.Marker <> 11 then + Halt(3); + if Second.Marker <> 12 then + Halt(4); + if TBase.StaticMarker <> 20 then + Halt(5); + if TAlias.StaticMarker <> 20 then + Halt(6); + if TFirst.StaticMarker <> 21 then + Halt(7); + if TSecond.StaticMarker <> 22 then + Halt(8); +end.