From e26188145238572580b9af18fbde4b824b341046 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Tue, 29 Sep 2015 14:19:47 +0200 Subject: Avoid unhelpful -Wunused-variable ...at least from "g++ (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)" with --disable-debug, when a namespace-scope const variable with a "complex" initializer declared in an include file remains unused. Avoid that warning via SAL_CONSTEXPR, which in turn requires large parts of o3tl::is_typed_flags to be SAL_CONSTEXPR, which in turn requires a new HAVE_CXX14_CONSTEXPR to allow assert in constexpr functions, which in turn requires using -std=c++14 instead of -std=c++11 where available, which in turn (a) requires to /not/ use -std=c++14 if it would run into a bug between Clang and libstdc++ discussed at "llvm-nm fails to build with gcc 5.1's libstdc++" (and which hits us in sfx2/source/control/thumbnailview.cxx), and (b) requires a new HAVE_CXX14_SIZED_DEALLOCATION to work around GCC 5.1 -Werror=sized-deallocation (where Clang >= 3.7 only supports C++14 sized deallocation when explictly enabled via -fsized-deallocation, btw). This effectively reverts ff6462e6307e6924dc6c8178043ae9032f4b4152 "avoid unused variable warning:" again. Change-Id: I424e3561452a3e6d8c8a9604d6c737cab49840c4 Reviewed-on: https://gerrit.libreoffice.org/18918 Reviewed-by: Stephan Bergmann Tested-by: Stephan Bergmann --- config_host/config_global.h.in | 2 ++ configure.ac | 56 +++++++++++++++++++++++++++-- include/o3tl/typed_flags_set.hxx | 73 +++++++++++++++++++++++++++----------- include/svx/dlgutil.hxx | 4 +-- sal/cpprt/operators_new_delete.cxx | 31 ++++++++++++++++ 5 files changed, 141 insertions(+), 25 deletions(-) diff --git a/config_host/config_global.h.in b/config_host/config_global.h.in index a029ff53c7e7..b2aa4da9353d 100644 --- a/config_host/config_global.h.in +++ b/config_host/config_global.h.in @@ -17,6 +17,8 @@ Any change in this header will cause a rebuild of almost everything. #define HAVE_CXX11_FINAL 0 #define HAVE_CXX11_PERFECT_FORWARDING 0 #define HAVE_CXX11_CONSTEXPR 0 +#define HAVE_CXX14_CONSTEXPR 0 +#define HAVE_CXX14_SIZED_DEALLOCATION 0 #define HAVE_GCC_BUILTIN_ATOMIC 0 /* _Pragma */ #define HAVE_GCC_PRAGMA_OPERATOR 0 diff --git a/configure.ac b/configure.ac index a84772b6932b..73855b01602e 100644 --- a/configure.ac +++ b/configure.ac @@ -6040,12 +6040,19 @@ if test "$COM" = MSC; then # MSVC supports (a subset of) CXX11 without any switch elif test "$GCC" = "yes"; then HAVE_CXX11= - AC_MSG_CHECKING([whether $CXX supports C++11]) - for flag in -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x ; do + AC_MSG_CHECKING([whether $CXX supports C++14 or C++11]) + for flag in -std=gnu++14 -std=gnu++1y -std=c++14 -std=c++1y -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x ; do save_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS $flag -Werror" AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[void f() {}]])],[CXXFLAGS_CXX11=$flag]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + void f(std::vector & v, std::function fn) { + std::sort(v.begin(), v.end(), fn); + } + ]])],[CXXFLAGS_CXX11=$flag]) AC_LANG_POP([C++]) CXXFLAGS=$save_CXXFLAGS if test -n "$CXXFLAGS_CXX11"; then @@ -6319,6 +6326,49 @@ if test "$cxx11_constexpr" = yes; then AC_DEFINE([HAVE_CXX11_CONSTEXPR]) fi +AC_MSG_CHECKING([whether $CXX supports C++14 constexpr]) +save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $CXXFLAGS_CXX11" +AC_LANG_PUSH([C++]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + struct S { + int n_; + constexpr bool f() { + int n = n_; + int i = 0; + while (n > 0) { --n; ++i; } + return i == 0; + } + }; + ]])], [cxx14_constexpr=yes], [cxx14_constexpr=no]) +AC_LANG_POP([C++]) +CXXFLAGS=$save_CXXFLAGS +AC_MSG_RESULT([$cxx14_constexpr]) +if test "$cxx14_constexpr" = yes; then + AC_DEFINE([HAVE_CXX14_CONSTEXPR]) +fi + +AC_MSG_CHECKING([whether $CXX supports C++14 sized deallocation]) +save_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $CXXFLAGS_CXX11" +AC_LANG_PUSH([C++]) +AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + void operator delete(void *) throw () { std::exit(1); } + void operator delete(void *, std::size_t) throw () { std::exit(0); } + struct S { S() { throw 0; } }; + ]],[[ + try { new S; } catch (...) {} + return 1; + ]])], [cxx14_sized_deallocation=yes], [cxx14_sized_deallocation=no]) +AC_LANG_POP([C++]) +CXXFLAGS=$save_CXXFLAGS +AC_MSG_RESULT([$cxx14_sized_deallocation]) +if test "$cxx14_sized_deallocation" = yes; then + AC_DEFINE([HAVE_CXX14_SIZED_DEALLOCATION]) +fi + HAVE_GCC_PRAGMA_OPERATOR= dnl _Pragma support (may require C++11) if test "$GCC" = "yes"; then diff --git a/include/o3tl/typed_flags_set.hxx b/include/o3tl/typed_flags_set.hxx index 4755c09fb536..9b8cb817ee02 100644 --- a/include/o3tl/typed_flags_set.hxx +++ b/include/o3tl/typed_flags_set.hxx @@ -25,18 +25,21 @@ #include #include +#include +#include + namespace o3tl { namespace detail { -template inline +template inline SAL_CONSTEXPR typename std::enable_if::value, bool>::type isNonNegative( T value) { return value >= 0; } -template inline +template inline SAL_CONSTEXPR typename std::enable_if::value, bool>::type isNonNegative(T) { return true; @@ -70,19 +73,23 @@ struct is_typed_flags { public: typedef is_typed_flags Unwrapped; - explicit Wrap(typename std::underlying_type::type value): + explicit SAL_CONSTEXPR Wrap( + typename std::underlying_type::type value): value_(value) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert(detail::isNonNegative(value)); assert((value & ~M) == 0); +#endif } - operator E() { return static_cast(value_); } + SAL_CONSTEXPR operator E() const { return static_cast(value_); } - explicit operator typename std::underlying_type::type() + explicit SAL_CONSTEXPR operator typename std::underlying_type::type() + const { return value_; } - explicit operator bool() { return value_ != 0; } + explicit SAL_CONSTEXPR operator bool() const { return value_ != 0; } private: typename std::underlying_type::type value_; @@ -94,17 +101,19 @@ struct is_typed_flags { } template -inline typename o3tl::typed_flags::Wrap operator ~(E rhs) { +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator ~(E rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( o3tl::typed_flags::mask & ~static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator ~( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator ~( typename o3tl::typed_flags::Wrap rhs) { return static_cast::Wrap>( @@ -113,44 +122,53 @@ inline typename o3tl::typed_flags::Wrap operator ~( } template -inline typename o3tl::typed_flags::Wrap operator ^(E lhs, E rhs) { +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator ^( + E lhs, E rhs) +{ +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) ^ static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator ^( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator ^( E lhs, typename o3tl::typed_flags::Wrap rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) ^ static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator ^( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator ^( typename o3tl::typed_flags::Wrap lhs, E rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) ^ static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator ^( +inline SAL_CONSTEXPR +typename o3tl::typed_flags::Wrap operator ^( W lhs, W rhs) { return static_cast( @@ -163,44 +181,53 @@ inline typename o3tl::typed_flags::Wrap operator ^( } template -inline typename o3tl::typed_flags::Wrap operator &(E lhs, E rhs) { +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator &( + E lhs, E rhs) +{ +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) & static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator &( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator &( E lhs, typename o3tl::typed_flags::Wrap rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) & static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator &( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator &( typename o3tl::typed_flags::Wrap lhs, E rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) & static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator &( +inline SAL_CONSTEXPR +typename o3tl::typed_flags::Wrap operator &( W lhs, W rhs) { return static_cast( @@ -213,44 +240,50 @@ inline typename o3tl::typed_flags::Wrap operator &( } template -inline typename o3tl::typed_flags::Wrap operator |(E lhs, E rhs) { +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator |(E lhs, E rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) | static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator |( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator |( E lhs, typename o3tl::typed_flags::Wrap rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(lhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) | static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator |( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator |( typename o3tl::typed_flags::Wrap lhs, E rhs) { +#if !HAVE_CXX11_CONSTEXPR || HAVE_CXX14_CONSTEXPR assert( o3tl::detail::isNonNegative( static_cast::type>(rhs))); +#endif return static_cast::Wrap>( static_cast::type>(lhs) | static_cast::type>(rhs)); } template -inline typename o3tl::typed_flags::Wrap operator |( +inline SAL_CONSTEXPR typename o3tl::typed_flags::Wrap operator |( W lhs, W rhs) { return static_cast( diff --git a/include/svx/dlgutil.hxx b/include/svx/dlgutil.hxx index c60fd93ca35f..284d3554cdbb 100644 --- a/include/svx/dlgutil.hxx +++ b/include/svx/dlgutil.hxx @@ -33,8 +33,8 @@ SVX_DLLPUBLIC FieldUnit GetModuleFieldUnit( const SfxItemSet& ); SVX_DLLPUBLIC FieldUnit GetModuleFieldUnit(); SVX_DLLPUBLIC bool GetApplyCharUnit( const SfxItemSet& ); -#define OUTPUT_DRAWMODE_COLOR DrawModeFlags::Default -#define OUTPUT_DRAWMODE_CONTRAST (DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient) +SAL_CONSTEXPR DrawModeFlags const OUTPUT_DRAWMODE_COLOR = DrawModeFlags::Default; +SAL_CONSTEXPR DrawModeFlags const OUTPUT_DRAWMODE_CONTRAST = DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient; #endif diff --git a/sal/cpprt/operators_new_delete.cxx b/sal/cpprt/operators_new_delete.cxx index 064caa5946f5..5fbd9c09be7d 100644 --- a/sal/cpprt/operators_new_delete.cxx +++ b/sal/cpprt/operators_new_delete.cxx @@ -18,8 +18,11 @@ */ #include +#include #include #include + +#include #include #include @@ -152,6 +155,20 @@ void SAL_CALL operator delete (void * p) throw () deallocate (p, ScalarTraits()); } +#if HAVE_CXX14_SIZED_DEALLOCATION +#if defined __clang__ +#pragma GCC diagnostic push // as happens on Mac OS X: +#pragma GCC diagnostic ignored "-Wimplicit-exception-spec-mismatch" +#endif +void SAL_CALL operator delete (void * p, std::size_t) noexcept +{ + deallocate (p, ScalarTraits()); +} +#if defined __clang__ +#pragma GCC diagnostic pop +#endif +#endif + // T * p = new(nothrow) T; delete(nothrow) p; void* SAL_CALL operator new (std::size_t n, std::nothrow_t const &) throw () @@ -176,6 +193,20 @@ void SAL_CALL operator delete[] (void * p) throw () deallocate (p, VectorTraits()); } +#if HAVE_CXX14_SIZED_DEALLOCATION +#if defined __clang__ +#pragma GCC diagnostic push // as happens on Mac OS X: +#pragma GCC diagnostic ignored "-Wimplicit-exception-spec-mismatch" +#endif +void SAL_CALL operator delete[] (void * p, std::size_t) noexcept +{ + deallocate (p, VectorTraits()); +} +#if defined __clang__ +#pragma GCC diagnostic pop +#endif +#endif + // T * p = new(nothrow) T[n]; delete(nothrow)[] p; void* SAL_CALL operator new[] (std::size_t n, std::nothrow_t const &) throw () -- cgit