Le 08/11/2023 à 22:50, Pavel Sanda a écrit :
We have to do something for this annoying warning. What about the following?

If it works why not. I stopped following that gcc bug, but last time I looked
they gcc devs seemed convinced that false-positive ratio is small enough that
they will not care anymore (despite of ongoing grivance from other projects).
So the most appropriate response from our side seems to be just disable this
warning...

Here is a new version of the patch that
* is more readable in the sources (+1),
* handles the three functions that cause trouble (+1),
* can be reused for the other annoying warning that we have (+1),
* but relies on #pragma magic (-1) and preprocessor dark magic (-1).

I tested it on latest gcc and clang, and on the slightly older versions in Ubuntu 20.04.

I do not expect issues, except maybe on macOS and Windows compilers. The worst that can happen is a compilation failure.

Thoughts?

JMarc

PS: I have to say that I learned a lot while making this thing work!
From e93a8a431b0b7c3b283af420b571cec49daf44b3 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
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 certains
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
allow 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 misdetected. The worse that
can happen AFAIU is a couple 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 allow to make local changes to warnings. The 'ignored' ones allow
to diable 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<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
 ])
 
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<Impl> 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
 
-- 
2.40.1

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to