On Fri, 30 Jul 2021, Martin Sebor wrote:

> On 7/30/21 2:21 PM, Tom de Vries wrote:
> > On 7/30/21 6:17 PM, Martin Sebor wrote:
> >> On 7/28/21 9:20 AM, Tom de Vries wrote:
> >>> Hi,
> >>>
> >>> Improve nonnull attribute documentation in a number of ways:
> >>>
> >>> Reorganize discussion of effects into:
> >>> - effects for calls to functions with nonnull-marked parameters, and
> >>> - effects for function definitions with nonnull-marked parameters.
> >>> This makes it clear that -fno-delete-null-pointer-checks has no effect
> >>> for
> >>> optimizations based on nonnull-marked parameters in function definitions
> >>> (see PR100404).
> >>
> >> This resolves half of PR 101665 that I raised the other day (i.e.,
> >> updates the docs).  Thank you!
> > 
> > You're welcome :)
> > 
> >> Since PR 100404 was resolved as
> >> invalid,
> > 
> > Yeah, I can also live with reopening that one as documentation PR.
> > 
> >> can you please reference the other PR in the changelog?
> > 
> > Done.
> > 
> >> The other half (warning when attribute nonnull is specified along
> >> with attribute optimize "-fno-delete-null-pointer-checks") remains.
> >> I plan to look into it unless someone beats me to it or unless some
> >> other solution emerges.
> >>
> > 
> > FWIW, In my reply to Richi here (
> > https://gcc.gnu.org/pipermail/gcc-patches/2021-July/576415.html ) I
> > proposed to split the existing nonnull  attribute functionality into
> > assume_nonnull/verify_nonnull attributes.  I'm curious what you think of
> > that proposal.
> 
> I think it may have been worth considering at the time nonnull was
> being proposed but it's too late now.  Users are familiar with it
> under its current name, it's embedded in lots of code, and it's
> supported by GCC-compatible compilers.  Introducing a pair of new
> attributes with slightly different semantics would make it difficult
> to write code that's meant to be portable across these implementations
> (including prior versions of GCC).  Not to mention that it wouldn't
> help users of nonnull.

True.

> But since the problem is limited to function definitions, we don't
> need a solution for declarations.  What's missing is an intuitive
> way to tell GCC that an attribute on the declaration should not
> have an effect in its definition.  A nicer name for Andrew's asm
> trick.  Coming up with a generic enough name would make it usable
> for arguments with other attributes with similar effect (the only
> one that comes to mind at the moment is attribute access which
> also triggers warnings in function bodies, although it's not yet
> used for optimization; others might pop up in the future).

I think -fno-delete-null-pointer-checks covering exactly this case
would be OK.  I think we just want to make sure we're not losing
the warnings when functions are called with explicit NULL in that
case.

Richard.

> Martin
> 
> > 
> >> A few comments on the documentation changes below.
> >>
> >>>
> >>> Mention -Wnonnull-compare.
> >>>
> >>> Mention workaround from PR100404 comment 7.
> >>>
> >>> The workaround can be used for this scenario.  Say we have a test.c:
> >>> ...
> >>>    #include <stdlib.h>
> >>>
> >>>    extern int isnull (char *ptr) __attribute__ ((nonnull));
> >>>    int isnull (char *ptr)
> >>>    {
> >>>      if (ptr == 0)
> >>>        return 1;
> >>>      return 0;
> >>>    }
> >>>
> >>>    int
> >>>    main (void)
> >>>    {
> >>>      char *ptr = NULL;
> >>>      if (isnull (ptr)) __builtin_abort ();
> >>>      return 0;
> >>>    }
> >>> ...
> >>>
> >>> The test-case contains a mistake: ptr == NULL, and we want to detect the
> >>> mistake using an abort:
> >>> ...
> >>> $ gcc test.c
> >>> $ ./a.out
> >>> Aborted (core dumped)
> >>> ...
> >>>
> >>> At -O2 however, the mistake is not detected:
> >>> ...
> >>> $ gcc test.c -O2
> >>> $ ./a.out
> >>> ...
> >>> which is what -Wnonnull-compare (not show here) warns about.
> >>>
> >>> The easiest way to fix this is by dropping the nonnull attribute.  But
> >>> that
> >>> also disables -Wnonnull, which would detect something like:
> >>> ...
> >>>    if (isnull (NULL)) __builtin_abort ();
> >>> ...
> >>> at compile time.
> >>>
> >>> Using this workaround:
> >>> ...
> >>>    int isnull (char *ptr)
> >>>    {
> >>> +  asm ("" : "+r"(ptr));
> >>>      if (ptr == 0)
> >>>        return 1;
> >>>      return 0;
> >>>    }
> >>> ...
> >>> we still manage to detect the problem at runtime with -O2:
> >>> ...
> >>> $ ~/gcc_versions/devel/install/bin/gcc test.c -O2
> >>> $ ./a.out
> >>> Aborted (core dumped)
> >>> ...
> >>> while keeping the possibility to detect "isnull (NULL)" at compile time.
> >>>
> >>> OK for trunk?
> >>>
> >>> Thanks,
> >>> - Tom
> >>>
> >>> [gcc/doc] Improve nonnull attribute documentation
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>> 2021-07-28  Tom de Vries  <tdevr...@suse.de>
> >>>
> >>>      * doc/extend.texi (nonnull attribute): Improve documentation.
> >>>
> >>> ---
> >>>   gcc/doc/extend.texi | 51
> >>> ++++++++++++++++++++++++++++++++++++++++-----------
> >>>    1 file changed, 40 insertions(+), 11 deletions(-)
> >>>
> >>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> >>> index b83cd4919bb..3389effd70c 100644
> >>> --- a/gcc/doc/extend.texi
> >>> +++ b/gcc/doc/extend.texi
> >>> @@ -3488,17 +3488,46 @@ my_memcpy (void *dest, const void *src, size_t
> >>> len)
> >>>    @end smallexample
> >>>      @noindent
> >>> -causes the compiler to check that, in calls to @code{my_memcpy},
> >>> -arguments @var{dest} and @var{src} are non-null.  If the compiler
> >>> -determines that a null pointer is passed in an argument slot marked
> >>> -as non-null, and the @option{-Wnonnull} option is enabled, a warning
> >>> -is issued.  @xref{Warning Options}.  Unless disabled by
> >>> -the @option{-fno-delete-null-pointer-checks} option the compiler may
> >>> -also perform optimizations based on the knowledge that certain function
> >>> -arguments cannot be null. In addition,
> >>> -the @option{-fisolate-erroneous-paths-attribute} option can be specified
> >>> -to have GCC transform calls with null arguments to non-null functions
> >>> -into traps. @xref{Optimize Options}.
> >>> +informs the compiler that, in calls to @code{my_memcpy}, arguments
> >>> +@var{dest} and @var{src} must be non-null.
> >>> +
> >>> +The attribute has effect both for functions calls and function
> >>> definitions.
> >>
> >> Missing article: has <ins>an </ins> effect.  Also, an effect on
> >> (rather than for) might be more appropriate.
> >>
> > 
> > Done.
> > 
> >>> +
> >>> +For function calls:
> >>> +@itemize @bullet
> >>> +@item If the compiler determines that a null pointer is
> >>> +passed in an argument slot marked as non-null, and the
> >>> +@option{-Wnonnull} option is enabled, a warning is issued.
> >>> +@xref{Warning Options}.
> >>> +@item The @option{-fisolate-erroneous-paths-attribute} option can be
> >>> +specified to have GCC transform calls with null arguments to non-null
> >>> +functions into traps.  @xref{Optimize Options}.
> >>> +@item The compiler may also perform optimizations based on the
> >>> +knowledge that certain function arguments cannot be null.  These
> >>> +optimizations can be disabled by the
> >>> +@option{-fno-delete-null-pointer-checks} option. @xref{Optimize
> >>> Options}.
> >>> +@end itemize
> >>> +
> >>> +For function definitions:
> >>> +@itemize @bullet
> >>> +@item If the compiler determines that a function parameter that is
> >>> +marked with non-null
> >>
> >> Either no "with" or no hyphen in nonnull (when it names the attribute).
> >>
> > 
> > Done.
> > 
> >>> is compared with null, and
> >>> +@option{-Wnonnull-compare} option is enabled, a warning is issued.
> >>> +@xref{Warning Options}.
> >>> +@item The compiler may also perform optimizations based on the
> >>> +knowledge that certain function parameters cannot be null.
> >>
> >> "certain function parameters" makes me think it might include others
> >> besides those marked nonnull.  Unless that's the case, to avoid any
> >> doubt I'd suggest to rephrase that: say "based on the knowledge that
> >> @code{nonnul} parameters cannot be null."
> >>
> > 
> > Done.
> > 
> >>> This can
> >>> +be disabled by hiding the nonnullness using an inline assembly
> >>> statement:
> >>
> >> This is a clever trick but it feels more like a workaround than
> >> a solution to recommend.  I think I would find it preferable to
> >> accept and gracefully handle the combination of attribute nonnull
> >> and optimize ("-fno-delete-null-pointer-checks").  But that has
> >> the downside of disabling the removal of all such checks, not
> >> just those of the argument, and so doesn't seem like an optimal
> >> solution either.  So it seems like some other mechanism might be
> >> needed here.
> > 
> > Yeah, I hope the assume_nonnull / verify_nonnull is an acceptable way
> > forward.
> > 
> > Anyway, dropped the workaround from this version.
> > 
> > Thanks,
> > - Tom
> > 
> > 
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to