Hi,

Changes in v2:

-  Fix author.
-  Fix inconsistencies with actual arrays, by not folding array
   parameter size expressions.
-  Document that -farray-parameters-are-const would close a hole in this
   feature.

At the bottom is a range-diff.

The related ISO C2y proposal is alx-0054 (currently, there's no
N-document yet for this proposal).  The proposed wording in that
proposal is:

        Proposed wording
                Based on N3550.

            6.5.4.5  The sizeof, _Countof, and alignof operators
                @@ Constraints, p1
                ...
                 The _Countof operator shall only be applied to
                 an expression that has a complete array type,
                -or to the parenthesized name of such a type.
                +or to the parenthesized name of such a type,
                +or to a <b>const</b>-qualified array parameter of specified 
size.
                ...

                @@ Semantics, p5
                 The _Countof operator yields
                 the number of elements of its operand.
                 The number of elements is determined from
                 the type of the operand.
                +If the operand is an array parameter,
                +the number of elements is determined from
                +the array type used in its declaration.
                 The result is an integer.
                 If the number of elements of the array type is variable,
                 the operand is evaluated;
                 otherwise,
                 the operand is not evaluated
                 and the expression is an integer constant expression.

However, this patch is intended as a GNU extension first, and is not
affected by the deficient specification of [n] in the standard.

Here, we've implemented this as taking the number of elements declared
in the declarator in which it is used.  That's the obvious thing to do,
and given our semantics for [n], it's self-consistent within GCC.  And
it wouldn't make sense to standardize any other behavior, FWIW, which is
why I think we don't need to hear the committee: either they standardize
this in the future, or they don't, but we can't end up with something
incompatible.


Have a lovely night!
Alex


Alejandro Colomar (1):
  c: Add support for array parameters in _Countof

 gcc/c/c-typeck.cc                             | 50 ++++++++++--
 gcc/doc/extend.texi                           | 11 +++
 gcc/testsuite/gcc.dg/countof-compile.c        |  8 +-
 gcc/testsuite/gcc.dg/countof-param-compile.c  | 78 +++++++++++++++++++
 gcc/testsuite/gcc.dg/countof-param-pedantic.c | 11 +++
 gcc/testsuite/gcc.dg/countof-param.c          | 25 ++++++
 6 files changed, 168 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/countof-param-compile.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-param-pedantic.c
 create mode 100644 gcc/testsuite/gcc.dg/countof-param.c

Range-diff against v1:
1:  b5e67c7fb806 ! 1:  120e200700d5 c: Add support for array parameters in 
_Countof
    @@
      ## Metadata ##
    -Author: Martin Uecker <uec...@tugraz.at>
    +Author: Alejandro Colomar <a...@kernel.org>
     
      ## Commit message ##
         c: Add support for array parameters in _Countof
    @@ Commit message
         This extension will allow using _Countof() in more places, reducing the
         chances of specifying an incorrect size accidentally.
     
    -    Due to how the array information is stored, it sometimes decays less
    -    than real arrays, and sometimes decays more.  This might be a bit
    -    surprising, but only results in benign differences, that don't seem
    -    error-prone or dangerous.
    +    We should eventually add -farray-parameters-are-const to make array
    +    parameters be implicitly const-qualified (similar to -Wwrite-strings).
    +
    +    Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121271>
     
         gcc/ChangeLog:
     
    @@ gcc/c/c-typeck.cc: c_expr_countof_expr (location_t loc, struct c_expr 
expr)
     +      tree type = TREE_TYPE (folded_expr);
     +      if (POINTER_TYPE_P (type))
     +  {
    -+    if (tree rv = c_array_parm_orig_type (folded_expr))
    ++    if (tree rv = c_array_parm_orig_type (expr.value))
     +      {
     +        pedwarn (input_location, OPT_Wpedantic,
     +                 "ISO C does not support array parameters in %qs",
    @@ gcc/testsuite/gcc.dg/countof-param-compile.c (new)
     +  _Countof (typeof (a));  /* { dg-error "invalid" } */
     +  _Countof (a + 1);  /* { dg-error "invalid" } */
     +  _Countof (42 ? NULL : a);  /* { dg-error "invalid" } */
    ++  _Countof (a + 0);  /* { dg-error "invalid" } */
    ++  _Countof (&*a);  /* { dg-error "invalid" } */
    ++  _Countof (42, a);  /* { dg-error "invalid" } */
    ++  _Countof (42 ? a : a);  /* { dg-error "invalid" } */
    ++  _Countof (42 ? a : NULL);  /* { dg-error "invalid" } */
     +
     +  int *p = a;
     +
    @@ gcc/testsuite/gcc.dg/countof-param-compile.c (new)
     +  _Countof (a2);  /* { dg-error "invalid" } */
     +}
     +
    -+/* These would decay if they were arrays, but being a parameter, it's 
works.  */
    -+void
    -+no_decay_surprising (int a[2])
    -+{
    -+  _Static_assert (2 == _Countof (a + 0));
    -+  _Static_assert (2 == _Countof (&*a));
    -+  _Static_assert (2 == _Countof (42, a));
    -+  _Static_assert (2 == _Countof (42 ? a : a));
    -+  _Static_assert (2 == _Countof (42 ? a : NULL));
    -+}
    -+
     +void
     +no_decay_obvious (int a[2])
     +{
    @@ gcc/testsuite/gcc.dg/countof-param-compile.c (new)
     +decay_surprising (int a[2])
     +{
     +  _Countof (*(&a + 1));  /* { dg-error "invalid" } */
    ++}
    ++
    ++/* We should warn: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121271>. 
 */
    ++void
    ++non_const (int a[2])
    ++{
    ++  a++;
    ++  _Countof (a);
     +}
     
      ## gcc/testsuite/gcc.dg/countof-param-pedantic.c (new) ##

base-commit: a440b382e43203857de9195eb526c4a16f21ceb1
-- 
2.50.1

Reply via email to