https://gcc.gnu.org/g:e19652b295165894ec37c8c41db1d8e42ca043f2
commit r17-5676-ge19652b295165894ec37c8c41db1d8e42ca043f2 Author: Eric Botcazou <[email protected]> Date: Wed Oct 28 19:45:06 2026 +0100 Ada: Fix assertion checking failure on pathological code The pathological code is from gnat.dg/slice7.adb and involves a slice of an array, which is fabricated by subtracting two integers and interpreting the result as an array... gcc/ada/ PR ada/89786 * gcc-interface/utils.cc (unchecked_convert): Deal specially with the conversion of the result of a binary operation to an array. gcc/testsuite/ * gnat.dg/slice11.adb: New test. Diff: --- gcc/ada/gcc-interface/utils.cc | 13 +++++++++++++ gcc/testsuite/gnat.dg/slice11.adb | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index edeecdb5f05c..6f32350ed1ba 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -6164,6 +6164,19 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) return unchecked_convert (type, expr, notrunc_p); } + /* If we are converting the result of a binary operation to an array type, + create a temporary to hold the result and convert the temporary. This + will avoid problems downstream when slices of the array are taken. */ + else if (!AGGREGATE_TYPE_P (etype) + && code == ARRAY_TYPE + && (tem = remove_conversions (expr, false)) + && BINARY_CLASS_P (tem)) + { + expr = build1 (SAVE_EXPR, etype, expr); + TREE_SIDE_EFFECTS (expr) = 1; + return unchecked_convert (type, expr, notrunc_p); + } + /* If we are converting a string constant to a pointer to character, make sure that the string is not folded into an integer constant. */ else if (TREE_CODE (expr) == STRING_CST diff --git a/gcc/testsuite/gnat.dg/slice11.adb b/gcc/testsuite/gnat.dg/slice11.adb new file mode 100644 index 000000000000..d823ef9aa715 --- /dev/null +++ b/gcc/testsuite/gnat.dg/slice11.adb @@ -0,0 +1,38 @@ +-- { dg-do compile } +-- { dg-options "-O -gnatws" } + +with System.Storage_Elements; use System.Storage_Elements; +with Unchecked_Conversion; +with Slice7_Pkg; use Slice7_Pkg; + +procedure Slice11 is + + type Discrete_Type is range 1 .. 32; + + Max_Byte_Count : constant := 4; + subtype Byte_Count_Type is Storage_Offset range 1..Max_Byte_Count; + + subtype Buffer_Type is Storage_Array (Byte_Count_Type); + function Convert_Put is new Unchecked_Conversion (Integer, Buffer_Type); + + function Set_Buffer_Size return Byte_Count_Type is + begin + return 4; + end; + + Buffer_Size : constant Byte_Count_Type := Set_Buffer_Size; + Buffer_End : constant Byte_Count_Type := Max_Byte_Count; + Buffer_Start : constant Byte_Count_Type := Buffer_End - Buffer_Size + 1; + + Obj : Discrete_Type; + +begin + Put (Convert_Put(Discrete_Type'Pos (Obj))); + + Put (Convert_Put(Discrete_Type'Pos (Obj)) + (Buffer_Start..Buffer_End)); + + Put (Convert_Put(Discrete_Type'Pos (Obj) - + Discrete_Type'Pos (Discrete_Type'First)) + (Buffer_Start..Buffer_End)); +end;
