From ac18ded230f1559f271f8d66121b2f16805f0b27 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Wed, 12 May 2021 11:56:47 +0200 Subject: [PATCH] Fix uninitialized variable in Atree.Size_In_Slots Size_In_Slots uses the Nkind to look up the size in a table indexed by Nkind. This patch fixes a couple of places where the Nkind is wrong (uninitialized or zeroed out) so Size_In_Slots cannot be used. gcc/ada/ PR ada/100564 * atree.adb (Change_Node): Do not call Zero_Slots on a Node_Id when the Nkind has not yet been set; call the other Zero_Slots that takes a range of slot offsets. Call the new Mutate_Kind that takes an Old_Size, for the same reason -- the size cannot be computed without the Nkind. (Mutate_Nkind): New function that allows specifying the Old_Size. (Size_In_Slots): Assert that the Nkind has proper (nonzero) value. * atree.ads: Minor reformatting. --- gcc/ada/atree.adb | 32 +++++++++++++++++++++++++------- gcc/ada/atree.ads | 3 +-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb index 4d4dc43..608819b 100644 --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -216,6 +216,13 @@ package body Atree is -- cannot be used to modify an already-initialized Nkind field. See also -- Mutate_Nkind. + procedure Mutate_Nkind + (N : Node_Id; Val : Node_Kind; Old_Size : Field_Offset); + -- Called by the other Mutate_Nkind to do all the work. This is needed + -- because the call in Change_Node, which calls this one directly, happens + -- after zeroing N's slots, which destroys its Nkind, which prevents us + -- from properly computing Old_Size. + package Field_Checking is function Field_Present (Kind : Node_Kind; Field : Node_Field) return Boolean; @@ -868,9 +875,8 @@ package body Atree is end Init_Nkind; procedure Mutate_Nkind - (N : Node_Id; Val : Node_Kind) + (N : Node_Id; Val : Node_Kind; Old_Size : Field_Offset) is - Old_Size : constant Field_Offset := Size_In_Slots (N); New_Size : constant Field_Offset := Size_In_Slots_To_Alloc (Val); All_Node_Offsets : Node_Offsets.Table_Type renames @@ -905,6 +911,11 @@ package body Atree is pragma Debug (Validate_Node_Write (N)); end Mutate_Nkind; + procedure Mutate_Nkind (N : Node_Id; Val : Node_Kind) is + begin + Mutate_Nkind (N, Val, Old_Size => Size_In_Slots (N)); + end Mutate_Nkind; + Ekind_Offset : constant Field_Offset := Entity_Field_Descriptors (Ekind).Offset; @@ -998,13 +1009,19 @@ package body Atree is end if; if New_Size > Old_Size then - pragma Debug (Zero_Slots (N)); - Node_Offsets.Table (N) := Alloc_Slots (New_Size); - end if; + declare + New_Offset : constant Field_Offset := Alloc_Slots (New_Size); + begin + pragma Debug (Zero_Slots (N)); + Node_Offsets.Table (N) := New_Offset; + Zero_Slots (New_Offset, New_Offset + New_Size - 1); + end; - Zero_Slots (N); + else + Zero_Slots (N); + end if; - Mutate_Nkind (N, New_Kind); + Mutate_Nkind (N, New_Kind, Old_Size); Set_Sloc (N, Save_Sloc); Set_In_List (N, Save_In_List); @@ -2125,6 +2142,7 @@ package body Atree is function Size_In_Slots (N : Node_Or_Entity_Id) return Field_Offset is begin + pragma Assert (Nkind (N) /= N_Unused_At_Start); return (if Nkind (N) in N_Entity then Einfo.Entities.Max_Entity_Size else Sinfo.Nodes.Size (Nkind (N))); diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads index efb8ca2..e2d3492 100644 --- a/gcc/ada/atree.ads +++ b/gcc/ada/atree.ads @@ -571,8 +571,7 @@ package Atree is (N : Entity_Id; Field : Entity_Field) return Boolean; -- True if the field value is the initial zero value - procedure Mutate_Nkind - (N : Node_Id; Val : Node_Kind) with Inline; + procedure Mutate_Nkind (N : Node_Id; Val : Node_Kind) with Inline; -- There is no Set_Nkind in Sinfo.Nodes. We use this instead. This is here, -- and has a different name, because it does some extra checking. Nkind is -- like a discriminant, in that it controls which fields exist, and that -- 2.7.4