Hi, Here's the patch set. This time, feature complete, and fully tested with no regressions. I'll send a reply with the test results in a moment.
v22 changes: - Move Link: tags to above the changelog, as Jason requested. - Update the tests for -pedantic-errors. Some tests are now errors instead of warnings. I've had to move some tests about GNU extensions to new test files, so now it's more granular. Some tests were removed, since I realized they were redundant while moving to smaller files. - Add <assert.h> (and NDEBUG) to some test files that were missing it, and also the forward declaration of strcmp(3). - Fix typos in dejagnu diagnostic comments. Is this ready to merge now, hopefully? :-) Have a lovely night! Alex Alejandro Colomar (3): c: Add _Countof operator c: Add <stdcountof.h> c: Add -Wpedantic diagnostic for _Countof gcc/Makefile.in | 1 + gcc/c-family/c-common.cc | 26 ++++ gcc/c-family/c-common.def | 3 + gcc/c-family/c-common.h | 2 + gcc/c/c-decl.cc | 22 +++- gcc/c/c-parser.cc | 63 +++++++-- gcc/c/c-tree.h | 4 + gcc/c/c-typeck.cc | 115 +++++++++++++++- gcc/doc/extend.texi | 30 +++++ gcc/ginclude/stdcountof.h | 31 +++++ gcc/testsuite/gcc.dg/countof-compat.c | 8 ++ gcc/testsuite/gcc.dg/countof-compile.c | 124 ++++++++++++++++++ gcc/testsuite/gcc.dg/countof-no-compat.c | 5 + .../gcc.dg/countof-pedantic-errors.c | 8 ++ gcc/testsuite/gcc.dg/countof-pedantic.c | 8 ++ gcc/testsuite/gcc.dg/countof-stdcountof.c | 25 ++++ gcc/testsuite/gcc.dg/countof-vla.c | 35 +++++ gcc/testsuite/gcc.dg/countof-vmt.c | 21 +++ gcc/testsuite/gcc.dg/countof-zero-compile.c | 38 ++++++ gcc/testsuite/gcc.dg/countof-zero.c | 32 +++++ gcc/testsuite/gcc.dg/countof.c | 121 +++++++++++++++++ 21 files changed, 698 insertions(+), 24 deletions(-) create mode 100644 gcc/ginclude/stdcountof.h create mode 100644 gcc/testsuite/gcc.dg/countof-compat.c create mode 100644 gcc/testsuite/gcc.dg/countof-compile.c create mode 100644 gcc/testsuite/gcc.dg/countof-no-compat.c create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic-errors.c create mode 100644 gcc/testsuite/gcc.dg/countof-pedantic.c create mode 100644 gcc/testsuite/gcc.dg/countof-stdcountof.c create mode 100644 gcc/testsuite/gcc.dg/countof-vla.c create mode 100644 gcc/testsuite/gcc.dg/countof-vmt.c create mode 100644 gcc/testsuite/gcc.dg/countof-zero-compile.c create mode 100644 gcc/testsuite/gcc.dg/countof-zero.c create mode 100644 gcc/testsuite/gcc.dg/countof.c Range-diff against v21: 1: 432081a4747 ! 1: 1c983c3baa7 c: Add _Countof operator @@ Commit message and somehow magically return the number of elements of the array, regardless of it being really a pointer. + Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3550.pdf> + Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117025> + Link: <https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/> + Link: <https://inbox.sourceware.org/gcc-patches/20240728141547.302478-1-...@kernel.org/T/#t> + Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf> + Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3325.pdf> + Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3369.pdf> + Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3469.htm> + Link: <https://github.com/llvm/llvm-project/issues/102836> + Link: <https://thephd.dev/the-big-array-size-survey-for-c> + Link: <https://thephd.dev/the-big-array-size-survey-for-c-results> + Link: <https://stackoverflow.com/questions/37538/#57537491> + gcc/ChangeLog: * doc/extend.texi: Document _Countof operator. @@ Commit message * gcc.dg/countof-compile.c * gcc.dg/countof-vla.c + * gcc.dg/countof-vmt.c + * gcc.dg/countof-zero-compile.c + * gcc.dg/countof-zero.c * gcc.dg/countof.c: Add tests for _Countof operator. - Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3550.pdf> - Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117025> - Link: <https://inbox.sourceware.org/gcc/m8s4oqy--...@tutanota.com/T/> - Link: <https://inbox.sourceware.org/gcc-patches/20240728141547.302478-1-...@kernel.org/T/#t> - Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf> - Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3325.pdf> - Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3369.pdf> - Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3469.htm> - Link: <https://github.com/llvm/llvm-project/issues/102836> - Link: <https://thephd.dev/the-big-array-size-survey-for-c> - Link: <https://thephd.dev/the-big-array-size-survey-for-c-results> - Link: <https://stackoverflow.com/questions/37538/#57537491> Suggested-by: Xavier Del Campo Romero <xavi....@tutanota.com> Co-authored-by: Martin Uecker <uec...@tugraz.at> Acked-by: "James K. Lowden" <jklow...@schemamania.org> @@ gcc/testsuite/gcc.dg/countof-compile.c (new) + +static int w[] = {1, 2, 3}; + -+static int z[0]; -+static int y[_Countof(z)]; -+ +void +completed (void) +{ @@ gcc/testsuite/gcc.dg/countof-compile.c (new) +} + +static int f1(); -+static int f2(); /* { dg-warning "never defined" } */ ++static int f2(); /* { dg-error "never defined" } */ +int a[10][9]; +int n; + @@ gcc/testsuite/gcc.dg/countof-compile.c (new) + + _Static_assert (_Countof (int [3][n]) == 3); + _Static_assert (_Countof (int [n][3]) == 7); /* { dg-error "not constant" } */ -+ _Static_assert (_Countof (int [0][3]) == 0); -+ _Static_assert (_Countof (int [0]) == 0); -+ _Static_assert (_Countof (int [0][n]) == 0); +} ## gcc/testsuite/gcc.dg/countof-vla.c (new) ## @@ gcc/testsuite/gcc.dg/countof-vla.c (new) + int (*x)[_Countof (*a)], + short (*)[_Generic(x, int (*)[3]: 1)]); + -+void zro_fix (int i, -+ char (*a)[0][5], -+ int (*x)[_Countof (*a)], -+ short (*)[_Generic(x, int (*)[3]: 1)]); -+void zro_var (int i, -+ char (*a)[0][i], /* dg-warn "variable" */ -+ int (*x)[_Countof (*a)], -+ short (*)[_Generic(x, int (*)[3]: 1)]); -+void zro_uns (int i, -+ char (*a)[0][*], -+ int (*x)[_Countof (*a)], -+ short (*)[_Generic(x, int (*)[3]: 1)]); -+ +void var_fix (int i, + char (*a)[i][5], /* dg-warn "variable" */ + int (*x)[_Countof (*a)]); /* dg-warn "variable" */ @@ gcc/testsuite/gcc.dg/countof-vla.c (new) +void uns_uns (int i, + char (*a)[*][*], + int (*x)[_Countof (*a)]); + + ## gcc/testsuite/gcc.dg/countof-vmt.c (new) ## +@@ ++/* { dg-do run } */ ++/* { dg-options "-std=c2y" } */ + -+static int z2[0]; -+static int y2[_Countof (z2)]; ++#undef NDEBUG ++#include <assert.h> ++ ++void ++inner_vla_noeval (void) ++{ ++ int i; ++ ++ i = 3; ++ static_assert (_Countof (struct {int x[i++];}[3]) == 3); ++ assert (i == 3); ++} ++ ++int ++main (void) ++{ ++ inner_vla_noeval (); ++} + + ## gcc/testsuite/gcc.dg/countof-zero-compile.c (new) ## +@@ ++/* { dg-do compile } */ ++/* { dg-options "-std=c2y" } */ ++ ++static int z[0]; ++static int y[_Countof (z)]; ++ ++_Static_assert(_Countof (y) == 0); ++ ++void ++completed (void) ++{ ++ int z[] = {}; ++ ++ static_assert (_Countof (z) == 0); ++} ++ ++void zro_fix (int i, ++ char (*a)[0][5], ++ int (*x)[_Countof (*a)], ++ short (*)[_Generic(x, int (*)[0]: 1)]); ++void zro_var (int i, ++ char (*a)[0][i], /* dg-warn "variable" */ ++ int (*x)[_Countof (*a)], ++ short (*)[_Generic(x, int (*)[0]: 1)]); ++void zro_uns (int i, ++ char (*a)[0][*], ++ int (*x)[_Countof (*a)], ++ short (*)[_Generic(x, int (*)[0]: 1)]); ++ ++void ++const_expr(void) ++{ ++ int n = 7; ++ ++ _Static_assert (_Countof (int [0][3]) == 0); ++ _Static_assert (_Countof (int [0]) == 0); ++ _Static_assert (_Countof (int [0][n]) == 0); ++} + + ## gcc/testsuite/gcc.dg/countof-zero.c (new) ## +@@ ++/* { dg-do run } */ ++/* { dg-options "-std=c2y" } */ ++ ++#undef NDEBUG ++#include <assert.h> ++ ++void ++vla (void) ++{ ++ unsigned n; ++ ++ n = 0; ++ int z[n]; ++ assert (_Countof (z) == 0); ++} ++ ++void ++matrix_vla (void) ++{ ++ int i; ++ ++ i = 0; ++ assert (_Countof (int [i++][4]) == 0); ++ assert (i == 0 + 1); ++} ++ ++int ++main (void) ++{ ++ vla (); ++ matrix_vla (); ++} ## gcc/testsuite/gcc.dg/countof.c (new) ## @@ @@ gcc/testsuite/gcc.dg/countof.c (new) + short a[7]; + + static_assert (_Countof (a) == 7); -+ static_assert (_Countof (long [0]) == 0); + static_assert (_Countof (unsigned [99]) == 99); +} + @@ gcc/testsuite/gcc.dg/countof.c (new) +completed (void) +{ + int a[] = {1, 2, 3}; -+ int z[] = {}; + + static_assert (_Countof (a) == 3); -+ static_assert (_Countof (z) == 0); +} + +void @@ gcc/testsuite/gcc.dg/countof.c (new) + + int v[n / 2]; + assert (_Countof (v) == 99 / 2); -+ -+ n = 0; -+ int z[n]; -+ assert (_Countof (z) == 0); +} + +void @@ gcc/testsuite/gcc.dg/countof.c (new) +} + +void -+inner_vla_noeval (void) -+{ -+ int i; -+ -+ i = 3; -+ static_assert (_Countof (struct {int x[i++];}[3]) == 3); -+ assert (i == 3); -+} -+ -+void +array_noeval (void) +{ + long a[5]; @@ gcc/testsuite/gcc.dg/countof.c (new) +} + +void -+matrix_zero (void) -+{ -+ int i; -+ -+ static_assert (_Countof (int [0][4]) == 0); -+ i = 3; -+ static_assert (_Countof (int [0][i]) == 0); -+} -+ -+void +matrix_fixed (void) +{ + int i; @@ gcc/testsuite/gcc.dg/countof.c (new) + assert (_Countof (int [i++][4]) == 7); + assert (i == 7 + 1); + -+ i = 0; -+ assert (_Countof (int [i++][4]) == 0); -+ assert (i == 0 + 1); -+ + i = 9; + j = 3; + assert (_Countof (int [i++][j]) == 9); @@ gcc/testsuite/gcc.dg/countof.c (new) + vla (); + member (); + vla_eval (); -+ inner_vla_noeval (); + array_noeval (); -+ matrix_zero (); + matrix_fixed (); + matrix_vla (); + no_parens (); 2: 46294255dd8 ! 2: 418f81175e7 c: Add <stdcountof.h> @@ gcc/testsuite/gcc.dg/countof-stdcountof.c (new) + +#include <stdcountof.h> + ++#undef NDEBUG ++#include <assert.h> ++ ++extern int strcmp (const char *, const char *); ++ +#ifndef countof +#error "countof not defined" +#endif @@ gcc/testsuite/gcc.dg/countof-stdcountof.c (new) +int +main (void) +{ -+ if (strcmp (xstr(countof), "_Alignas") != 0) -+ abort (); ++ assert (strcmp (xstr(countof), "_Countof") == 0); +} 3: 20cf2d14d3e ! 3: c44ef4a2c75 c: Add -Wpedantic diagnostic for _Countof @@ gcc/testsuite/gcc.dg/countof-compat.c (new) + +int a[1]; +int b[countof(a)]; -+int c[_Countof(a)]; /* { dg-warning "ISO C does not support" */ ++int c[_Countof(a)]; /* { dg-warning "ISO C does not support" } */ ## gcc/testsuite/gcc.dg/countof-no-compat.c (new) ## @@ @@ gcc/testsuite/gcc.dg/countof-pedantic-errors.c (new) + +int a[1]; +int b[countof(a)]; -+int c[_Countof(a)]; /* { dg-error "ISO C does not support" */ ++int c[_Countof(a)]; /* { dg-error "ISO C does not support" } */ ## gcc/testsuite/gcc.dg/countof-pedantic.c (new) ## @@ @@ gcc/testsuite/gcc.dg/countof-pedantic.c (new) + +int a[1]; +int b[countof(a)]; -+int c[_Countof(a)]; /* { dg-warning "ISO C does not support" */ ++int c[_Countof(a)]; /* { dg-warning "ISO C does not support" } */ -- 2.49.0