This series allows the nonnull attribute to be written directly on
function parameters (patches 1 and 3) and on C++ struct/class data
members (patch 2), rather than only on the function declaration with
a positional argument index.
void f (char * __attribute__ ((nonnull)) p, int n);
void g ([[gnu::nonnull]] char *p, int n);
struct X { [[gnu::nonnull]] int *p; };
The existing nonnull(N) syntax forces the programmer to count parameter
positions and keep numerical indices in sync with the declaration. When
parameters are added, removed, or reordered the indices silently become
wrong, and a reader must count across the parameter list to understand
which pointer must be non-null. Writing the attribute directly on the
constrained entity eliminates both problems.
Patch 1 adds the parameter-level nonnull support in both C and C++.
The attribute is rewritten into an internal "*nonnull parm" marker on
the PARM_DECL and synthesized back into a function-level nonnull(N) once
the parameter list is complete, so all existing -Wnonnull diagnostics
execute unchanged.
Patch 2 adds data-member-level nonnull for C++. A user-written nonnull
is stored as a "*nonnull field" marker on the FIELD_DECL and checked
during brace-enclosed aggregate initialization to diagnose null
initializers under -Wnonnull.
Patch 3 improves the diagnostic when nonnull appears on a non-function,
non-pointer declaration, since the old message ("only applies to function
types") is no longer accurate given the new valid targets.
Bootstrapped and regression-tested on x86_64-pc-linux-gnu.
OK for trunk?
Andrei Rusanescu (3):
c, c++: allow the nonnull attribute directly on a function parameter
c++: allow the nonnull attribute on a struct/class data member
c-family: improve nonnull diagnostic on non-function declarations
gcc/c-family/c-attribs.cc | 169 ++++++++++++++++++-
gcc/c-family/c-common.h | 2 +
gcc/c/c-decl.cc | 11 ++
gcc/cp/decl.cc | 65 ++++++-
gcc/cp/decl2.cc | 9 +-
gcc/cp/parser.cc | 13 +-
gcc/cp/typeck2.cc | 50 ++++++
gcc/doc/extend.texi | 47 ++++++
gcc/testsuite/g++.dg/warn/Wnonnull-field-1.C | 63 +++++++
gcc/testsuite/g++.dg/warn/Wnonnull-field-2.C | 12 ++
gcc/testsuite/g++.dg/warn/Wnonnull-field-3.C | 20 +++
gcc/testsuite/g++.dg/warn/Wnonnull-parm-1.C | 36 ++++
gcc/testsuite/g++.dg/warn/Wnonnull-parm-2.C | 14 ++
gcc/testsuite/g++.dg/warn/Wnonnull-var-1.C | 18 ++
gcc/testsuite/gcc.dg/Wnonnull-parm-1.c | 29 ++++
gcc/testsuite/gcc.dg/Wnonnull-var-1.c | 16 ++
16 files changed, 561 insertions(+), 13 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-field-1.C
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-field-2.C
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-field-3.C
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-parm-1.C
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-parm-2.C
create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull-var-1.C
create mode 100644 gcc/testsuite/gcc.dg/Wnonnull-parm-1.c
create mode 100644 gcc/testsuite/gcc.dg/Wnonnull-var-1.c
--
2.43.0