[libvirt] [PATCH] util: Remove unnecessary ATTRIBUTE_NONNULL for virCommandAddArg[Pair]
Daniel P. Berrangé
berrange at redhat.com
Tue Dec 18 16:16:08 UTC 2018
On Tue, Dec 18, 2018 at 11:10:34AM -0500, John Ferlan wrote:
>
>
> On 12/18/18 10:47 AM, Daniel P. Berrangé wrote:
> > On Tue, Dec 18, 2018 at 10:39:20AM -0500, John Ferlan wrote:
> >> Commit 912c6b22 modified the virCommandAddArg and virCommandAddArgPair
> >> to perform NULL argument checking; however, no corresponding change
> >> to the prototypes was made to remove the ATTRIBUTE_NONNULL, so the
> >> Coverity build failed. Adjust the prototypes accordingly.
> >
> > This sounds wrong or at least different from the past.
> >
>
> I didn't push yet...
>
> The last time this happened is/was commit 425aac3abf.
>
> Still, before this patch if you build with STATIC_ANALYSIS set you'd see
> the same phenomena. If I modify config.h to have STATIC_ANALYSIS be 1
> instead of 0, I get:
>
> util/vircommand.c: In function 'virCommandAddArg':
> util/vircommand.c:1501:8: error: nonnull argument 'val' compared to NULL
> [-Werror=nonnull-compare]
> if (val == NULL) {
> ^
> util/vircommand.c: In function 'virCommandAddArgPair':
> util/vircommand.c:1604:14: error: nonnull argument 'name' compared to
> NULL [-Werror=nonnull-compare]
> if (name == NULL || val == NULL) {
> ^
> util/vircommand.c:1604:29: error: nonnull argument 'val' compared to
> NULL [-Werror=nonnull-compare]
> if (name == NULL || val == NULL) {
> ^
> Is there a different way you'd prefer this resolved? I could leave it as
> a my coverity environment only, but I would assume clang would be
> impacted too, although I don't use clang.
>
>
> > We have historically still added nonnull annotations even when
> > having checks for NULL in the impl. We had to explicitly disabble
> > the nonnull annotation when building under GCC to prevent it from
> > optimizing out the NULL checks. We left it enabled for STATIC_ANALYSIS
> > so that coverity would still report if any callers passed a NULL into
> > the methods.
> >
>
> That wasn't my recollection. Adding ATTRIBUTE_NONNULL has been "less
> important" because we found that it really only helps if someone calls
> some API with NULL and it does not help if the argument itself is NULL.
> My recollection is always towards removing it once the attribute itself
> was checked in the API. I also have a faint recollection of a discussion
> we've had before on this with the thought towards removing all the
> ATTRIBUTE_NONNULL's and replacing with real argument == NULL checks, but
> that got to be too many patches and checks in too many places.
This goes way back to this commit:
commit eefb881d4683d50882b43e5b28b0e94657cd0c9c
Author: Laine Stump <laine at laine.org>
Date: Wed Apr 25 16:10:01 2012 -0400
build: make ATTRIBUTE_NONNULL() a NOP unless STATIC_ANALYSIS is on
The ATTRIBUTE_NONNULL(m) macro normally resolves to the gcc builtin
__attribute__((__nonnull__(m))). The effect of this in gcc is
unfortunately only to make gcc believe that "m" can never possibly be
NULL, *not* to add in any checks to guarantee that it isn't ever NULL
(i.e. it is an optimization aid, *not* something to verify code
correctness.) - see the following gcc bug report for more details:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17308
Static source analyzers such as clang and coverity apparently can use
ATTRIBUTE_NONNULL(), though, to detect dead code (in the case that the
arg really is guaranteed non-NULL), as well as situations where an
obviously NULL arg is given to the function.
https://bugzilla.redhat.com/show_bug.cgi?id=815270 is a good example
of a bug caused by erroneous application of ATTRIBUTE_NONNULL().
Several people spent a long time staring at this code and not finding
the problem, because the problem wasn't in the function itself, but in
the prototype that specified ATTRIBUTE_NONNULL() for an arg that
actually *wasn't* always non-NULL, and caused a segv when dereferenced
(even though the code that dereferenced the pointer was inside an if()
that checked for a NULL pointer, that code was optimized out by gcc).
There may be some very small gain to be had from the optimizations
that can be inferred from ATTRIBUTE_NONNULL(), but it seems safer to
err on the side of generating code that behaves as expected, while
turning on the attribute for static analyzers.
We had methods doing "if (foo == NULL) return 0" and had code that
was (mistakenly) passing in NULL which would have been safe, except
gcc had deleted the "if (foo == NULL)" check. Rather than removing
all attribute(nonnull) checks, we merely disabling it under gcc. We
left it under STATIC_ANALYSIS so that coverity could still report on
places which passed an explicit NULL into a method annotated nonnull.
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list