> Am 26.10.2023 um 13:51 schrieb Siddhesh Poyarekar <siddh...@gotplt.org>:
>
> On 2023-10-26 04:37, Martin Uecker wrote:
>> Hi Sid and Jakub,
>> here is the patch discussed in PR 109334.
>
> I can't approve, but here's a review:
Ok
Thanks for the review,
Richard
>> Martin
>> tree-optimization/109334: Improve computation for access attribute
>> 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 explicit access attributes.
>> gcc/testsuite/ChangeLog:
>> PR tree-optimization/109334
>> * gcc.dg/builtin-dynamic-object-size-20.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.
>> 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 6da04202ffe..07e3da6f254 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
>> @@ -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);
>> }
>
> This test case now works. OK.
>
>> +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);
>> +}
>> +
>
> New test case that isn't supported yet. OK.
>
>> /* 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
>> index 00000000000..2c8e07dd98d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-20.c
>> @@ -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);
>
> f(), g(), h() supported, but i() isn't. OK.
>
>> +
>> + return 0;
>> +}
>> +
>> diff --git a/gcc/testsuite/gcc.dg/pr104970.c
>> b/gcc/testsuite/gcc.dg/pr104970.c
>> new file mode 100644
>> index 00000000000..e24a7f22dfb
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pr104970.c
>> @@ -0,0 +1,13 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O1 -D_FORTIFY_SOURCE=2" } */
>
> The -D_FORTIFY_SOURCE=2 shouldn't be necessary since it doesn't really do
> anything in the context of this test.
>
>> +
>> +__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)); }
>
> New regression test for the ICE reported in pr104970. OK.
>
>> +
>> +
>> diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
>> index a62af050056..28f27adf9ca 100644
>> --- a/gcc/tree-object-size.cc
>> +++ b/gcc/tree-object-size.cc
>> @@ -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
>
> Dropped the unnecessary internal_p test. OK.
>
>> /* ... 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. */
>
> Isn't this testcase h() in builtin-dynamic-object-size-20.c? If you're
> referring to testcase i(), then maybe "where the size is given by a
> non-trivial function of a function parameter, e.g.
> fn (size_t n, char buf[dummy(n)])."
>
>> 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)
>> {
>
> We rely on the frontend to make sure that the arg at sizarg is an integral
> type. OK.
>
> Overall the change looks OK with a few nits I pointed out above.
>
> Thanks,
> Sid