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;

Reply via email to