Hi Martin,
On Mon, Aug 05, 2024 at 06:05:15PM GMT, Martin Uecker wrote:
> >
> > However, if I turn on -Wvla, both get a warning:
> >
> > len.c: At top level:
> > len.c:288:1: warning: ISO C90 forbids variable length array ‘x’ [-Wvla]
> > 288 | void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
> > | ^~~~
> > len.c:289:1: warning: ISO C90 forbids variable length array ‘x’ [-Wvla]
> > 289 | void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);
> > | ^~~~
> >
>
> You should check the the result you get from __lengthof__
> is an integer constant expression in the first case.
>
> > I suspect that the problem is in:
> >
> > $ grepc -tfd array_type_nelts_minus_one gcc
> > gcc/tree.cc:tree
> > array_type_nelts_minus_one (const_tree type)
> > {
> > tree index_type, min, max;
> >
> > /* If they did it with unspecified bounds, then we should have already
> > given an error about it before we got here. */
> > if (! TYPE_DOMAIN (type))
> > return error_mark_node;
> >
> > index_type = TYPE_DOMAIN (type);
> > min = TYPE_MIN_VALUE (index_type);
> > max = TYPE_MAX_VALUE (index_type);
> >
> > /* TYPE_MAX_VALUE may not be set if the array has unknown length. */
> > if (!max)
> > {
> > /* zero sized arrays are represented from C FE as complete types
> > with
> > NULL TYPE_MAX_VALUE and zero TYPE_SIZE, while C++ FE represents
> > them as min 0, max -1. */
> > if (COMPLETE_TYPE_P (type)
> > && integer_zerop (TYPE_SIZE (type))
> > && integer_zerop (min))
> > return build_int_cst (TREE_TYPE (min), -1);
> >
> > return error_mark_node;
> > }
> >
> > return (integer_zerop (min)
> > ? max
> > : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
> > }
> >
> > With some debugging code, I've seen that in the fixed-length case, this
> > reaches the last return (integer_zerop() is true, so it returns max),
> > which is exactly the same as with any normal fixed-length array.
> >
> > In the variable-length case (i.e., [*][3]), it returns build_int_cst().
> >
> > So, it seems my problem is that 'max' does not represent an integer
> > constant, even though we know it is. Can we coerce it to an integer
> > constant somehow? Or maybe it's some of the in_lengthof that's messing
> > with me?
> >
>
> I would suspect the logic related to the C_MAYBE_CONST_EXPR.
> In your original patch this still used C_TYPE_VARIABLE_SIZE,
> which is not what we want for lengthof.Ahhh, I blindly pasted that from sizeof, IIRC. I'll check. Thanks a lot! > > > It is possible that you can not properly distinguish between > > > > > > int a[0][n]; > > > int a[*][n]; > > > > > > those two cases. The logic will treat the first as the second. > > > > Those can be distinguished. [0] triggers the zero test, while [*] > > triggers the second var test. > > Are you sure? Both types should have C_TYPE_VARIABLE_SIZE set to 1. You were right. They're the same. I was thinking of [0] vs [*], but [0][n] is bad. It gets treated as a VLA. I won't worry too much about it, since GCC doesn't properly support 0-length arrays. We'll have to worry about it if we start discussing full support for 0-length arrays. > > > I think this is ok for now. All this array stuff should be > > > implified and refactored anyway, but this is for another time. > > > > > > > > > I am also not sure you even need to use array_type_nelts in C > > > because there is never a non-zero minimum size. > > > > How should I get the number of elements without array_type_nelts()? Is > > there any other existing way to get it? It just had a good name that > > matched my grep, but maybe I'm missing something easier. > > Maybe it is ok, but there is also code which just adds one > to TYPE_MAX_VALUE. Hmmm. I'll check. > > Martin Cheers, Alex -- <https://www.alejandro-colomar.es/>
signature.asc
Description: PGP signature
