Browse Source

* Fix to TObjectOpenAddressingLP in generics.collections where SetValue
would free the object if the current value is the same as the new value
(fixes #40024)

J. Gareth "Curious Kit" Moreton 2 years ago
parent
commit
663ee7bc20

+ 14 - 0
packages/rtl-generics/src/inc/generics.dictionaries.inc

@@ -2233,6 +2233,20 @@ begin
   FOwnerships := AOwnerships;
   FOwnerships := AOwnerships;
 end;
 end;
 
 
+procedure TObjectOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS>.SetValue(var AValue: TValue; constref ANewValue: TValue);
+var
+  LOldValue: TValue;
+begin
+  if TObject((@AValue)^) <> TObject((@ANewValue)^) then
+  begin
+    LOldValue := AValue;
+    AValue := ANewValue;
+
+    ValueNotify(LOldValue, cnRemoved);
+    ValueNotify(ANewValue, cnAdded);
+  end;
+end;
+
 procedure TObjectOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS>.KeyNotify(
 procedure TObjectOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS>.KeyNotify(
   constref AKey: TKey; ACollectionNotification: TCollectionNotification);
   constref AKey: TKey; ACollectionNotification: TCollectionNotification);
 begin
 begin

+ 2 - 1
packages/rtl-generics/src/inc/generics.dictionariesh.inc

@@ -98,7 +98,7 @@ type
     procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); virtual;
     procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); virtual;
     procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); virtual;
     procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); virtual;
     procedure PairNotify(constref APair: TDictionaryPair; ACollectionNotification: TCollectionNotification); inline;
     procedure PairNotify(constref APair: TDictionaryPair; ACollectionNotification: TCollectionNotification); inline;
-    procedure SetValue(var AValue: TValue; constref ANewValue: TValue);
+    procedure SetValue(var AValue: TValue; constref ANewValue: TValue); dynamic;
   public
   public
     property OnKeyNotify: TCollectionNotifyEvent<TKey> read FOnKeyNotify write FOnKeyNotify;
     property OnKeyNotify: TCollectionNotifyEvent<TKey> read FOnKeyNotify write FOnKeyNotify;
     property OnValueNotify: TCollectionNotifyEvent<TValue> read FOnValueNotify write FOnValueNotify;
     property OnValueNotify: TCollectionNotifyEvent<TValue> read FOnValueNotify write FOnValueNotify;
@@ -597,6 +597,7 @@ type
   private
   private
     FOwnerships: TDictionaryOwnerships;
     FOwnerships: TDictionaryOwnerships;
   protected
   protected
+    procedure SetValue(var AValue: TValue; constref ANewValue: TValue); override;
     procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); override;
     procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); override;
     procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); override;
     procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); override;
   public
   public