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.
This commit is contained in:
Jean-Marc Lasgouttes 2023-11-08 18:07:14 +01:00
parent 3698281943
commit c2653e451c
4 changed files with 35 additions and 0 deletions

View File

@ -313,6 +313,33 @@ char * strerror(int n);
# define USE_WCHAR_T # define USE_WCHAR_T
#endif #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<warn> 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 <warn> 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 #endif
]) ])

View File

@ -181,8 +181,10 @@ private:
extern Movers & theMovers(); extern Movers & theMovers();
LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference)
/// @c returns the Mover registered for format @c fmt. /// @c returns the Mover registered for format @c fmt.
extern Mover const & getMover(std::string const & 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 /** Register a specialised @c command to be used to copy a file
* of format @c fmt. * of format @c fmt.
*/ */

View File

@ -36,7 +36,9 @@ private:
std::unique_ptr<Impl> d; std::unique_ptr<Impl> d;
}; };
LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference)
WordList & theWordList(std::string const & lang); WordList & theWordList(std::string const & lang);
LYX_END_MUTE_GCC_WARNING
} // namespace lyx } // namespace lyx

View File

@ -177,8 +177,12 @@ class Font;
class FontInfo; class FontInfo;
/// Implementation is in Application.cpp /// Implementation is in Application.cpp
LYX_BEGIN_MUTE_GCC_WARNING(dangling-reference)
frontend::FontMetrics const & theFontMetrics(Font const & f); frontend::FontMetrics const & theFontMetrics(Font const & f);
frontend::FontMetrics const & theFontMetrics(FontInfo const & fi); frontend::FontMetrics const & theFontMetrics(FontInfo const & fi);
LYX_END_MUTE_GCC_WARNING
} // namespace lyx } // namespace lyx