From fed7c3deb3f4ec81f78967c2d7f3c4554398cb9d Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Fri, 18 Jan 2019 16:13:57 +0100 Subject: [PATCH] Slience bogus -Werror=maybe-uninitialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...as emitted by at least GCC 8.2 with --enable-optimized, e.g. at: > In file included from include/rtl/ustring.hxx:37, > from include/cppuhelper/factory.hxx:26, > from unoxml/source/rdf/librdf_repository.hxx:24, > from unoxml/source/rdf/librdf_repository.cxx:20: > include/rtl/string.hxx: In static member function ‘static std::shared_ptr<{anonymous}::librdf_TypeConverter::Node> {anonymous}::librdf_TypeConverter::extractNode_NoLock(const com::sun::star::uno::Reference&)’: > include/rtl/string.hxx:294:27: error: ‘*((void*)(& type)+8).rtl::OString::pData’ may be used uninitialized in this function [-Werror=maybe-uninitialized] > rtl_string_release( pData ); > ~~~~~~~~~~~~~~~~~~^~~~~~~~~ > unoxml/source/rdf/librdf_repository.cxx:2094:30: note: ‘*((void*)(& type)+8).rtl::OString::pData’ was declared here > boost::optional type; > ^~~~ This appears to be a common pattern of false positives with uses of boost::optional, common enough to disable the warning globally for affected compilers, even if there would also be useful findings by that warning (e.g., "Fix -Werror=maybe-uninitialized"). I didn't bother to file a GCC bug for the reproducer used in configure.ac, already shows lots of open bugs in that area, and the documentation at states that "GCC may not be able to determine when the code is correct in spite of appearing to have an error." (Clang appears to not support -Wmaybe-uninitialized at all, so exclude it from the configure.ac check, to not have the check's failure result in an unsupported -Wno-maybe-uninitialized end up on the compiler command line.) Change-Id: Ifb9ca4c342750eae54f7e1a01506101310484c7e Reviewed-on: https://gerrit.libreoffice.org/66621 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- config_host.mk.in | 1 + configure.ac | 57 ++++++++++++++++++++++++++ solenv/gbuild/platform/com_GCC_defs.mk | 4 ++ 3 files changed, 62 insertions(+) diff --git a/config_host.mk.in b/config_host.mk.in index 55a4c00c8219..aa64c32b77ab 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -244,6 +244,7 @@ export GTK_PRINT_CFLAGS=$(gb_SPACE)@GTK_PRINT_CFLAGS@ export GTK_PRINT_LIBS=$(gb_SPACE)@GTK_PRINT_LIBS@ export USING_X11=@USING_X11@ export HAMCREST_JAR=@HAMCREST_JAR@ +export HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED=@HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED@ export HAVE_GCC_AVX=@HAVE_GCC_AVX@ export HAVE_GCC_STACK_PROTECTOR_STRONG=@HAVE_GCC_STACK_PROTECTOR_STRONG@ export HAVE_GCC_BUILTIN_ATOMIC=@HAVE_GCC_BUILTIN_ATOMIC@ diff --git a/configure.ac b/configure.ac index fe0d792ba7fe..19f1f5803d5e 100644 --- a/configure.ac +++ b/configure.ac @@ -6540,6 +6540,63 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ CXXFLAGS=$save_CXXFLAGS AC_LANG_POP([C++]) +dnl At least GCC 8.2 with -O2 (i.e., --enable-optimized) causes a false-positive -Wmaybe- +dnl uninitialized warning for code like +dnl +dnl OString f(); +dnl boost::optional * g(bool b) { +dnl boost::optional o; +dnl if (b) o = f(); +dnl return new boost::optional(o); +dnl } +dnl +dnl (as is e.g. present, in a slightly more elaborate form, in +dnl librdf_TypeConverter::extractNode_NoLock in unoxml/source/rdf/librdf_repository.cxx); the below +dnl code is meant to be a faithfully stripped-down and self-contained version of the above code: +HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED= +if test "$GCC" = yes && test "$COM_IS_CLANG" != TRUE; then + AC_MSG_CHECKING([whether $CXX might report false -Werror=maybe-uninitialized]) + AC_LANG_PUSH([C++]) + save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $CXXFLAGS_CXX11 -Werror -Wmaybe-uninitialized" + if test "$ENABLE_OPTIMIZED" = TRUE; then + CXXFLAGS="$CXXFLAGS -O2" + else + CXXFLAGS="$CXXFLAGS -O0" + fi + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + void f1(int); + struct S1 { + ~S1() { f1(n); } + int n = 0; + }; + struct S2 { + S2() {} + S2(S2 const & s) { if (s.init) set(*reinterpret_cast(s.stg)); } + ~S2() { if (init) reinterpret_cast(stg)->S1::~S1(); } + void set(S1 s) { + new (stg) S1(s); + init = true; + } + bool init = false; + char stg[sizeof (S1)]; + } ; + S1 f2(); + S2 * f3(bool b) { + S2 o; + if (b) o.set(f2()); + return new S2(o); + } + ]])], [AC_MSG_RESULT([no])], [ + HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED=TRUE + AC_MSG_RESULT([yes]) + ]) + CXXFLAGS=$save_CXXFLAGS + AC_LANG_POP([C++]) +fi +AC_SUBST([HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED]) + dnl =================================================================== dnl system stl sanity tests dnl =================================================================== diff --git a/solenv/gbuild/platform/com_GCC_defs.mk b/solenv/gbuild/platform/com_GCC_defs.mk index 1048a1375327..14d82ccdc0e2 100644 --- a/solenv/gbuild/platform/com_GCC_defs.mk +++ b/solenv/gbuild/platform/com_GCC_defs.mk @@ -79,6 +79,10 @@ gb_CXXFLAGS_COMMON := \ -fno-common \ -pipe \ +ifeq ($(HAVE_BROKEN_GCC_WMAYBE_UNINITIALIZED),TRUE) +gb_CXXFLAGS_COMMON += -Wno-maybe-uninitialized +endif + gb_CXXFLAGS_Wundef = -Wno-undef ifeq ($(ENABLE_GDB_INDEX),TRUE)