public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-6482] tree-object-size: Dynamic sizes for ADDR_EXPR
@ 2022-01-11 14:48 Siddhesh Poyarekar
  0 siblings, 0 replies; only message in thread
From: Siddhesh Poyarekar @ 2022-01-11 14:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:06bc1b0c539e3a60692d7432d15e701c38610f80

commit r12-6482-g06bc1b0c539e3a60692d7432d15e701c38610f80
Author: Siddhesh Poyarekar <siddhesh@gotplt.org>
Date:   Tue Jan 11 08:08:27 2022 +0530

    tree-object-size: Dynamic sizes for ADDR_EXPR
    
    Allow returning dynamic expressions from ADDR_EXPR for
    __builtin_dynamic_object_size and also allow offsets to be dynamic.
    
    gcc/ChangeLog:
    
            PR middle-end/70090
            * tree-object-size.c (size_valid_p): New function.
            (size_for_offset): Remove OFFSET constness assertion.
            (addr_object_size): Build dynamic expressions for object
            sizes and use size_valid_p to decide if it is valid for the
            given OBJECT_SIZE_TYPE.
            (compute_builtin_object_size): Allow dynamic offsets when
            computing size at O0.
            (call_object_size): Call size_valid_p.
            (plus_stmt_object_size): Allow non-constant offset and use
            size_valid_p to decide if it is valid for the given
            OBJECT_SIZE_TYPE.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/70090
            * gcc.dg/builtin-dynamic-object-size-0.c: Add new tests.
            * gcc.dg/builtin-object-size-1.c (test1)
            [__builtin_object_size]: Adjust expected output for dynamic
            object sizes.
            * gcc.dg/builtin-object-size-2.c (test1)
            [__builtin_object_size]: Likewise.
            * gcc.dg/builtin-object-size-3.c (test1)
            [__builtin_object_size]: Likewise.
            * gcc.dg/builtin-object-size-4.c (test1)
            [__builtin_object_size]: Likewise.
    
    Signed-off-by: Siddhesh Poyarekar <siddhesh@gotplt.org>

Diff:
---
 .../gcc.dg/builtin-dynamic-object-size-0.c         | 156 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/builtin-object-size-1.c       |  30 +++-
 gcc/testsuite/gcc.dg/builtin-object-size-2.c       |  43 ++++--
 gcc/testsuite/gcc.dg/builtin-object-size-3.c       |  25 +++-
 gcc/testsuite/gcc.dg/builtin-object-size-4.c       |  17 +--
 gcc/tree-object-size.c                             |  94 ++++++-------
 6 files changed, 299 insertions(+), 66 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
index 930fd49cd16..dd8dc99a580 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
@@ -250,6 +250,79 @@ test_deploop (size_t sz, size_t cond)
   return __builtin_dynamic_object_size (bin, 0);
 }
 
+/* Address expressions.  */
+
+struct dynarray_struct
+{
+  long a;
+  char c[16];
+  int b;
+};
+
+size_t
+__attribute__ ((noinline))
+test_dynarray_struct (size_t sz, size_t off)
+{
+  struct dynarray_struct bin[sz];
+
+  return __builtin_dynamic_object_size (&bin[off].c, 0);
+}
+
+size_t
+__attribute__ ((noinline))
+test_dynarray_struct_subobj (size_t sz, size_t off)
+{
+  struct dynarray_struct bin[sz];
+
+  return __builtin_dynamic_object_size (&bin[off].c[4], 1);
+}
+
+size_t
+__attribute__ ((noinline))
+test_dynarray_struct_subobj2 (size_t sz, size_t off, size_t *objsz)
+{
+  struct dynarray_struct2
+    {
+      long a;
+      int b;
+      char c[sz];
+    };
+
+  struct dynarray_struct2 bin;
+
+  *objsz = sizeof (bin);
+
+  return __builtin_dynamic_object_size (&bin.c[off], 1);
+}
+
+size_t
+__attribute__ ((noinline))
+test_substring (size_t sz, size_t off)
+{
+  char str[sz];
+
+  return __builtin_dynamic_object_size (&str[off], 0);
+}
+
+size_t
+__attribute__ ((noinline))
+test_substring_ptrplus (size_t sz, size_t off)
+{
+  int str[sz];
+
+  return __builtin_dynamic_object_size (str + off, 0);
+}
+
+size_t
+__attribute__ ((noinline))
+test_substring_ptrplus2 (size_t sz, size_t off, size_t off2)
+{
+  int str[sz];
+  int *ptr = &str[off];
+
+  return __builtin_dynamic_object_size (ptr + off2, 0);
+}
+
 size_t
 __attribute__ ((access (__read_write__, 1, 2)))
 __attribute__ ((noinline))
@@ -258,6 +331,14 @@ test_parmsz_simple (void *obj, size_t sz)
   return __builtin_dynamic_object_size (obj, 0);
 }
 
+size_t
+__attribute__ ((noinline))
+__attribute__ ((access (__read_write__, 1, 2)))
+test_parmsz (void *obj, size_t sz, size_t off)
+{
+  return __builtin_dynamic_object_size (obj + off, 0);
+}
+
 size_t
 __attribute__ ((access (__read_write__, 1, 2)))
 __attribute__ ((noinline))
@@ -266,6 +347,14 @@ test_parmsz_scaled (int *obj, size_t sz)
   return __builtin_dynamic_object_size (obj, 0);
 }
 
+size_t
+__attribute__ ((noinline))
+__attribute__ ((access (__read_write__, 1, 2)))
+test_parmsz_scaled_off (int *obj, size_t sz, size_t off)
+{
+  return __builtin_dynamic_object_size (obj + off, 0);
+}
+
 size_t
 __attribute__ ((access (__read_write__, 1, 3)))
 __attribute__ ((noinline))
@@ -274,6 +363,23 @@ test_parmsz_unknown (void *obj, void *unknown, size_t sz, int cond)
   return __builtin_dynamic_object_size (cond ? obj : unknown, 0);
 }
 
+size_t
+__attribute__ ((noinline))
+__attribute__ ((access (__read_write__, 1, 2)))
+test_loop (int *obj, size_t sz, size_t start, size_t end, int incr)
+{
+  int *ptr = obj + start;
+
+  for (int i = start; i != end; i = i + incr)
+    {
+      ptr = ptr + incr;
+      if (__builtin_dynamic_object_size (ptr, 0) == 0)
+	return 0;
+    }
+
+  return __builtin_dynamic_object_size (ptr, 0);
+}
+
 unsigned nfails = 0;
 
 #define FAIL() ({ \
@@ -333,6 +439,32 @@ main (int argc, char **argv)
     FAIL ();
   if (test_dynarray (__builtin_strlen (argv[0])) != __builtin_strlen (argv[0]))
     FAIL ();
+  if (test_dynarray_struct (42, 4) !=
+      ((42 - 4) * sizeof (struct dynarray_struct)
+       - __builtin_offsetof (struct dynarray_struct, c)))
+    FAIL ();
+  if (test_dynarray_struct (42, 48) != 0)
+    FAIL ();
+  if (test_substring (128, 4) != 128 - 4)
+    FAIL ();
+  if (test_substring (128, 142) != 0)
+    FAIL ();
+  if (test_dynarray_struct_subobj (42, 4) != 16 - 4)
+    FAIL ();
+  if (test_dynarray_struct_subobj (42, 48) != 0)
+    FAIL ();
+  size_t objsz = 0;
+  if (test_dynarray_struct_subobj2 (42, 4, &objsz)
+    != objsz - 4 - sizeof (long) - sizeof (int))
+    FAIL ();
+  if (test_substring_ptrplus (128, 4) != (128 - 4) * sizeof (int))
+    FAIL ();
+  if (test_substring_ptrplus (128, 142) != 0)
+    FAIL ();
+  if (test_substring_ptrplus2 (128, 4, 4) != (128 - 8) * sizeof (int))
+    FAIL ();
+  if (test_substring_ptrplus2 (128, 4, -3) != (128 - 1) * sizeof (int))
+    FAIL ();
   if (test_dynarray_cond (0) != 16)
     FAIL ();
   if (test_dynarray_cond (1) != 8)
@@ -349,6 +481,30 @@ main (int argc, char **argv)
     FAIL ();
   if (test_parmsz_unknown (argv[0], argv[0], __builtin_strlen (argv[0]) + 1, 0)
       != -1)
+  if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, -1) != 0)
+    FAIL ();
+  if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, 0)
+      != __builtin_strlen (argv[0]) + 1)
+    FAIL ();
+  if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1,
+		   __builtin_strlen (argv[0])) != 1)
+    FAIL ();
+  if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1,
+		   __builtin_strlen (argv[0]) + 2) != 0)
+    FAIL ();
+  if (test_parmsz_scaled_off (arr, 42, 2) != 40 * sizeof (int))
+    FAIL ();
+  if (test_loop (arr, 42, 0, 32, 1) != 10 * sizeof (int))
+    FAIL ();
+  if (test_loop (arr, 42, 32, -1, -1) != 0)
+    FAIL ();
+  if (test_loop (arr, 42, 32, 10, -1) != 32 * sizeof (int))
+    FAIL ();
+  if (test_loop (arr, 42, 42, 0, -1) != 42 * sizeof (int))
+    FAIL ();
+  if (test_loop (arr, 42, 44, 0, -1) != 0)
+    FAIL ();
+  if (test_loop (arr, 42, 20, 52, 1) != 0)
     FAIL ();
 
   if (nfails > 0)
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
index 06d442796cb..161f426ec0b 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
@@ -81,30 +81,56 @@ test1 (void *q, int x)
     r = malloc (30);
   else
     r = calloc (2, 16);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0) != (x < 20 ? 30 : 2 * 16))
+    abort ();
+#else
   /* We may duplicate this test onto the two exit paths.  On one path
      the size will be 32, the other it will be 30.  If we don't duplicate
      this test, then the size will be 32.  */
   if (__builtin_object_size (r, 0) != 2 * 16
       && __builtin_object_size (r, 0) != 30)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 14);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0) != (x < 20 ? 30 : 2 * 14))
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != 30)
     abort ();
+#endif
   if (x < 30)
     r = malloc (sizeof (a));
   else
     r = &a.a[3];
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0) != (x < 30 ? sizeof (a) : sizeof (a) - 3))
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r, "a", 2);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0) != (x < 30 ? sizeof (a) : sizeof (a) - 3))
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r + 2, "b", 2) + 2;
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0)
+      != (x < 30 ? sizeof (a) - 4 : sizeof (a) - 7))
+    abort ();
+#else
   if (__builtin_object_size (r, 0) != sizeof (a) - 4)
     abort ();
+#endif
   r = &a.a[4];
   r = memset (r, 'a', 2);
   if (__builtin_object_size (r, 0)
@@ -140,14 +166,16 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (var + 10, 0) != x)
     abort ();
+  if (__builtin_object_size (&var[5], 0) != x + 5)
+    abort ();
 #else
   if (__builtin_object_size (var, 0) != (size_t) -1)
     abort ();
   if (__builtin_object_size (var + 10, 0) != (size_t) -1)
     abort ();
-#endif
   if (__builtin_object_size (&var[5], 0) != (size_t) -1)
     abort ();
+#endif
   if (__builtin_object_size (zerol, 0) != 0)
     abort ();
   if (__builtin_object_size (&zerol, 0) != 0)
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
index 2364f2d6afd..2729538da17 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
@@ -75,30 +75,56 @@ test1 (void *q, int x)
     r = malloc (30);
   else
     r = calloc (2, 16);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 1) != (x < 20 ? 30 : 2 * 16))
+    abort ();
+#else
   /* We may duplicate this test onto the two exit paths.  On one path
      the size will be 32, the other it will be 30.  If we don't duplicate
      this test, then the size will be 32.  */
   if (__builtin_object_size (r, 1) != 2 * 16
       && __builtin_object_size (r, 1) != 30)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 14);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 1) != (x < 20 ? 30 : 2 * 14))
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != 30)
     abort ();
+#endif
   if (x < 30)
     r = malloc (sizeof (a));
   else
     r = &a.a[3];
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 1) != (x < 30 ? sizeof (a) : sizeof (a) - 3))
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r, "a", 2);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 1) != (x < 30 ? sizeof (a) : sizeof (a) - 3))
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a))
     abort ();
+#endif
   r = memcpy (r + 2, "b", 2) + 2;
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 0)
+      != (x < 30 ? sizeof (a) - 4 : sizeof (a) - 7))
+    abort ();
+#else
   if (__builtin_object_size (r, 1) != sizeof (a) - 4)
     abort ();
+#endif
   r = &a.a[4];
   r = memset (r, 'a', 2);
   if (__builtin_object_size (r, 1) != sizeof (a.a) - 4)
@@ -142,27 +168,28 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (var + 10, 1) != x)
     abort ();
+  if (__builtin_object_size (&var[5], 1) != x + 5)
+    abort ();
+  if (__builtin_object_size (vara, 1) != (x + 10) * sizeof (struct A))
+    abort ();
+  if (__builtin_object_size (vara + 10, 1) != x * sizeof (struct A))
+    abort ();    
+  if (__builtin_object_size (&vara[5], 1) != (x + 5) * sizeof (struct A))
+    abort ();
 #else
   if (__builtin_object_size (var, 1) != (size_t) -1)
     abort ();
   if (__builtin_object_size (var + 10, 1) != (size_t) -1)
     abort ();
-#endif
   if (__builtin_object_size (&var[5], 1) != (size_t) -1)
     abort ();
-#ifdef __builtin_object_size
-  if (__builtin_object_size (vara, 1) != (x + 10) * sizeof (struct A))
-    abort ();
-  if (__builtin_object_size (vara + 10, 1) != x * sizeof (struct A))
-    abort ();    
-#else
   if (__builtin_object_size (vara, 1) != (size_t) -1)
     abort ();
   if (__builtin_object_size (vara + 10, 1) != (size_t) -1)
     abort ();    
-#endif
   if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
     abort ();
+#endif
   if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
     abort ();
   if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
index 753ee4a1a4f..db31171a8bd 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
@@ -42,9 +42,17 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (q, 2) != 0)
     abort ();
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 2)
+      != (x < 0
+	  ? sizeof (a) - __builtin_offsetof (struct A, a) - 9
+	  : sizeof (a) - __builtin_offsetof (struct A, c) - 1))
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, c) - 1)
     abort ();
+#endif
   if (x < 6)
     r = &w[2].a[1];
   else
@@ -58,15 +66,28 @@ test1 (void *q, int x)
   if (__builtin_object_size (&y.b, 2)
       != sizeof (a) - __builtin_offsetof (struct A, b))
     abort ();
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 2)
+      != (x < 6
+	  ? 2 * sizeof (w[0]) - __builtin_offsetof (struct A, a) - 1
+	  : sizeof (a) - __builtin_offsetof (struct A, a) - 6))
+    abort ();
+#else
   if (__builtin_object_size (r, 2)
       != sizeof (a) - __builtin_offsetof (struct A, a) - 6)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
     r = calloc (2, 16);
+#ifdef __builtin_object_size
+  if (__builtin_object_size (r, 2) != (x < 20 ? 30 : 2 * 16))
+    abort ();
+#else
   if (__builtin_object_size (r, 2) != 30)
     abort ();
+#endif
   if (x < 20)
     r = malloc (30);
   else
@@ -145,14 +166,16 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (var + 10, 2) != x)
     abort ();
+  if (__builtin_object_size (&var[5], 2) != x + 5)
+    abort ();
 #else
   if (__builtin_object_size (var, 2) != 0)
     abort ();
   if (__builtin_object_size (var + 10, 2) != 0)
     abort ();
-#endif
   if (__builtin_object_size (&var[5], 2) != 0)
     abort ();
+#endif
   if (__builtin_object_size (zerol, 2) != 0)
     abort ();
   if (__builtin_object_size (&zerol, 2) != 0)
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index c383385e060..f644890dd14 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -155,27 +155,28 @@ test1 (void *q, int x)
     abort ();
   if (__builtin_object_size (var + 10, 3) != x)
     abort ();
+  if (__builtin_object_size (&var[5], 3) != x + 5)
+    abort ();
+  if (__builtin_object_size (vara, 3) != (x + 10) * sizeof (struct A))
+    abort ();
+  if (__builtin_object_size (vara + 10, 3) != x * sizeof (struct A))
+    abort ();    
+  if (__builtin_object_size (&vara[5], 3) != (x + 5) * sizeof (struct A))
+    abort ();
 #else
   if (__builtin_object_size (var, 3) != 0)
     abort ();
   if (__builtin_object_size (var + 10, 3) != 0)
     abort ();
-#endif
   if (__builtin_object_size (&var[5], 3) != 0)
     abort ();
-#ifdef __builtin_object_size
-  if (__builtin_object_size (vara, 3) != (x + 10) * sizeof (struct A))
-    abort ();
-  if (__builtin_object_size (vara + 10, 3) != x * sizeof (struct A))
-    abort ();    
-#else
   if (__builtin_object_size (vara, 3) != 0)
     abort ();
   if (__builtin_object_size (vara + 10, 3) != 0)
     abort ();    
-#endif
   if (__builtin_object_size (&vara[5], 3) != 0)
     abort ();
+#endif
   if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
     abort ();
   if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index a887cc65af1..3a39e6f15bb 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -107,6 +107,14 @@ size_unknown_p (tree val, int object_size_type)
 	  ? integer_zerop (val) : integer_all_onesp (val));
 }
 
+/* Return true if VAL represents a valid size for OBJECT_SIZE_TYPE.  */
+
+static inline bool
+size_valid_p (tree val, int object_size_type)
+{
+  return ((object_size_type & OST_DYNAMIC) || TREE_CODE (val) == INTEGER_CST);
+}
+
 /* Return true if VAL is usable as an object size in the object_sizes
    vectors.  */
 
@@ -341,7 +349,6 @@ init_offset_limit (void)
 static tree
 size_for_offset (tree sz, tree offset, tree wholesize = NULL_TREE)
 {
-  gcc_checking_assert (TREE_CODE (offset) == INTEGER_CST);
   gcc_checking_assert (types_compatible_p (TREE_TYPE (sz), sizetype));
 
   /* For negative offsets, if we have a distinct WHOLESIZE, use it to get a net
@@ -540,18 +547,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 	    sz = wholesize = size_unknown (object_size_type);
 	}
       if (!size_unknown_p (sz, object_size_type))
-	{
-	  tree offset = TREE_OPERAND (pt_var, 1);
-	  if (TREE_CODE (offset) != INTEGER_CST
-	      || TREE_CODE (sz) != INTEGER_CST)
-	    sz = wholesize = size_unknown (object_size_type);
-	  else
-	    sz = size_for_offset (sz, offset, wholesize);
-	}
+	sz = size_for_offset (sz, TREE_OPERAND (pt_var, 1), wholesize);
 
       if (!size_unknown_p (sz, object_size_type)
-	  && TREE_CODE (sz) == INTEGER_CST
-	  && compare_tree_int (sz, offset_limit) < 0)
+	  && (TREE_CODE (sz) != INTEGER_CST
+	      || compare_tree_int (sz, offset_limit) < 0))
 	{
 	  pt_var_size = sz;
 	  pt_var_wholesize = wholesize;
@@ -571,8 +571,9 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 
   if (pt_var_size)
     {
-      /* Validate the size determined above.  */
-      if (compare_tree_int (pt_var_size, offset_limit) >= 0)
+      /* Validate the size determined above if it is a constant.  */
+      if (TREE_CODE (pt_var_size) == INTEGER_CST
+	  && compare_tree_int (pt_var_size, offset_limit) >= 0)
 	return false;
     }
 
@@ -596,7 +597,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 	    var = TREE_OPERAND (var, 0);
 	  if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
 	      || ! tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (var)))
-	      || (pt_var_size
+	      || (pt_var_size && TREE_CODE (pt_var_size) == INTEGER_CST
 		  && tree_int_cst_lt (pt_var_size,
 				      TYPE_SIZE_UNIT (TREE_TYPE (var)))))
 	    var = pt_var;
@@ -610,17 +611,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 		switch (TREE_CODE (v))
 		  {
 		  case ARRAY_REF:
-		    if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
-			&& TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
+		    if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0))))
 		      {
 			tree domain
 			  = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
-			if (domain
-			    && TYPE_MAX_VALUE (domain)
-			    && TREE_CODE (TYPE_MAX_VALUE (domain))
-			       == INTEGER_CST
-			    && tree_int_cst_lt (TREE_OPERAND (v, 1),
-						TYPE_MAX_VALUE (domain)))
+			if (domain && TYPE_MAX_VALUE (domain))
 			  {
 			    v = NULL_TREE;
 			    break;
@@ -687,20 +682,20 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 	var = pt_var;
 
       if (var != pt_var)
-	var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
+	{
+	  var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
+	  if (!TREE_CONSTANT (var_size))
+	    var_size = get_or_create_ssa_default_def (cfun, var_size);
+	  if (!var_size)
+	    return false;
+	}
       else if (!pt_var_size)
 	return false;
       else
 	var_size = pt_var_size;
       bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
       if (bytes != error_mark_node)
-	{
-	  if (TREE_CODE (bytes) == INTEGER_CST
-	      && tree_int_cst_lt (var_size, bytes))
-	    bytes = size_zero_node;
-	  else
-	    bytes = size_binop (MINUS_EXPR, var_size, bytes);
-	}
+	bytes = size_for_offset (var_size, bytes);
       if (var != pt_var
 	  && pt_var_size
 	  && TREE_CODE (pt_var) == MEM_REF
@@ -709,11 +704,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
 	  tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
 	  if (bytes2 != error_mark_node)
 	    {
-	      if (TREE_CODE (bytes2) == INTEGER_CST
-		  && tree_int_cst_lt (pt_var_size, bytes2))
-		bytes2 = size_zero_node;
-	      else
-		bytes2 = size_binop (MINUS_EXPR, pt_var_size, bytes2);
+	      bytes2 = size_for_offset (pt_var_size, bytes2);
 	      bytes = size_binop (MIN_EXPR, bytes, bytes2);
 	    }
 	}
@@ -729,14 +720,18 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
       wholebytes = pt_var_wholesize;
     }
 
-  if (TREE_CODE (bytes) != INTEGER_CST
-      || TREE_CODE (wholebytes) != INTEGER_CST)
-    return false;
+  if (!size_unknown_p (bytes, object_size_type)
+      && size_valid_p (bytes, object_size_type)
+      && !size_unknown_p (bytes, object_size_type)
+      && size_valid_p (wholebytes, object_size_type))
+    {
+      *psize = bytes;
+      if (pwholesize)
+	*pwholesize = wholebytes;
+      return true;
+    }
 
-  *psize = bytes;
-  if (pwholesize)
-    *pwholesize = wholebytes;
-  return true;
+  return false;
 }
 
 
@@ -1058,11 +1053,11 @@ compute_builtin_object_size (tree ptr, int object_size_type,
 	      tree offset = gimple_assign_rhs2 (def);
 	      ptr = gimple_assign_rhs1 (def);
 
-	      if (tree_fits_shwi_p (offset)
+	      if (((object_size_type & OST_DYNAMIC)
+		   || tree_fits_shwi_p (offset))
 		  && compute_builtin_object_size (ptr, object_size_type,
 						  psize))
 		{
-		  /* Return zero when the offset is out of bounds.  */
 		  *psize = size_for_offset (*psize, offset);
 		  return true;
 		}
@@ -1247,7 +1242,7 @@ call_object_size (struct object_size_info *osi, tree ptr, gcall *call)
   gcc_assert (osi->pass == 0);
   tree bytes = alloc_object_size (call, object_size_type);
 
-  if (!(object_size_type & OST_DYNAMIC) && TREE_CODE (bytes) != INTEGER_CST)
+  if (!size_valid_p (bytes, object_size_type))
     bytes = size_unknown (object_size_type);
 
   object_sizes_set (osi, varno, bytes, bytes);
@@ -1328,9 +1323,8 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
     return false;
 
   /* Handle PTR + OFFSET here.  */
-  if (TREE_CODE (op1) == INTEGER_CST
-      && (TREE_CODE (op0) == SSA_NAME
-	  || TREE_CODE (op0) == ADDR_EXPR))
+  if (size_valid_p (op1, object_size_type)
+      && (TREE_CODE (op0) == SSA_NAME || TREE_CODE (op0) == ADDR_EXPR))
     {
       if (TREE_CODE (op0) == SSA_NAME)
 	{
@@ -1358,6 +1352,10 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple *stmt)
   else
     bytes = wholesize = size_unknown (object_size_type);
 
+  if (!size_valid_p (bytes, object_size_type)
+      || !size_valid_p (wholesize, object_size_type))
+    bytes = wholesize = size_unknown (object_size_type);
+
   if (object_sizes_set (osi, varno, bytes, wholesize))
     osi->changed = true;
   return reexamine;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-01-11 14:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-11 14:48 [gcc r12-6482] tree-object-size: Dynamic sizes for ADDR_EXPR Siddhesh Poyarekar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).