From a7a2d4ebf14889191c09a3d99131ea42e1469a78 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 14 Aug 2022 16:10:26 +0300 Subject: [PATCH] Added a BOOST_DEPRECATED macro for deprecated symbol markup. BOOST_DEPRECATED can be used to mark functions, types and objects as deprecated, with a message with a recommendation of replacement. Using such marked symbols in code will generate compiler warnings, with the specified message, if possible. The warnings can be suppressed if BOOST_ALLOW_DEPRECATED_SYMBOLS is defined. Additionally, added support BOOST_ALLOW_DEPRECATED macro that not only allows for deprecated symbols but also deprecated headers (i.e. defining BOOST_ALLOW_DEPRECATED is equivalent to defining both BOOST_ALLOW_DEPRECATED_SYMBOLS and BOOST_ALLOW_DEPRECATED_HEADERS). --- doc/macro_reference.qbk | 95 +++++++++++++-------- include/boost/config/compiler/clang.hpp | 13 ++- include/boost/config/compiler/gcc.hpp | 12 ++- include/boost/config/compiler/sunpro_cc.hpp | 6 ++ include/boost/config/compiler/visualc.hpp | 8 ++ include/boost/config/compiler/xlcpp.hpp | 4 + include/boost/config/detail/suffix.hpp | 17 ++++ include/boost/config/header_deprecated.hpp | 2 +- test/Jamfile.v2 | 16 ++-- test/symbol_deprecated_test.cpp | 19 +++++ 10 files changed, 140 insertions(+), 52 deletions(-) create mode 100644 test/symbol_deprecated_test.cpp diff --git a/doc/macro_reference.qbk b/doc/macro_reference.qbk index 1ff43fba..b4ce40ed 100644 --- a/doc/macro_reference.qbk +++ b/doc/macro_reference.qbk @@ -1199,41 +1199,41 @@ struct foo{ Normally evaluates to nothing, but evaluates to return x; if the compiler requires a return, even when it can never be reached. ]] -[[`BOOST_FALLTHROUGH`][ -The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through -between switch labels: -`` - switch (x) { - case 40: - case 41: - if (truth_is_out_there) { - ++x; - BOOST_FALLTHROUGH; // Use instead of/along with annotations in - // comments. - } else { - return x; - } - case 42: - ... -`` -As shown in the example above, the BOOST_FALLTHROUGH macro should be -followed by a semicolon. It is designed to mimic control-flow statements -like 'break;', so it can be placed in most places where 'break;' can, but -only if there are no statements on the execution path between it and the -next switch label. +[[`BOOST_FALLTHROUGH`][ +The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through +between switch labels: +`` + switch (x) { + case 40: + case 41: + if (truth_is_out_there) { + ++x; + BOOST_FALLTHROUGH; // Use instead of/along with annotations in + // comments. + } else { + return x; + } + case 42: + ... +`` +As shown in the example above, the BOOST_FALLTHROUGH macro should be +followed by a semicolon. It is designed to mimic control-flow statements +like 'break;', so it can be placed in most places where 'break;' can, but +only if there are no statements on the execution path between it and the +next switch label. -When compiled with Clang >3.2 in C++11 mode, the BOOST_FALLTHROUGH macro is -expanded to `[[clang::fallthrough]]` attribute, which is analysed when -performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough'). -See clang [@http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough -documentation on language extensions for details.] +When compiled with Clang >3.2 in C++11 mode, the BOOST_FALLTHROUGH macro is +expanded to `[[clang::fallthrough]]` attribute, which is analysed when +performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough'). +See clang [@http://clang.llvm.org/docs/LanguageExtensions.html#clang__fallthrough +documentation on language extensions for details.] -When used with unsupported compilers, the BOOST_FALLTHROUGH macro has no -effect on diagnostics. +When used with unsupported compilers, the BOOST_FALLTHROUGH macro has no +effect on diagnostics. -In either case this macro has no effect on runtime behavior and performance -of code. -]] +In either case this macro has no effect on runtime behavior and performance +of code. +]] [[`BOOST_EXPLICIT_TEMPLATE_TYPE(t)` `BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t,v)` @@ -1405,11 +1405,11 @@ Usage example: handle_error("ptr is NULL"); `` ]] -[[`BOOST_ATTRIBUTE_UNUSED`][Expands to `__attribute__((unused))` when this is available - +[[`BOOST_ATTRIBUTE_UNUSED`][Expands to `__attribute__((unused))` when this is available - can be used to disable compiler warnings relating to unused types or variables.]] -[[`BOOST_ATTRIBUTE_NODISCARD`][Expands to `[[nodiscard]]` when this is available - +[[`BOOST_ATTRIBUTE_NODISCARD`][Expands to `[[nodiscard]]` when this is available - can be used to create a warning when a type or variable is unused.]] -[[`BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS`][Expands to `[[no_unique_address]]` when this is available - +[[`BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS`][Expands to `[[no_unique_address]]` when this is available - can be used to indicate that a non-static data member need not have a unique address (for example empty classes).]] [[`BOOST_MAY_ALIAS`, `BOOST_NO_MAY_ALIAS`][ `BOOST_MAY_ALIAS` expands to a type attribute that can be used to mark types that may @@ -1423,6 +1423,27 @@ Usage example: typedef unsigned int BOOST_MAY_ALIAS aliasing_uint; `` ]] +[[`BOOST_DEPRECATED(M)`][Expands to an attribute for a symbol that generates warnings when that +symbol is used in code. The warnings may contain a message `M`, which must be a string literal. +This attribute may be applied to types, functions or objects and is typically used to mark +parts of the API as deprecated with a recommendation of replacement. + +Example: +`` +BOOST_DEPRECATED("Use bar() instead.") +void foo(); + +template< typename T > +class BOOST_DEPRECATED("Use std::unique_ptr instead.") auto_ptr +{ +}; + +BOOST_DEPRECATED("Use std::numeric_limits::max() instead.") +const int max_int = 0x7fffffff; +`` + +The warnings issued by `BOOST_DEPRECATED` can be suppressed by defining +`BOOST_ALLOW_DEPRECATED_SYMBOLS` or `BOOST_ALLOW_DEPRECATED` macros.]] [[`BOOST_PRAGMA_MESSAGE(M)`][Defined in header ``, this macro expands to the equivalent of `#pragma message(M)`. `M` must be a string literal. @@ -1438,8 +1459,8 @@ this macro issues the message "This header is deprecated. Use `A` instead." via Example: `BOOST_HEADER_DEPRECATED("")` -The messages issued by `BOOST_HEADER_DEPRECATED` can be suppressed by defining the macro -`BOOST_ALLOW_DEPRECATED_HEADERS`.]] +The messages issued by `BOOST_HEADER_DEPRECATED` can be suppressed by defining +`BOOST_ALLOW_DEPRECATED_HEADERS` or `BOOST_ALLOW_DEPRECATED` macros.]] ] [endsect] diff --git a/include/boost/config/compiler/clang.hpp b/include/boost/config/compiler/clang.hpp index f28da107..cb08d27f 100644 --- a/include/boost/config/compiler/clang.hpp +++ b/include/boost/config/compiler/clang.hpp @@ -325,11 +325,18 @@ // All versions with __cplusplus above this value seem to support this: # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif -// -// __builtin_unreachable: -#if defined(__has_builtin) && __has_builtin(__builtin_unreachable) + +// Unreachable code markup +#if defined(__has_builtin) +#if __has_builtin(__builtin_unreachable) #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif +#endif + +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif #if (__clang_major__ == 3) && (__clang_minor__ == 0) // Apparently a clang bug: diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp index d4cf0e9c..4cea0ce2 100644 --- a/include/boost/config/compiler/gcc.hpp +++ b/include/boost/config/compiler/gcc.hpp @@ -340,12 +340,18 @@ // Type aliasing hint. Supported since gcc 3.3. #define BOOST_MAY_ALIAS __attribute__((__may_alias__)) -// -// __builtin_unreachable: +// Unreachable code markup #if BOOST_GCC_VERSION >= 40500 #define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); #endif +// Deprecated symbol markup +#if BOOST_GCC_VERSION >= 40500 +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#else +#define BOOST_DEPRECATED(msg) __attribute__((deprecated)) +#endif + #ifndef BOOST_COMPILER # define BOOST_COMPILER "GNU C++ version " __VERSION__ #endif @@ -359,7 +365,7 @@ // versions check: // we don't know gcc prior to version 3.30: -#if (BOOST_GCC_VERSION< 30300) +#if (BOOST_GCC_VERSION < 30300) # error "Compiler not configured - please reconfigure" #endif // diff --git a/include/boost/config/compiler/sunpro_cc.hpp b/include/boost/config/compiler/sunpro_cc.hpp index c674e8ab..1ab78991 100644 --- a/include/boost/config/compiler/sunpro_cc.hpp +++ b/include/boost/config/compiler/sunpro_cc.hpp @@ -86,6 +86,12 @@ # define BOOST_SYMBOL_VISIBLE __global #endif +// Deprecated symbol markup +// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute. +#if (__SUNPRO_CC >= 0x5130) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + #if (__SUNPRO_CC < 0x5130) // C++03 features in 12.4: #define BOOST_NO_TWO_PHASE_NAME_LOOKUP diff --git a/include/boost/config/compiler/visualc.hpp b/include/boost/config/compiler/visualc.hpp index 4859c7c8..6378094c 100644 --- a/include/boost/config/compiler/visualc.hpp +++ b/include/boost/config/compiler/visualc.hpp @@ -107,6 +107,14 @@ # define BOOST_NO_RTTI #endif +// Deprecated symbol markup +#if (_MSC_VER >= 1400) +#define BOOST_DEPRECATED(msg) __declspec(deprecated(msg)) +#else +// MSVC 7.1 only supports the attribute without a message +#define BOOST_DEPRECATED(msg) __declspec(deprecated) +#endif + // // TR1 features: // diff --git a/include/boost/config/compiler/xlcpp.hpp b/include/boost/config/compiler/xlcpp.hpp index 6e868817..f002e69c 100644 --- a/include/boost/config/compiler/xlcpp.hpp +++ b/include/boost/config/compiler/xlcpp.hpp @@ -270,6 +270,10 @@ # define BOOST_NO_CXX14_DIGIT_SEPARATORS #endif +// Deprecated symbol markup +#if __has_attribute(deprecated) +#define BOOST_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif // Unused attribute: #if defined(__GNUC__) && (__GNUC__ >= 4) diff --git a/include/boost/config/detail/suffix.hpp b/include/boost/config/detail/suffix.hpp index 13d4bb6a..fa8c5b28 100644 --- a/include/boost/config/detail/suffix.hpp +++ b/include/boost/config/detail/suffix.hpp @@ -668,6 +668,23 @@ namespace std{ using ::type_info; } # define BOOST_NORETURN #endif +// BOOST_DEPRECATED -------------------------------------------// +// The macro can be used to mark deprecated symbols, such as functions, objects and types. +// Any code that uses these symbols will produce warnings, possibly with a message specified +// as an argument. The warnings can be suppressed by defining BOOST_ALLOW_DEPRECATED_SYMBOLS +// or BOOST_ALLOW_DEPRECATED. +#if !defined(BOOST_DEPRECATED) && __cplusplus >= 201402 +#define BOOST_DEPRECATED(msg) [[deprecated(msg)]] +#endif + +#if defined(BOOST_ALLOW_DEPRECATED_SYMBOLS) || defined(BOOST_ALLOW_DEPRECATED) +#undef BOOST_DEPRECATED +#endif + +#if !defined(BOOST_DEPRECATED) +#define BOOST_DEPRECATED(msg) +#endif + // Branch prediction hints // These macros are intended to wrap conditional expressions that yield true or false // diff --git a/include/boost/config/header_deprecated.hpp b/include/boost/config/header_deprecated.hpp index 864554f2..120b4b3a 100644 --- a/include/boost/config/header_deprecated.hpp +++ b/include/boost/config/header_deprecated.hpp @@ -17,7 +17,7 @@ #include -#if defined(BOOST_ALLOW_DEPRECATED_HEADERS) +#if defined(BOOST_ALLOW_DEPRECATED_HEADERS) || defined(BOOST_ALLOW_DEPRECATED) # define BOOST_HEADER_DEPRECATED(a) #else # define BOOST_HEADER_DEPRECATED(a) BOOST_PRAGMA_MESSAGE("This header is deprecated. Use " a " instead.") diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bed7f279..f4fe179c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -84,9 +84,9 @@ test-suite config [ run config_info.cpp : : : always_show_run_output single msvc:static msvc:static msvc:on gcc:on clang:on ] [ run config_info.cpp : : : always_show_run_output multi msvc:on gcc:on clang:on : config_info_threaded ] [ run config_info.cpp : : : always_show_run_output off msvc:on gcc:on clang:on : config_info_no_rtti ] - [ run config_info.cpp : : : always_show_run_output off - vxworks:no - : config_info_no_except ] + [ run config_info.cpp : : : always_show_run_output off + vxworks:no + : config_info_no_except ] [ run math_info.cpp : : : always_show_run_output borland:static borland:static ] [ run abi/abi_test.cpp abi/main.cpp ] [ run limits_test.cpp ] @@ -113,11 +113,12 @@ test-suite config [ run helper_macros_test.cpp ] [ compile pragma_message_test.cpp ] [ compile header_deprecated_test.cpp ] + [ compile symbol_deprecated_test.cpp ] [ compile boost_override_test.cpp ] ; obj has_clang_implicit_fallthrough : cmd_line_check.cpp : - clang:"-std=c++11 -Wimplicit-fallthrough" on all ; + clang:"-std=c++11 -Wimplicit-fallthrough" on all ; explicit has_clang_implicit_fallthrough ; @@ -128,9 +129,9 @@ explicit math_info_printer ; actions print-run { - echo With Standard Version $(STANDARD:E=default) - echo ===================================================================== - $(>) + echo With Standard Version $(STANDARD:E=default) + echo ===================================================================== + $(>) } rule print-run ( target : sources * : properties * ) @@ -147,4 +148,3 @@ explicit print_math_info ; exe config_info_travis : config_info.cpp ; install config_info_travis_install : config_info_travis : . ; explicit config_info_travis_install ; - diff --git a/test/symbol_deprecated_test.cpp b/test/symbol_deprecated_test.cpp new file mode 100644 index 00000000..2d667b65 --- /dev/null +++ b/test/symbol_deprecated_test.cpp @@ -0,0 +1,19 @@ +// Copyright 2022 Andrey Semashev. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include + +BOOST_DEPRECATED("Use bar() instead.") +void foo(); + +template< typename T > +class BOOST_DEPRECATED("Use std::unique_ptr instead.") my_auto_ptr +{ +}; + +BOOST_DEPRECATED("Use std::numeric_limits::max() instead.") +const int max_int = 0x7fffffff;