Am Mittwoch, dem 07.08.2024 um 01:12 +0200 schrieb Alejandro Colomar:
Hi Alex, a coupled of comments below. > --- a/gcc/c/c-parser.cc > +++ b/gcc/c/c-parser.cc > @@ -74,7 +74,17 @@ along with GCC; see the file COPYING3. If not see > #include "bitmap.h" > #include "analyzer/analyzer-language.h" > #include "toplev.h" > + > +#define c_parser_sizeof_expression(parser) > \ > +( > \ > + c_parser_sizeof_or_lengthof_expression (parser, RID_SIZEOF) > \ > +) > > +#define c_parser_lengthof_expression(parser) > \ > +( > \ > + c_parser_sizeof_or_lengthof_expression (parser, RID_LENGTHOF) > \ > +) > + I suggest to avoid the macros. I think the original function calls are clear enough and this is then just another detour for somebody trying to follow the code. Or is there a reason I am missing? ... > diff --git a/gcc/testsuite/gcc.dg/lengthof-compile.c > b/gcc/testsuite/gcc.dg/lengthof-compile.c > new file mode 100644 > index 00000000000..6b44704ca7e > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/lengthof-compile.c > @@ -0,0 +1,49 @@ > +/* { dg-do compile } */ > +/* { dg-options "-Wno-declaration-after-statement -Wno-pedantic -Wno-vla" } > */ > + > +extern int x[]; > + > +void > +incomplete (int p[]) > +{ > + unsigned n; > + > + n = __lengthof__ (x); /* { dg-error "incomplete" } */ > + > + /* We want to support the following one in the future, > + but for now it should fail. */ > + n = __lengthof__ (p); /* { dg-error "invalid" } */ > +} > + > +void > +fam (void) > +{ > + struct { > + int x; > + int fam[]; > + } s; > + unsigned n; > + > + n = __lengthof__ (s.fam); /* { dg-error "incomplete" } */ > +} > + > +void fix_fix (int i, char (*a)[3][5], int (*x)[__lengthof__ (*a)]); > +void fix_var (int i, char (*a)[3][i], int (*x)[__lengthof__ (*a)]); > +void fix_uns (int i, char (*a)[3][*], int (*x)[__lengthof__ (*a)]); It would include a test that shows that when lengthof is applied to [*] that it remains formally non-constant. For example, you could test with -Wvla-parameter that the two declarations do not give a warning: void foo(char (*a)[*], int x[*]); void foo(char (*a)[*], int x[__lengthof__(*a)]); (With int (*x)[*] we would run into the issue that we can not distinguish zero arrays from unspecified ones, PR 98539) > + > +void > +func (void) > +{ > + int i3[3]; > + int i5[5]; > + char c35[3][5]; > + > + fix_fix (5, &c35, &i3); > + fix_fix (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ > + > + fix_var (5, &c35, &i3); > + fix_var (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ > + > + fix_uns (5, &c35, &i3); > + fix_uns (5, &c35, &i5); /* { dg-error "incompatible-pointer-types" } */ > +} > diff --git a/gcc/testsuite/gcc.dg/lengthof.c b/gcc/testsuite/gcc.dg/lengthof.c > new file mode 100644 > index 00000000000..38da5df52a5 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/lengthof.c > @@ -0,0 +1,127 @@ > +/* { dg-do run } */ > +/* { dg-options "-Wno-declaration-after-statement -Wno-pedantic -Wno-vla" } > */ > + > +#undef NDEBUG > +#include <assert.h> > + > +void > +array (void) > +{ > + short a[7]; > + > + assert (__lengthof__ (a) == 7); > + assert (__lengthof__ (long [0]) == 0); > + assert (__lengthof__ (unsigned [99]) == 99); > +} Instead of using assert you can use if (! ...) __builtin_abort(); to avoid the include in the testsuite. Otherwise it looks fine from my side. Joseph needs to approve and may have more comments. Martin