Am Sonntag, dem 04.08.2024 um 10:25 +0200 schrieb Alejandro Colomar:
> Hi Martin,
> 
> On Sun, Aug 04, 2024 at 07:38:49AM GMT, Martin Uecker wrote:
> > Am Sonntag, dem 04.08.2024 um 01:17 +0200 schrieb Alejandro Colomar:
> > > 
> > > FUTURE DIRECTIONS:
> > > 
> > >   We could make it work with array parameters to functions, and
> > >   somehow magically return the length designator of the array,
> > >   regardless of it being really a pointer.
> > 
> > And maybe flexible array members with "counted_by" attribute.
> 
> Hmmm; I didn't know that one.  Indeed.  I'll have a look at implementing
> that in this patch set.

But maybe wait for this:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116016

> 
> > > +
> > > +/* Implement the lengthof keyword: Return the length of an array,
> > > +   that is, the number of elements in the array.  */
> > > +
> > > +tree
> > > +c_lengthof_type (location_t loc, tree type)
> > > +{
> > > +  enum tree_code type_code;
> > > +
> > > +  type_code = TREE_CODE (type);
> > > +  if (!COMPLETE_TYPE_P (type))
> > > +    {
> > > +      error_at (loc,
> > > +         "invalid application of %<lengthof%> to incomplete type %qT",
> > > +         type);
> > > +      return error_mark_node;
> > > +    }
> > > +  if (type_code != ARRAY_TYPE)
> > > +    {
> > > +      error_at (loc, "invalid application of %<lengthof%> to type %qT", 
> > > type);
> > > +      return error_mark_node;
> > > +    }
> > 
> > I would swap these two errors, because the first is more specific and
> > less helpful if you pass an incomplete struct, where it would be better
> > to get the second error.
> 
> Agree.
> 
> BTW, I still don't understand what `if (! TYPE_DOMAIN (type))` means,
> within array_type_nelts_minus_one().  What code triggers that condition?
> Am I missing error handling for that?  Thanks!

For incomplete arrays, basically we have the following different
variants for arrays:

T[ ] incomplete: !TYPE_DOMAIN 
T[1] constant size: TYPE_MAX_VALUE == INTEGER_CST
T[n] variable size: TYPE_MAX_VALUE != INTEGER_CST
T[0] flexible array member: !TYPE_MAX_VALUE && !C_TYPE_VARIABLE_SIZE
  (ISO version T[0] has TYPE_SIZE == NULL_TREE)
T[*] unspecified variable size: !TYPE_MAX_VALUE && C_TYPE_VARIABLE_SIZE

The first should give an error. The next two should work giving an
integer constant expression or run-time size, respectively. 
The ISO FAM case should also give an error, while the GNU fam case
could return zero to be consistent with sizeof (not sure). The last 
case should return a non-constant.

If you reuse the sizeof code, it should be mostly correct, but
maybe the last case needs to be revisted. In the following
examples

void foo(char (*a)[3][*], int (*x)[__lengthof__(*a)]);
void bar(char (*a)[*][3], int (*x)[__lengthof__(*a)]);

the array '*x' should be a regular fixed size array in foo
but a VLA in 'bar'.


Martin





Reply via email to