[libc++] Properly mark std::function as deprecated in C++03

Due to Clang bug http://llvm.org/PR45151, deprecated attributes are not
picked up on partial specializations. This patch instead applies it to
the first declaration of std::function itself.
This commit is contained in:
Louis Dionne 2020-03-09 11:16:22 -04:00
parent 5c845c1c50
commit a13417352a
3 changed files with 41 additions and 12 deletions

View file

@ -443,15 +443,8 @@ __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::target_type() const
} // __function
#if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
__attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
#else
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
#endif
template<class _Rp>
class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function<_Rp()>
class _LIBCPP_TEMPLATE_VIS function<_Rp()>
{
typedef __function::__base<_Rp()> __base;
aligned_storage<3*sizeof(void*)>::type __buf_;
@ -730,7 +723,7 @@ function<_Rp()>::target() const
#endif // _LIBCPP_NO_RTTI
template<class _Rp, class _A0>
class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0)>
: public unary_function<_A0, _Rp>
{
typedef __function::__base<_Rp(_A0)> __base;
@ -1010,7 +1003,7 @@ function<_Rp(_A0)>::target() const
#endif // _LIBCPP_NO_RTTI
template<class _Rp, class _A0, class _A1>
class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1)>
: public binary_function<_A0, _A1, _Rp>
{
typedef __function::__base<_Rp(_A0, _A1)> __base;
@ -1290,7 +1283,7 @@ function<_Rp(_A0, _A1)>::target() const
#endif // _LIBCPP_NO_RTTI
template<class _Rp, class _A0, class _A1, class _A2>
class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
class _LIBCPP_TEMPLATE_VIS function<_Rp(_A0, _A1, _A2)>
{
typedef __function::__base<_Rp(_A0, _A1, _A2)> __base;
aligned_storage<3*sizeof(void*)>::type __buf_;

View file

@ -1434,7 +1434,14 @@ void __throw_bad_function_call()
#endif
}
template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
__attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
#else
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
#endif
template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
namespace __function
{

View file

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <functional>
// Check that libc++'s emulation of std::function is deprecated in C++03
// REQUIRES: c++98 || c++03
// REQUIRES: verify-support
#include <functional>
#include "test_macros.h"
int main() {
// Note:
// We use sizeof() to require it to be a complete type. We don't create a
// variable because otherwise we get two errors for each variable (the
// second error is when the destructor is implicitly called).
(void)sizeof(std::function<void ()>); // expected-error{{'function<void ()>' is deprecated}}
(void)sizeof(std::function<void (int)>); // expected-error{{'function<void (int)>' is deprecated}}
(void)sizeof(std::function<void (int, int)>); // expected-error{{'function<void (int, int)>' is deprecated}}
(void)sizeof(std::function<void (int, int, int)>); // expected-error{{'function<void (int, int, int)>' is deprecated}}
}