From c2653e451cd4ffb162a25267f86ad40d0c956f61 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 8 Nov 2023 18:07:14 +0100 Subject: [PATCH] Avoid dangling-reference warning in several places This new warning in gcc 13 is annoying because it happens in certain parts of our code where it is harmless to pass a temporary variable to a function that returns a reference. This patch introduces a new pair of macros, LYX_BEGIN_MUTE_GCC_WARNING(warn) and LYX_END_MUTE_GCC_WARNING, which can be used to define a block of code where a given GCC warning is disabled. The macros are no-ops with compilers other than gcc, although some compilers that pretend to be GCC make be mis-detected. The worse that can happen AFAIU is a bunch of warnings. The macro relies on an intimidating set of for nested macros. The goal of these macros is to build a nested string bit by bit. Here is how it works: PRAGMA_IGNORE(dangling-reference) => PRAGMA_IGNORE_1(-Wdangling-reference) => PRAGMA_IGNORE_2("-Wdangling-reference") => PRAGMA_IGNORE_3(GCC diagnostic ignored "-Wdangling-reference") => _Pragma("GCC diagnostic ignored \""-Wdangling-reference\"") The next question is: what is _Pragma() good for? Well, it is a version of #pragma that can be used in a macro. And finally, what are those pragmas good for? The 'push' and 'pop' ones make changes to warnings local. The 'ignored' ones allow to disable some warnings. And disabling -Wpragmas ensures that we do not have a warning if we try to disable a warning that is not supported by the compiler. --- configure.ac | 27 +++++++++++++++++++++++++++ src/Mover.h | 2 ++ src/WordList.h | 2 ++ src/frontends/FontMetrics.h | 4 ++++ 4 files changed, 35 insertions(+) diff --git a/configure.ac b/configure.ac index e3fcb8285b..6688cbfb94 100644 --- a/configure.ac +++ b/configure.ac @@ -313,6 +313,33 @@ char * strerror(int n); # define USE_WCHAR_T #endif +#if defined(__GNUC__) && !defined(__clang__) +/* This macro can be used to stipulate that a given GCC warning is not + * relevant in a given block. + * + * The -Wpragmas bit takes care of the case where -W is not implemented + * + * The idea for PRAGMA_IGNORE has been stolen from + * https://stackoverflow.com/questions/45762357/how-to-concatenate-strings-in-the-arguments-of-pragma#comment124444258_45783809 + * The difficulty is to put the value inside nested quotes; it is done + * using nested macros. + */ +# define PRAGMA_IGNORE(x) PRAGMA_IGNORE_1(-W##x) +# define PRAGMA_IGNORE_1(x) PRAGMA_IGNORE_2(#x) +# define PRAGMA_IGNORE_2(x) PRAGMA_IGNORE_3(GCC diagnostic ignored x) +# define PRAGMA_IGNORE_3(x) _Pragma(#x) +# define LYX_BEGIN_MUTE_GCC_WARNING(warn) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wpragmas\"") \ + PRAGMA_IGNORE(warn) +# define LYX_END_MUTE_GCC_WARNING \ + _Pragma("GCC diagnostic pop") +#else +# define LYX_BEGIN_MUTE_GCC_WARNING(warn) +# define LYX_END_MUTE_GCC_WARNING +#endif + + #endif ]) diff --git a/src/Mover.h b/src/Mover.h index a684a87557..1cd3698e72 100644 --- a/src/Mover.h +++ b/src/Mover.h @@ -181,8 +181,10 @@ private: extern Movers & theMovers(); +LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference) /// @c returns the Mover registered for format @c fmt. extern Mover const & getMover(std::string const & fmt); +LYX_END_MUTE_GCC_WARNING /** Register a specialised @c command to be used to copy a file * of format @c fmt. */ diff --git a/src/WordList.h b/src/WordList.h index 2afd6cb050..9819a31bbe 100644 --- a/src/WordList.h +++ b/src/WordList.h @@ -36,7 +36,9 @@ private: std::unique_ptr d; }; +LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference) WordList & theWordList(std::string const & lang); +LYX_END_MUTE_GCC_WARNING } // namespace lyx diff --git a/src/frontends/FontMetrics.h b/src/frontends/FontMetrics.h index f3952706ae..c1b7e028eb 100644 --- a/src/frontends/FontMetrics.h +++ b/src/frontends/FontMetrics.h @@ -177,8 +177,12 @@ class Font; class FontInfo; /// Implementation is in Application.cpp + +LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference) frontend::FontMetrics const & theFontMetrics(Font const & f); frontend::FontMetrics const & theFontMetrics(FontInfo const & fi); +LYX_END_MUTE_GCC_WARNING + } // namespace lyx