]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix bogus -Wstringop-overflow warning in Ada
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 5 Oct 2022 10:21:03 +0000 (12:21 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Wed, 5 Oct 2022 11:48:57 +0000 (13:48 +0200)
It comes from a discrepancy between get_offset_range, which uses a signed
type, and handle_array_ref, which uses an unsigned one, to do computations.

gcc/
PR tree-optimization/106698
* pointer-query.cc (handle_array_ref): Fix handling of low bound.

gcc/testsuite/
* gnat.dg/lto26.adb: New test.
* gnat.dg/lto26_pkg1.ads, gnat.dg/lto26_pkg1.adb: New helper.
* gnat.dg/lto26_pkg2.ads, gnat.dg/lto26_pkg2.adb: Likewise.

gcc/pointer-query.cc
gcc/testsuite/gnat.dg/lto26.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/lto26_pkg1.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/lto26_pkg1.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/lto26_pkg2.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/lto26_pkg2.ads [new file with mode: 0644]

index ae561731216c0a6a96cb3c5791591e830fc90cde..0f0100233c1ef58a089d3dfa7170230f7dc7df7f 100644 (file)
@@ -1796,14 +1796,19 @@ handle_array_ref (tree aref, gimple *stmt, bool addr, int ostype,
       orng[0] = -orng[1] - 1;
     }
 
-  /* Convert the array index range determined above to a byte
-     offset.  */
+  /* Convert the array index range determined above to a byte offset.  */
   tree lowbnd = array_ref_low_bound (aref);
-  if (!integer_zerop (lowbnd) && tree_fits_uhwi_p (lowbnd))
-    {
-      /* Adjust the index by the low bound of the array domain
-        (normally zero but 1 in Fortran).  */
-      unsigned HOST_WIDE_INT lb = tree_to_uhwi (lowbnd);
+  if (TREE_CODE (lowbnd) == INTEGER_CST && !integer_zerop (lowbnd))
+    {
+      /* Adjust the index by the low bound of the array domain (0 in C/C++,
+        1 in Fortran and anything in Ada) by applying the same processing
+        as in get_offset_range.  */
+      const wide_int wlb = wi::to_wide (lowbnd);
+      signop sgn = SIGNED;
+      if (TYPE_UNSIGNED (TREE_TYPE (lowbnd))
+         && wlb.get_precision () < TYPE_PRECISION (sizetype))
+       sgn = UNSIGNED;
+      const offset_int lb = offset_int::from (wlb, sgn);
       orng[0] -= lb;
       orng[1] -= lb;
     }
diff --git a/gcc/testsuite/gnat.dg/lto26.adb b/gcc/testsuite/gnat.dg/lto26.adb
new file mode 100644 (file)
index 0000000..a27348b
--- /dev/null
@@ -0,0 +1,13 @@
+-- { dg-do run }
+-- { dg-options "-O2 -flto" { target lto } }
+
+with Ada.Streams; use Ada.Streams;
+with Lto26_Pkg1; use Lto26_Pkg1;
+
+procedure Lto26 is
+  R : Rec;
+begin
+  for I in 1 .. 10 loop
+    Set (R, (7, 0, 84, Stream_Element (I), 0, 0, 0), 1);
+  end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/lto26_pkg1.adb b/gcc/testsuite/gnat.dg/lto26_pkg1.adb
new file mode 100644 (file)
index 0000000..c68b134
--- /dev/null
@@ -0,0 +1,11 @@
+with Lto26_Pkg2; use Lto26_Pkg2;
+
+package body Lto26_Pkg1 is
+
+  procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8) is
+    procedure My_Build is new Build;
+  begin
+     My_Build (A, C);
+  end;
+
+end Lto26_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/lto26_pkg1.ads b/gcc/testsuite/gnat.dg/lto26_pkg1.ads
new file mode 100644 (file)
index 0000000..5279747
--- /dev/null
@@ -0,0 +1,11 @@
+with Ada.Finalization;
+with Ada.Streams;  use Ada.Streams;
+with Interfaces; use Interfaces;
+
+package Lto26_Pkg1 is
+
+  type Rec is new Ada.Finalization.Limited_Controlled with null record;
+
+  procedure Set (R : Rec; A : Stream_Element_Array; C :Unsigned_8);
+
+end Lto26_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/lto26_pkg2.adb b/gcc/testsuite/gnat.dg/lto26_pkg2.adb
new file mode 100644 (file)
index 0000000..9f89733
--- /dev/null
@@ -0,0 +1,15 @@
+package body Lto26_Pkg2 is
+
+  procedure Build (A : Stream_Element_Array; C : Unsigned_8) is
+    Start  : Stream_Element_Offset := A'First;
+    Next   : Stream_Element_Offset;
+    Length : Unsigned_8;
+  begin
+    for I in 1 .. C loop
+      Length := Unsigned_8 (A (A'First));
+      Next   := Start + Stream_Element_Offset (Length);
+      Start  := Next;
+    end loop;
+  end;
+
+end Lto26_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/lto26_pkg2.ads b/gcc/testsuite/gnat.dg/lto26_pkg2.ads
new file mode 100644 (file)
index 0000000..68741bb
--- /dev/null
@@ -0,0 +1,9 @@
+with Ada.Streams; use Ada.Streams;
+with Interfaces; use Interfaces;
+
+package Lto26_Pkg2 is
+
+  generic
+  procedure Build (A : Stream_Element_Array; C : Unsigned_8);
+
+end Lto26_Pkg2;