]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/109334: Improve computation for access attribute
authorMartin Uecker <uecker@tugraz.at>
Wed, 25 Oct 2023 21:24:34 +0000 (23:24 +0200)
committerMartin Uecker <uecker@tugraz.at>
Sun, 29 Oct 2023 06:47:36 +0000 (07:47 +0100)
The fix for PR104970 restricted size computations to the case
where the access attribute was specified explicitly (no VLA).
It also restricted it to void pointers or elements with constant
sizes.  The second restriction is enough to fix the original bug.
Revert the first change to again allow size computations for VLA
parameters and for VLA parameters together with an explicit access
attribute.

gcc/ChangeLog:

PR tree-optimization/109334
* tree-object-size.cc (parm_object_size): Allow size
computation for implicit access attributes.

gcc/testsuite/ChangeLog:

PR tree-optimization/109334
* gcc.dg/builtin-dynamic-object-size-0.c
(test_parmsz_simple3): Supported again.
(test_parmsz_external4): New test.
* gcc.dg/builtin-dynamic-object-size-20.c: New test.
* gcc.dg/pr104970.c: New test.

gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr104970.c [new file with mode: 0644]
gcc/tree-object-size.cc

index 6da04202ffed4d07100ce051c82305ed2b4fc6f7..07e3da6f254fbe4f09dff75ac30fa8661f018af0 100644 (file)
@@ -455,7 +455,6 @@ test_parmsz_simple2 (size_t sz, char obj[])
   return __builtin_dynamic_object_size (obj, 0);
 }
 
-/* Implicitly constructed access attributes not supported yet.  */
 size_t
 __attribute__ ((noinline))
 test_parmsz_simple3 (size_t sz, char obj[sz])
@@ -527,6 +526,13 @@ test_parmsz_internal3 (size_t sz1, size_t sz2, double obj[sz1][sz2])
   return __builtin_dynamic_object_size (obj, 0);
 }
 
+size_t
+__attribute__ ((noinline))
+test_parmsz_internal4 (size_t sz1, size_t sz2, double obj[sz1 + 1][4])
+{
+  return __builtin_dynamic_object_size (obj, 0);
+}
+
 /* Loops.  */
 
 size_t
@@ -721,8 +727,8 @@ main (int argc, char **argv)
   if (test_parmsz_simple2 (__builtin_strlen (argv[0]) + 1, argv[0])
       != __builtin_strlen (argv[0]) + 1)
     FAIL ();
-  /* Only explicitly added access attributes are supported for now.  */
-  if (test_parmsz_simple3 (__builtin_strlen (argv[0]) + 1, argv[0]) != -1)
+  if (test_parmsz_simple3 (__builtin_strlen (argv[0]) + 1, argv[0]) 
+      != __builtin_strlen (argv[0]) + 1)
     FAIL ();
   int arr[42];
   if (test_parmsz_scaled (arr, 42) != sizeof (arr))
@@ -759,6 +765,8 @@ main (int argc, char **argv)
     FAIL ();
   if (test_parmsz_internal3 (4, 4, obj) != -1)
     FAIL ();
+  if (test_parmsz_internal4 (3, 4, obj) != -1)
+    FAIL ();
   if (test_loop (arr, 42, 0, 32, 1) != 10 * sizeof (int))
     FAIL ();
   if (test_loop (arr, 42, 32, -1, -1) != 0)
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c
new file mode 100644 (file)
index 0000000..2c8e07d
--- /dev/null
@@ -0,0 +1,49 @@
+/* PR 109334 
+ * { dg-do run }
+ * { dg-options "-O1" } */
+
+
+[[gnu::noinline,gnu::noipa]]
+int f(int n, int buf[n])
+    [[gnu::access(read_only, 2, 1)]]
+{
+    return __builtin_dynamic_object_size(buf, 0);
+}
+
+[[gnu::noinline,gnu::noipa]]
+int g(int n, int buf[])
+    [[gnu::access(read_only, 2, 1)]]
+{
+    return __builtin_dynamic_object_size(buf, 0);
+}
+
+[[gnu::noinline,gnu::noipa]]
+int h(int n, int buf[n])
+{
+    return __builtin_dynamic_object_size(buf, 0);
+}
+
+int dummy(int x) { return x + 1; }
+
+[[gnu::noinline,gnu::noipa]]
+int i(int n, int buf[dummy(n)])
+{
+    return __builtin_dynamic_object_size(buf, 0);
+}
+
+int main()
+{
+    int n = 10;
+    int buf[n];
+    if (n * sizeof(int) != f(n, buf))
+        __builtin_abort();
+    if (n * sizeof(int) != g(n, buf))
+        __builtin_abort();
+    if (n * sizeof(int) != h(n, buf))
+        __builtin_abort();
+
+    (void)i(n, buf);
+    return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr104970.c b/gcc/testsuite/gcc.dg/pr104970.c
new file mode 100644 (file)
index 0000000..ce81654
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+__inline void
+memset2(void *__dest, int __ch, long __len) {
+  long __trans_tmp_1 = __builtin_dynamic_object_size(__dest, 0);
+  __builtin___memset_chk(__dest, __ch, __len, __trans_tmp_1);
+}
+
+void
+mleye(int l, double E[][l]) { memset2(E, 0, sizeof(double)); }
+
+
index a62af050056315fd63802e0f77e72f4eff52dbcd..28f27adf9ca2f2e86c527277cbb3a3a3e74a16ad 100644 (file)
@@ -1575,8 +1575,8 @@ parm_object_size (struct object_size_info *osi, tree var)
   tree typesize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (parm)));
   tree sz = NULL_TREE;
 
-  /* If we have an explicit access attribute with a usable size argument... */
-  if (access && access->sizarg != UINT_MAX && !access->internal_p
+  /* If we have an access attribute with a usable size argument... */
+  if (access && access->sizarg != UINT_MAX
       /* ... and either PARM is void * or has a type that is complete and has a
         constant size... */
       && ((typesize && poly_int_tree_p (typesize))
@@ -1587,10 +1587,14 @@ parm_object_size (struct object_size_info *osi, tree var)
       unsigned argpos = 0;
 
       /* ... then walk through the parameters to pick the size parameter and
-        safely scale it by the type size if needed.  */
+        safely scale it by the type size if needed.
+
+        TODO: we could also compute the size of VLAs where the size is
+        given by a function parameter.  */
       for (arg = fnargs; arg; arg = TREE_CHAIN (arg), ++argpos)
-       if (argpos == access->sizarg && INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+       if (argpos == access->sizarg)
          {
+           gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (arg)));
            sz = get_or_create_ssa_default_def (cfun, arg);
            if (sz != NULL_TREE)
              {