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])
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
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))
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)
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* { 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)); }
+
+
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))
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)
{