[gdb/build] Fix Werror=nonnull-compare build breaker with gcc 12 When building gdb using current gcc trunk, we run into: ... gdbsupport/gdb_unlinker.h: \ In constructor 'gdb::unlinker::unlinker(const char*)': gdbsupport/gdb_assert.h:35:4: error: \ 'nonnull' argument 'filename' compared to NULL [-Werror=nonnull-compare] 35| ((void) ((expr) ? 0 : \ | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 36| (gdb_assert_fail (#expr, __FILE__, __LINE__, FUNCTION_NAME), 0))) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gdbsupport/gdb_unlinker.h:38:5: note: in expansion of macro 'gdb_assert' 38| gdb_assert (filename != NULL); | ^~~~~~~~~~ cc1plus: all warnings being treated as errors make[1]: *** [compile/compile.o] Error 1 ... The warning triggers in this code: ... unlinker (const char *filename) ATTRIBUTE_NONNULL (2) : m_filename (filename) { gdb_assert (filename != NULL); } ... The attribute nonnull (applied here to the filename parameter) has two effects: - if the compiler determines that a null pointer is passed in argument filename, and the -Wnonnull option is enabled, a warning is issued. - the compiler may perform optimizations based on the knowledge that filename != NULL (unless disabled by the -fno-delete-null-pointer-checks option). The warning Werror=nonnull-compare warns that the compiler may perform the optimization: .... gdb_assert (filename != NULL); ... -> ... gdb_assert (true); ... in which case "unlinker (obfuscated_NULL)" no longer will trigger the assert. And we want to keep the gdb_assert to detect cases that -Wnonnull doesn't detect. We could simply fix this by dropping the attribute, but that means that we no longer get the -Wnonnull warning. Fix this by ignoring the nonnull attribute using a function: ... template const T *volatile ignore_nonnull (const T *ptr) { return ptr; } ... such that we can do: ... gdb_assert (ignore_nonnull (filename) != NULL); ... Build on x86_64-linux using "gcc version 12.0.0 20210727 (experimental) (GCC)" build from gcc commit 7ffba77d01a. Reported-By: Jan-Benedict Glaw gdb/ChangeLog: 2021-07-27 Andrew Burgess Tom de Vries * gdbsupport/gdb_assert.h (ignore_nonnull): New function. * gdb/gdb_regex.c (compiled_regex::compiled_regex): Use ignore_nonnull to ignore nonnull attribute on function parameter. * gdbsupport/gdb_unlinker.h (unlinker::unlinker): Same. --- gdb/gdb_regex.c | 4 ++-- gdbsupport/gdb_assert.h | 6 ++++++ gdbsupport/gdb_unlinker.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gdb/gdb_regex.c b/gdb/gdb_regex.c index 17fbfd28ee8..22473f57e26 100644 --- a/gdb/gdb_regex.c +++ b/gdb/gdb_regex.c @@ -22,8 +22,8 @@ compiled_regex::compiled_regex (const char *regex, int cflags, const char *message) { - gdb_assert (regex != NULL); - gdb_assert (message != NULL); + gdb_assert (ignore_nonnull (regex) != NULL); + gdb_assert (ignore_nonnull (message) != NULL); int code = regcomp (&m_pattern, regex, cflags); if (code != 0) diff --git a/gdbsupport/gdb_assert.h b/gdbsupport/gdb_assert.h index 00553a78613..26a9594e7f8 100644 --- a/gdbsupport/gdb_assert.h +++ b/gdbsupport/gdb_assert.h @@ -58,4 +58,10 @@ internal_error (__FILE__, __LINE__, _(message)) #endif +template +const T *volatile +ignore_nonnull (const T *ptr) +{ + return ptr; +} #endif /* COMMON_GDB_ASSERT_H */ diff --git a/gdbsupport/gdb_unlinker.h b/gdbsupport/gdb_unlinker.h index bda6fe7ab54..4aa4f3fc3e9 100644 --- a/gdbsupport/gdb_unlinker.h +++ b/gdbsupport/gdb_unlinker.h @@ -35,7 +35,7 @@ class unlinker unlinker (const char *filename) ATTRIBUTE_NONNULL (2) : m_filename (filename) { - gdb_assert (filename != NULL); + gdb_assert (ignore_nonnull (filename) != NULL); } ~unlinker ()