From 3d278ee75fa88634b23a3dbee42db9bd52a1c617 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 17:50:37 +0200 Subject: [PATCH 1/7] Avoid warnings about operations on different enums in C++20 mode Arithmetic operations on the elements of different enums are deprecated in C++20 and the latest compiler versions warn about them. While individual warnings could be fixed in wxWidgets itself (although it would be quite an effort to do it for all ~500 of them), it wouldn't help with the same warnings in the applications using wx, so prefer to do it by explicitly defining the operations on the enums that can be combined with each other by using wxALLOW_COMBINING_ENUMS() macro, except for a single warning in wxTar code where it's easier to just not use an anum at all. --- include/wx/aui/auibook.h | 1 + include/wx/defs.h | 32 ++++++++++++++++++++++++++++ include/wx/richtext/richtextbuffer.h | 2 ++ include/wx/toolbar.h | 4 +++- src/common/tarstrm.cpp | 4 +--- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/wx/aui/auibook.h b/include/wx/aui/auibook.h index dc3f509510..23d66ade71 100644 --- a/include/wx/aui/auibook.h +++ b/include/wx/aui/auibook.h @@ -55,6 +55,7 @@ enum wxAuiNotebookOption wxAUI_NB_MIDDLE_CLICK_CLOSE }; +wxALLOW_COMBINING_ENUMS(wxAuiNotebookOption, wxBorder) diff --git a/include/wx/defs.h b/include/wx/defs.h index d98dac5354..07533d00f6 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -1255,6 +1255,28 @@ typedef double wxDouble; /* Geometric flags */ /* ---------------------------------------------------------------------------- */ +/* + In C++20 operations on the elements of different enums are deprecated and + many compilers (clang 10+, gcc 11+, MSVS 2019) warn about combining them, + as a lot of existing code using them does, so we provide explicit operators + for doing this, that do the same thing as would happen without them, but + without the warnings. + */ +#if defined(__cplusplus) && (__cplusplus >= 202002L) + #define wxALLOW_COMBINING_ENUMS_IMPL(en1, en2) \ + inline int operator|(en1 v1, en2 v2) \ + { return static_cast(v1) | static_cast(v2); } \ + inline int operator+(en1 v1, en2 v2) \ + { return static_cast(v1) + static_cast(v2); } + + #define wxALLOW_COMBINING_ENUMS(en1, en2) \ + wxALLOW_COMBINING_ENUMS_IMPL(en1, en2) \ + wxALLOW_COMBINING_ENUMS_IMPL(en2, en1) +#else /* !C++ 20 */ + /* Don't bother doing anything in this case. */ + #define wxALLOW_COMBINING_ENUMS(en1, en2) +#endif /* C++ 20 */ + enum wxGeometryCentre { wxCENTRE = 0x0001, @@ -1380,6 +1402,16 @@ enum wxBorder /* This makes it easier to specify a 'normal' border for a control */ #define wxDEFAULT_CONTROL_BORDER wxBORDER_SUNKEN +/* + Elements of these enums can be combined with each other when using + wxSizer::Add() overload not using wxSizerFlags. + */ +wxALLOW_COMBINING_ENUMS(wxAlignment, wxDirection) +wxALLOW_COMBINING_ENUMS(wxAlignment, wxGeometryCentre) +wxALLOW_COMBINING_ENUMS(wxAlignment, wxStretch) +wxALLOW_COMBINING_ENUMS(wxDirection, wxStretch) +wxALLOW_COMBINING_ENUMS(wxDirection, wxGeometryCentre) + /* ---------------------------------------------------------------------------- */ /* Window style flags */ /* ---------------------------------------------------------------------------- */ diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 13e1dfb867..132667c50c 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -345,6 +345,8 @@ enum wxTextBoxAttrPosition wxTEXT_BOX_ATTR_POSITION_MASK = 0x00F0 }; +wxALLOW_COMBINING_ENUMS(wxTextAttrUnits, wxTextAttrValueFlags) + /** @class wxTextAttrDimension diff --git a/include/wx/toolbar.h b/include/wx/toolbar.h index 3aacb1f27d..f6a3a766f0 100644 --- a/include/wx/toolbar.h +++ b/include/wx/toolbar.h @@ -17,7 +17,7 @@ // wxToolBar style flags // ---------------------------------------------------------------------------- -enum +enum wxToolBarStyleFlags { // lay out the toolbar horizontally wxTB_HORIZONTAL = wxHORIZONTAL, // == 0x0004 @@ -61,6 +61,8 @@ enum wxTB_DEFAULT_STYLE = wxTB_HORIZONTAL }; +wxALLOW_COMBINING_ENUMS(wxToolBarStyleFlags, wxBorder) + #if wxUSE_TOOLBAR #include "wx/tbarbase.h" // the base class for all toolbars diff --git a/src/common/tarstrm.cpp b/src/common/tarstrm.cpp index 30b584e41d..7324b3ac3c 100644 --- a/src/common/tarstrm.cpp +++ b/src/common/tarstrm.cpp @@ -58,9 +58,7 @@ enum { TAR_NUMFIELDS }; -enum { - TAR_BLOCKSIZE = 512 -}; +static const int TAR_BLOCKSIZE = 512; // checksum type enum { From 7f246330de8ad310dad7527ef00eee9192abdf1b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:02:19 +0200 Subject: [PATCH 2/7] Remove wrong template arguments from wxArgNormalized ctors Ctor of a template class specialization shouldn't actually repeat the specialized template arguments, as it was done in 65cbf40b7e (Add wxNO_UNSAFE_WXSTRING_CONV2 macro, 2019-10-21), so remove them because this doesn't compile with g++ 11, even though it (wrongly?) did with the previous gcc versions. --- include/wx/strvararg.h | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index 0abf59b1b3..a565079771 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -295,7 +295,7 @@ struct wxFormatStringArgumentFinder : public wxFormatStringArgumentFinder { #ifdef wxNO_IMPLICIT_WXSTRING_ENCODING private: - wxFormatStringArgumentFinder(); // Disabled + wxFormatStringArgumentFinder(); // Disabled #endif // wxNO_IMPLICIT_WXSTRING_ENCODING }; @@ -308,7 +308,7 @@ struct wxFormatStringArgumentFinder : public wxFormatStringArgumentFinder { #ifdef wxNO_IMPLICIT_WXSTRING_ENCODING private: - wxFormatStringArgumentFinder(); // Disabled + wxFormatStringArgumentFinder(); // Disabled #endif // wxNO_IMPLICIT_WXSTRING_ENCODING }; @@ -409,7 +409,7 @@ struct wxFormatStringSpecifier template<> struct wxFormatStringSpecifier \ { \ private: \ - wxFormatStringSpecifier(); /* Disabled */ \ + wxFormatStringSpecifier(); /* Disabled */ \ }; wxFORMAT_STRING_SPECIFIER(bool, wxFormatString::Arg_Int) @@ -689,42 +689,37 @@ struct wxArgNormalizerWchar template<> struct wxArgNormalizer { private: - wxArgNormalizer(const char*, const wxFormatString *, - unsigned); + wxArgNormalizer(const char*, const wxFormatString *, unsigned); const char *get() const; }; template<> struct wxArgNormalizer { private: - wxArgNormalizer(const char*, const wxFormatString *, unsigned); + wxArgNormalizer(const char*, const wxFormatString *, unsigned); char *get() const; }; template<> struct wxArgNormalizer { private: - wxArgNormalizer(const std::string&, - const wxFormatString *, unsigned); + wxArgNormalizer(const std::string&, const wxFormatString *, unsigned); std::string get() const; }; template<> struct wxArgNormalizer { private: - wxArgNormalizer(std::string&, - const wxFormatString *, unsigned); + wxArgNormalizer(std::string&, const wxFormatString *, unsigned); std::string get() const; }; template<> struct wxArgNormalizer { private: - wxArgNormalizer(wxCharBuffer&, - const wxFormatString *, unsigned); + wxArgNormalizer(wxCharBuffer&, const wxFormatString *, unsigned); std::string get() const; }; template<> struct wxArgNormalizer { private: - wxArgNormalizer(wxScopedCharBuffer&, - const wxFormatString *, unsigned); + wxArgNormalizer(wxScopedCharBuffer&, const wxFormatString *, unsigned); std::string get() const; }; #endif // wxNO_IMPLICIT_WXSTRING_ENCODING From 51cb0e53b1d4b88bbe36bb3c1f048b43d7511dcc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:07:08 +0200 Subject: [PATCH 3/7] Use wxMEMBER_DELETE instead of "Disabled" comment No real changes, but this is more clear and should result in better error messages. --- include/wx/strvararg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/wx/strvararg.h b/include/wx/strvararg.h index a565079771..95f2369263 100644 --- a/include/wx/strvararg.h +++ b/include/wx/strvararg.h @@ -295,7 +295,7 @@ struct wxFormatStringArgumentFinder : public wxFormatStringArgumentFinder { #ifdef wxNO_IMPLICIT_WXSTRING_ENCODING private: - wxFormatStringArgumentFinder(); // Disabled + wxFormatStringArgumentFinder() wxMEMBER_DELETE; #endif // wxNO_IMPLICIT_WXSTRING_ENCODING }; @@ -308,7 +308,7 @@ struct wxFormatStringArgumentFinder : public wxFormatStringArgumentFinder { #ifdef wxNO_IMPLICIT_WXSTRING_ENCODING private: - wxFormatStringArgumentFinder(); // Disabled + wxFormatStringArgumentFinder() wxMEMBER_DELETE; #endif // wxNO_IMPLICIT_WXSTRING_ENCODING }; @@ -409,7 +409,7 @@ struct wxFormatStringSpecifier template<> struct wxFormatStringSpecifier \ { \ private: \ - wxFormatStringSpecifier(); /* Disabled */ \ + wxFormatStringSpecifier() wxMEMBER_DELETE; \ }; wxFORMAT_STRING_SPECIFIER(bool, wxFormatString::Arg_Int) From ffc3168f6f726195831bc00acc3d835e5970e72d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:46:33 +0200 Subject: [PATCH 4/7] Make wxFontBase::operator==() symmetric by taking wxFontBase Taking wxFont here resulted in a potential ambiguity when comparing wxFont objects, at least according to clang 12 in C++20 mode. Avoid this by just taking wxFontBase here, as now the operator is fully symmetric, rather than exactly matching only (wxFontBase, wxFont) and matching (wxFont, wxFont) either directly or with reversed arguments order. --- include/wx/font.h | 4 ++-- src/common/fontcmn.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/wx/font.h b/include/wx/font.h index 938e6aeaf1..428840d3b3 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -395,8 +395,8 @@ public: #endif // wxUSE_PRIVATE_FONTS // comparison - bool operator==(const wxFont& font) const; - bool operator!=(const wxFont& font) const { return !(*this == font); } + bool operator==(const wxFontBase& font) const; + bool operator!=(const wxFontBase& font) const { return !(*this == font); } // accessors: get the font characteristics virtual int GetPointSize() const; diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index 3ae09d0f49..96082ed375 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -425,7 +425,7 @@ bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info) return false; } -bool wxFontBase::operator==(const wxFont& font) const +bool wxFontBase::operator==(const wxFontBase& font) const { // either it is the same font, i.e. they share the same common data or they // have different ref datas but still describe the same font From c85267184ed537be29d6ea53a8b249f793f212ca Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:50:30 +0200 Subject: [PATCH 5/7] Simplify wxDataFormat comparison and avoid clang warning Comparing wxDataFormat directly with wxDF_XXX is supposed to work too and doing it like this avoids -Wambiguous-reversed-operator from clang 12. --- src/gtk/clipbrd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gtk/clipbrd.cpp b/src/gtk/clipbrd.cpp index 8cd7b1644d..07fcf02ce3 100644 --- a/src/gtk/clipbrd.cpp +++ b/src/gtk/clipbrd.cpp @@ -317,7 +317,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), // use UTF8_STRING format if requested in Unicode build but just plain // STRING one in ANSI or if explicitly asked in Unicode #if wxUSE_UNICODE - if (format == wxDataFormat(wxDF_UNICODETEXT)) + if (format == wxDF_UNICODETEXT) { gtk_selection_data_set_text( selection_data, From ccbf0b2f9a5bff7efe62c418825583be049b332c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:53:26 +0200 Subject: [PATCH 6/7] Define wxDataFormat comparison operator overload taking it itself We still can't avoid defining the overload taking NativeFormat due to an ambiguity that we would have otherwise between converting from NativeFormat to wxDataFormat or vice versa when comparing them (it would have been better to avoid implicit conversions in all directions, of course, but this is how it was done back in e1ee679c2e (wxDataObejct and related changes (won't compile right now), 1999-10-21) and it's too late to change it now), but we can at least define an overload taking wxDataFormat itself and not wxDataFormatId to make things slightly more logical and avoid -Wambiguous-reversed-operator clang 12 warnings. --- include/wx/gtk/dataform.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/wx/gtk/dataform.h b/include/wx/gtk/dataform.h index 9389a99765..ae5a2c232b 100644 --- a/include/wx/gtk/dataform.h +++ b/include/wx/gtk/dataform.h @@ -33,15 +33,18 @@ public: wxDataFormat& operator=(NativeFormat format) { SetId(format); return *this; } - // comparison (must have both versions) + // comparison (note that we rely on implicit conversions for comparison + // with wxDataFormatId, but have to provide them explicitly for comparison + // with NativeFormat to avoid ambiguity between comparing from it to + // wxDataFormat or vice versa) bool operator==(NativeFormat format) const { return m_format == (NativeFormat)format; } bool operator!=(NativeFormat format) const { return m_format != (NativeFormat)format; } - bool operator==(wxDataFormatId format) const - { return m_type == (wxDataFormatId)format; } - bool operator!=(wxDataFormatId format) const - { return m_type != (wxDataFormatId)format; } + bool operator==(const wxDataFormat& other) const + { return m_format == other.m_format; } + bool operator!=(const wxDataFormat& other) const + { return m_format != other.m_format; } // explicit and implicit conversions to NativeFormat which is one of // standard data types (implicit conversion is useful for preserving the From 95c98a0b5ff71caca6654327bf341719c6587766 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 25 Apr 2021 18:16:29 +0200 Subject: [PATCH 7/7] Work around -Wuggest-override for event table macros from gcc 11 Disabling -Wsuggest-override inside macros is broken in gcc, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578, and has started affecting wxWARNING_SUPPRESS_MISSING_OVERRIDE since gcc 11, i.e. this macro doesn't have any effect any more and the warning is still given. Avoid it by actually specifying "override" for gcc 11 (as doing it for all compilers would result in -Winconsistent-missing-override from clang) and check that we don't get this warning in the allheaders test. Also don't use wxDECLARE_ABSTRACT_CLASS() inside wxObject itself, now that it uses "override", which is not appropriate for the base class version. This is arguably more clear and should have been done like this since the beginning anyhow. --- include/wx/defs.h | 11 +++++++++++ include/wx/event.h | 4 ++-- include/wx/object.h | 5 +++-- include/wx/rtti.h | 2 +- tests/allheaders.cpp | 27 +++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index 07533d00f6..629706b1c8 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -740,6 +740,17 @@ typedef short int WXTYPE; # define wxWARNING_RESTORE_MISSING_OVERRIDE() #endif +/* + Macros above don't work with gcc 11 due to a compiler bug, unless we also + use "override" in the function declaration -- but this breaks other + compilers, so define a specific macro for gcc 11 only. + */ +#if wxCHECK_GCC_VERSION(11, 0) +# define wxDUMMY_OVERRIDE wxOVERRIDE +#else +# define wxDUMMY_OVERRIDE +#endif + /* Combination of the two variants above: should be used for deprecated functions which are defined inline and are used by wxWidgets itself. diff --git a/include/wx/event.h b/include/wx/event.h index c14b5def97..c649d2fb8f 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -4322,8 +4322,8 @@ typedef void (wxEvtHandler::*wxPressAndTapEventFunction)(wxPressAndTapEvent&); static const wxEventTableEntry sm_eventTableEntries[]; \ protected: \ wxWARNING_SUPPRESS_MISSING_OVERRIDE() \ - const wxEventTable* GetEventTable() const; \ - wxEventHashTable& GetEventHashTable() const; \ + const wxEventTable* GetEventTable() const wxDUMMY_OVERRIDE; \ + wxEventHashTable& GetEventHashTable() const wxDUMMY_OVERRIDE; \ wxWARNING_RESTORE_MISSING_OVERRIDE() \ static const wxEventTable sm_eventTable; \ static wxEventHashTable sm_eventHashTable diff --git a/include/wx/object.h b/include/wx/object.h index e4baee1396..4ec2bc457f 100644 --- a/include/wx/object.h +++ b/include/wx/object.h @@ -368,8 +368,6 @@ private: class WXDLLIMPEXP_BASE wxObject { - wxDECLARE_ABSTRACT_CLASS(wxObject); - public: wxObject() { m_refData = NULL; } virtual ~wxObject() { UnRef(); } @@ -392,6 +390,7 @@ public: bool IsKindOf(const wxClassInfo *info) const; + virtual wxClassInfo *GetClassInfo() const; // Turn on the correct set of new and delete operators @@ -453,6 +452,8 @@ protected: virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const; wxObjectRefData *m_refData; + + static wxClassInfo ms_classInfo; }; inline wxObject *wxCheckDynamicCast(wxObject *obj, wxClassInfo *classInfo) diff --git a/include/wx/rtti.h b/include/wx/rtti.h index 09faa06d51..0f54a0b914 100644 --- a/include/wx/rtti.h +++ b/include/wx/rtti.h @@ -140,7 +140,7 @@ WXDLLIMPEXP_BASE wxObject *wxCreateDynamicObject(const wxString& name); #define wxDECLARE_ABSTRACT_CLASS(name) \ public: \ wxWARNING_SUPPRESS_MISSING_OVERRIDE() \ - virtual wxClassInfo *GetClassInfo() const; \ + virtual wxClassInfo *GetClassInfo() const wxDUMMY_OVERRIDE; \ wxWARNING_RESTORE_MISSING_OVERRIDE() \ static wxClassInfo ms_classInfo diff --git a/tests/allheaders.cpp b/tests/allheaders.cpp index 522885b636..2663573da1 100644 --- a/tests/allheaders.cpp +++ b/tests/allheaders.cpp @@ -387,6 +387,33 @@ #include "allheaders.h" +// Check that using wx macros doesn't result in -Wsuggest-override or +// equivalent warnings in classes using and not using "override". +struct Base : wxEvtHandler +{ + virtual ~Base() { } + + virtual void Foo() { } +}; + +struct DerivedWithoutOverride : Base +{ + void OnIdle(wxIdleEvent&) { } + + wxDECLARE_DYNAMIC_CLASS_NO_COPY(DerivedWithoutOverride); + wxDECLARE_EVENT_TABLE(); +}; + +struct DerivedWithOverride : Base +{ + virtual void Foo() wxOVERRIDE { } + + void OnIdle(wxIdleEvent&) { } + + wxDECLARE_DYNAMIC_CLASS_NO_COPY(DerivedWithOverride); + wxDECLARE_EVENT_TABLE(); +}; + #ifdef GCC_TURN_OFF // Just using REQUIRE() below triggers -Wparentheses, so avoid it. GCC_TURN_OFF(parentheses)