From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id 1636C3990C0A for ; Wed, 28 Jul 2021 08:37:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1636C3990C0A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x42b.google.com with SMTP id l18so1490736wrv.5 for ; Wed, 28 Jul 2021 01:37:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=F0FJODZ5RIetoSN9nFJto5wWacBdusMQDBrPuQwOrX0=; b=YU7C+LfyP6DdLykB3OQVGC8iL1HPkfd5anoWKFH69ZfVHcXylYIYbg3yhblib+7PeY pCP0KmgJSQKCcPFHPZcYdyBashzkWL7ac+luyMIhEdcyA3gc2Kx6te08fTbiX7jS79+G svzi0twbEVvNOXkOp7JwHd4x6KMUOUjV1R67etsPCzJrbG1vKzJW/Q8loOqpL2YnDmzL Ntukm8bb8tnMuGZJVRXJ/pxg6m9wbirM4D8iLHCUiOb2Q8ETDL3lpIB5WmksbOFbeHsC 58MaazAoHowWYLZjw0DvXrbsWufyIDbNBQcR8kTwM0D7f3hQT/OsFdz5Lyb3fKH0cfPi 4osQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=F0FJODZ5RIetoSN9nFJto5wWacBdusMQDBrPuQwOrX0=; b=uiTBciZw0hnHpgWSYOuN5fFJ2WhdCoSmj1oyY81oBsarEklAQ3xgrE1fHoqOJPghvh wdZjfREQB0joetrHLfGBU1gVr0Jsh3gUPCYAIi7HSAZ9Mde7y3HeFR3UX6jodbeCMLQi wYS3r/b2Wu8/NKVIZegfzB+vAhBFIskBf/uxOLbXoHnfRadkUpc9Y/js8ldNQ8XA8FNk owFticZui8/FxRfy0NIwdionXH6JzYMxSaCnzmEwMnH9W3MQ224ps3mlVX9n7R1D4uBj j+VqOj6W7OR/CIouTZJzVz5RfM9tuddwAKJ8hCGGaXAurggP5QkMmGtzUrqn1QPcvmBZ O6zA== X-Gm-Message-State: AOAM5337+ZFHIQ6mQpTurOCp/Zovhde7BmnQElFIyA3bMGRgdejTpfsN dgeZPJAEnPlIzBrtk82AaKRtqw== X-Google-Smtp-Source: ABdhPJxKLS1QgHV2oYXJAs4XLXHSObXx4c3rsEQG1jGOfsbXhdgZeuoBEe+2QS6VR5piYqKbQPhX0g== X-Received: by 2002:a5d:67cc:: with SMTP id n12mr29358001wrw.131.1627461433160; Wed, 28 Jul 2021 01:37:13 -0700 (PDT) Received: from localhost (host86-161-16-194.range86-161.btcentralplus.com. [86.161.16.194]) by smtp.gmail.com with ESMTPSA id t15sm5908283wrx.17.2021.07.28.01.37.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Jul 2021 01:37:12 -0700 (PDT) Date: Wed, 28 Jul 2021 09:37:11 +0100 From: Andrew Burgess To: Tom de Vries Cc: Jan-Benedict Glaw , gdb@sourceware.org Subject: Re: Building with recent GCC versions: gdbsupport/gdb_assert.h:35:4: error: 'nonnull' argument 'filename' compared to NULL [-Werror=nonnull-compare] Message-ID: <20210728083711.GA9094@embecosm.com> References: <20210726211101.ivychvbfgaafxjtz@lug-owl.de> <20210727100354.GB4037238@embecosm.com> <20210727113511.GC4037238@embecosm.com> <6cf80ba9-b010-bb42-c92d-84e4f396813c@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux/5.8.18-100.fc31.x86_64 (x86_64) X-Uptime: 09:30:22 up 14:37, 1 user, X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2021 08:37:16 -0000 * Tom de Vries [2021-07-27 15:38:19 +0200]: > On 7/27/21 1:49 PM, Tom de Vries wrote: > > On 7/27/21 1:35 PM, Andrew Burgess wrote: > >> * Tom de Vries [2021-07-27 12:44:10 +0200]: > >> > >>> On 7/27/21 12:03 PM, Andrew Burgess wrote: > >>>> * Jan-Benedict Glaw [2021-07-26 23:11:01 +0200]: > >>>> > >>>>> Hi! > >>>>> > >>>>> I'm running some CI builds and noticed that, when building GDB with > >>>>> quite recent GCC versions, it breaks. > >>>>> > >>>>> With ie. this "gcc-snapshot" GCC from Debian: > >>>>> > >>>>> /usr/lib/gcc-snapshot/bin/gcc --version > >>>>> gcc (Debian 20210630-1) 12.0.0 20210630 (experimental) [master revision 6bf383c37e6:93c270320bb:35da8a98026849bd20d16bbf9210ac1d0b44ea6a] > >>>>> > >>>>> we see: > >>>>> > >>>>> ./configure --target=i686-linux --prefix=/tmp/gdb-i686-linux > >>>>> [...] > >>>>> all make V=1 all-gdb > >>>>> [...] > >>>>> [all 2021-07-26 20:39:22] /usr/lib/gcc-snapshot/bin/g++ -x c++ -I. -I. -I./config -DLOCALEDIR="\"/tmp/gdb-i686-linux/share/locale\"" -DHAVE_CONFIG_H -I./../include/opcode -I./../readline/readline/.. -I./../zlib -I../bfd -I./../bfd -I./../include -I../libdecnumber -I./../libdecnumber -I./../gnulib/import -I../gnulib/import -I./.. -I.. -DTUI=1 -I./.. -pthread -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-variable -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wsuggest-override -Wimplicit-fallthrough=3 -Wduplicated-cond -Wshadow=local -Wdeprecated-copy -Wdeprecated-copy-dtor -Wredundant-move -Wmissing-declarations -Wstrict-null-sentinel -Wformat -Wformat-nonliteral -Werror -g -O2 -c -o compile/compile.o -MT compile/compile.o -MMD -MP -MF compile/.deps/compile.Tpo compile/compile.c > >>>>> [all 2021-07-26 20:39:26] In file included from ./../gdbsupport/common-defs.h:126, > >>>>> [all 2021-07-26 20:39:26] from ./defs.h:28, > >>>>> [all 2021-07-26 20:39:26] from compile/compile.c:20: > >>>>> [all 2021-07-26 20:39:26] ./../gdbsupport/gdb_unlinker.h: In constructor 'gdb::unlinker::unlinker(const char*)': > >>>>> [all 2021-07-26 20:39:26] ./../gdbsupport/gdb_assert.h:35:4: error: 'nonnull' argument 'filename' compared to NULL [-Werror=nonnull-compare] > >>>>> [all 2021-07-26 20:39:26] 35 | ((void) ((expr) ? 0 : \ > >>>>> [all 2021-07-26 20:39:26] | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > >>>>> [all 2021-07-26 20:39:26] 36 | (gdb_assert_fail (#expr, __FILE__, __LINE__, FUNCTION_NAME), 0))) > >>>>> [all 2021-07-26 20:39:26] | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > >>>>> [all 2021-07-26 20:39:26] ./../gdbsupport/gdb_unlinker.h:38:5: note: in expansion of macro 'gdb_assert' > >>>>> [all 2021-07-26 20:39:26] 38 | gdb_assert (filename != NULL); > >>>>> [all 2021-07-26 20:39:26] | ^~~~~~~~~~ > >>>>> [all 2021-07-26 20:39:27] cc1plus: all warnings being treated as errors > >>>>> [all 2021-07-26 20:39:27] make[1]: *** [Makefile:1642: compile/compile.o] Error 1 > >>>>> [all 2021-07-26 20:39:27] make[1]: Leaving directory '/var/lib/laminar/run/gdb-i686-linux/4/binutils-gdb/gdb' > >>>>> [all 2021-07-26 20:39:27] make: *** [Makefile:11410: all-gdb] Error 2 > >>>>> > >>>>> > >>>>> I also discussed this on the GCC patches mailing list > >>>>> (https://gcc.gnu.org/pipermail/gcc-patches/2021-July/575568.html), > >>>>> where Martin suggested that this should be fixed here in GDB. > >>>>> > >>>>> Any thoughts about this? > >>>> > >>>> As I understand it the nonnull attribute only provides compile time > >>>> protection against explicitly passing NULL, there's no compiled in > >>>> non-null check (well, maybe with -fisolate-erroneous-paths-attribute, > >>>> but the assert might give a better error message). > >>>> > >>>> This means its still possible to pass NULL to a nonnull function, its > >>>> just the behaviour of the program is undefined in that case. > >>>> > >>>> So, it doesn't seem crazy that we might want to both (a) have a > >>>> function declared nonnull, to prevent explicitly passing NULL, and (b) > >>>> have a NULL check inside the function to catch logic bugs that result > >>>> in NULL being passed. > >>>> > >>>> We could, of course, push the assert outside of the function, but that > >>>> would really suck due to code duplication, and the risk of missing an > >>>> assert, so that seems like a non-starter. > >>>> > >>>> We could drop either the assert, or the nonnull attribute, but that > >>>> would suck as both give a valuable, but different form of protection. > >>>> > >>>> After some experimenting, I suspect that the assert is being optimised > >>>> away anyway, which kind of makes sense, as we're telling the compiler > >>>> it can assume that the pointer is non-null. > >>>> > >>> > >>> Yes, in fact that's what the nonnull-compare warning specifically warns > >>> against: there's some code that may be optimized away, due to the > >>> nonnull attribute. > >>> > >>>> So, what we probably want is someway to tell (or trick) GCC into > >>>> including the null check even in the nonnull function.... > >>>> > >>>> ... here's what I came up with, add this somewhere: > >>>> > >>>> template > >>>> bool __attribute__ ((noinline)) > >>>> nonnull_arg_is_really_not_null (const T *ptr) > >>>> { > >>>> return ptr != nullptr; > >>>> } > >>>> > >>>> then change the assert to: > >>>> > >>>> gdb_assert (nonnull_arg_is_really_not_null (filename)); > >>>> > >>>> Seems to keep the assert, and silence the warning. Thoughts? > >>>> > >>> > >>> I understand why it works, but it seems fragile to me. At some point > >>> some compiler may get smart enough to also optimize this case, and then > >>> we're back in the same situation. > >> > >> Good point. > >> > >> The GCC documentation for noinline[1] suggests we can avoid the call > >> being removed by adding 'asm ("");' into the function: > >> > >> template > >> bool __attribute__ ((noinline)) > >> nonnull_arg_is_really_not_null (const T *ptr) > >> { > >> asm (""); > >> return ptr != nullptr; > >> } > >> > >> I'm not really arguing for this approach over any other, just sharing > >> what I discovered. > >> > > > > Ack, understood. Note that the added asm doesn't stop a compiler from > > doing: > > ... > > gdb_assert (nonnull_arg_is_really_not_null (filename)); > > ... > > -> > > ... > > nonnull_arg_is_really_not_null (filename); > > gdb_assert (true); > > ... > > > > Thanks, > > - Tom > > > >> Thanks, > >> Andrew > >> > >> [1] https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes > >> > >>> > >>> I wonder whether using volatile is a better idea (can't try this out > >>> right now). > >>> > > I was thinking of something like this: > ... > diff --git a/gdbsupport/gdb_unlinker.h b/gdbsupport/gdb_unlinker.h > index bda6fe7ab54..3d99b41e7ad 100644 > --- a/gdbsupport/gdb_unlinker.h > +++ b/gdbsupport/gdb_unlinker.h > @@ -20,6 +20,13 @@ > #ifndef COMMON_GDB_UNLINKER_H > #define COMMON_GDB_UNLINKER_H > > +template > +const T *volatile > +ignore_nonnull (const T *ptr) > +{ > + return ptr; > +} > + > namespace gdb > { > > @@ -35,7 +42,7 @@ class unlinker > unlinker (const char *filename) ATTRIBUTE_NONNULL (2) > : m_filename (filename) > { > - gdb_assert (filename != NULL); > + gdb_assert (ignore_nonnull (filename) != NULL); > } > > ~unlinker () > ... > > This builds for me, though I haven't got a setup yet where the warning > reproduces, so I can't check whether it actually fixes things. I've been testing issues like this using: https://godbolt.org/z/nfhq6zb7q Your suggestion gives this error: error: 'volatile'-qualified return type is deprecated [-Werror=volatile] 21 | const T * volatile | ^~~~~ cc1plus: all warnings being treated as errors Compiler returned: 1 If we remove the volatile return type then of course GCC inlines and optimises out the assert. We could make the 'ignore_nonnull' noinline, but then we're basically back at my original suggestion. I suspect the only choice (right now) might be to do: template void __attribute__ ((noinline)) assert_nonnull (const T *ptr) { asm (""); gdb_assert (ptr != nullptr); } Then replace gdb_assert with 'assert_nonnull (filename)'. What we'd actually want is for 'assert_nonnull' to be a macro that passes through the file/function/line just like the existing assert does so that the failed assert can be reported in the correct place. The more I look at this the more it feels like this is something GCC should be able to help us with... Thanks, Andrew