diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -121,6 +121,13 @@ the C locale API (e.g. embedded). When localization is not supported, several parts of the library will be disabled: , , will be completely unusable, and other parts may be only partly available." ON) +option(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS + "Whether to turn on vendor availability annotations on declarations that depend + on definitions in a shared library. By default, we assume that we're not building + libc++ for any specific vendor, and we disable those annotations. Vendors wishing + to provide compile-time errors when using features unavailable on some version of + the shared library they shipped should turn this on and see `include/__availability` + for more details." OFF) option(LIBCXX_TEST_GDB_PRETTY_PRINTERS "Test gdb pretty printers." OFF) set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/legacy.cfg.in" CACHE STRING "The Lit testing configuration to use when running the tests.") @@ -844,6 +851,7 @@ config_define_if(LIBCXX_ENABLE_PARALLEL_ALGORITHMS _LIBCPP_HAS_PARALLEL_ALGORITHMS) config_define_if_not(LIBCXX_ENABLE_RANDOM_DEVICE _LIBCPP_HAS_NO_RANDOM_DEVICE) config_define_if_not(LIBCXX_ENABLE_LOCALIZATION _LIBCPP_HAS_NO_LOCALIZATION) +config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) if (LIBCXX_ABI_DEFINES) set(abi_defines) diff --git a/libcxx/cmake/caches/Apple.cmake b/libcxx/cmake/caches/Apple.cmake --- a/libcxx/cmake/caches/Apple.cmake +++ b/libcxx/cmake/caches/Apple.cmake @@ -11,6 +11,7 @@ set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "") set(LIBCXX_HIDE_FROM_ABI_PER_TU_BY_DEFAULT ON CACHE BOOL "") set(LIBCXX_ENABLE_DEBUG_MODE_SUPPORT OFF CACHE BOOL "") +set(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS ON CACHE BOOL "") set(LIBCXXABI_ENABLE_PIC OFF CACHE BOOL "") set(LIBCXXABI_ENABLE_ASSERTIONS OFF CACHE BOOL "") diff --git a/libcxx/docs/DesignDocs/AvailabilityMarkup.rst b/libcxx/docs/DesignDocs/AvailabilityMarkup.rst deleted file mode 100644 --- a/libcxx/docs/DesignDocs/AvailabilityMarkup.rst +++ /dev/null @@ -1,96 +0,0 @@ -=================== -Availability Markup -=================== - -.. contents:: - :local: - -Overview -======== - -Libc++ is used as a system library on macOS and iOS (amongst others). In order -for users to be able to compile a binary that is intended to be deployed to an -older version of the platform, clang provides the -`availability attribute `_ -that can be placed on declarations to describe the lifecycle of a symbol in the -library. - -Design -====== - -When a new feature is introduced that requires dylib support, a macro should be -created in include/__config to mark this feature as unavailable for all the -systems. For example:: - - // Define availability macros. - #if defined(_LIBCPP_USE_AVAILABILITY_APPLE) - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) - #else if defined(_LIBCPP_USE_AVAILABILITY_SOME_OTHER_VENDOR) - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) - #else - # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - #endif - -When the library is updated by the platform vendor, the markup can be updated. -For example:: - - #define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) - -In the source code, the macro can be added on a class if the full class requires -type info from the library for example:: - - _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL - class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access - : public std::logic_error { - -or on a particular symbol: - - _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; - -Furthermore, a lit feature should be added to match that availability macro, -so that tests depending on that feature can be marked to XFAIL if the feature -is not supported. This way, the test suite will work on platforms that have -not shipped the feature yet. This can be done by adding the appropriate lit -feature in test/config.py. - - -Testing -======= - -Some parameters can be passed to lit to run the test-suite and exercise the -availability. - -* The `target_triple` parameter controls the deployment target. For example lit - can be invoked with `--param=target_triple=x86_64-apple-macosx10.12`. - Default is the current host. -* The `use_system_cxx_lib` parameter indicates that the test suite is being - compiled with the intent of being run against the system library for the - given triple, AND that it is being run against it. - -Tests can be marked as XFAIL based on multiple features made available by lit. -If `use_system_cxx_lib` is true, then assuming `target_triple=x86_64-apple-macosx10.12`, -the following features will be made available: - - - with_system_cxx_lib=macosx - - with_system_cxx_lib=macosx10.12 - - with_system_cxx_lib=x86_64-apple-macosx10.12 - -These features are used to XFAIL a test that fails when deployed on (or is -compiled for) an older system. For example, if the test exhibits a bug in the -libc on a particular system version, or if the test uses a symbol that is not -available on an older version of the dylib, it can be marked as XFAIL with -one of the above features. - -It is sometimes useful to check that a test fails specifically when compiled -for a given deployment target. For example, this is the case when testing -availability markup, where we want to make sure that using the annotated -facility on a deployment target that doesn't support it will fail at compile -time, not at runtime. This can be achieved by creating a `.compile.pass.cpp` -and XFAILing it for the right deployment target. If the test doesn't fail at -compile-time like it's supposed to, the test will XPASS. Another option is to -create a `.verify.cpp` test that checks for the right errors, and mark that -test as requiring `with_system_cxx_lib=`. diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -1,4 +1,5 @@ set(files + __availability __bit_reference __bsd_locale_defaults.h __bsd_locale_fallbacks.h diff --git a/libcxx/include/__availability b/libcxx/include/__availability new file mode 100644 --- /dev/null +++ b/libcxx/include/__availability @@ -0,0 +1,206 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___AVAILABILITY +#define _LIBCPP___AVAILABILITY + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// Libc++ is shipped by various vendors. In particular, it is used as a system +// library on macOS, iOS and other Apple platforms. In order for users to be +// able to compile a binary that is intended to be deployed to an older version +// of a platform, Clang provides availability attributes [1]. These attributes +// can be placed on declarations and are used to describe the life cycle of a +// symbol in the library. +// +// The main goal is to ensure a compile-time error if a symbol that hasn't been +// introduced in a previously released library is used in a program that targets +// that previously released library. Normally, this would be a load-time error +// when one tries to launch the program against the older library. +// +// For example, the filesystem library was introduced in the dylib in macOS 10.15. +// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their +// program, the compiler would normally not complain (because the required +// declarations are in the headers), but the dynamic loader would fail to find +// the symbols when actually trying to launch the program on macOS 10.13. To +// turn this into a compile-time issue instead, declarations are annotated with +// when they were introduced, and the compiler can produce a diagnostic if the +// program references something that isn't available on the deployment target. +// +// This mechanism is general in nature, and any vendor can add their markup to +// the library (see below). Whenever a new feature is added that requires support +// in the shared library, a macro should be added below to mark this feature +// as unavailable. When vendors decide to ship the feature as part of their +// shared library, they can update the markup appropriately. +// +// Note that this mechanism is disabled by default in the "upstream" libc++. +// Availability annotations are only meaningful when shipping libc++ inside +// a platform (i.e. as a system library), and so vendors that want them should +// turn those annotations on at CMake configuration time. +// +// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability + + +// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY +// for a while. +#if defined(_LIBCPP_DISABLE_AVAILABILITY) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +// Availability markup is disabled when building the library, or when the compiler +// doesn't support the proper attributes. +#if defined(_LIBCPP_BUILDING_LIBRARY) || \ + defined(_LIBCXXABI_BUILDING_LIBRARY) || \ + !__has_feature(attribute_availability_with_strict) || \ + !__has_feature(attribute_availability_in_templates) || \ + !__has_extension(pragma_clang_attribute_external_declaration) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) + + // This controls the availability of std::shared_mutex and std::shared_timed_mutex, + // which were added to the dylib later. +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX + + // These macros control the availability of std::bad_optional_access and + // other exception types. These were put in the shared library to prevent + // code bloat from every user program defining the vtable for these exception + // types. +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST + + // This controls the availability of std::uncaught_exceptions(). +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS + + // This controls the availability of the sized version of ::operator delete, + // which was added to the dylib later. +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE + + // This controls the availability of the std::future_error exception. +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR + + // This controls the availability of std::type_info's vtable. + // I can't imagine how using std::type_info can work at all if + // this isn't supported. +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE + + // This controls the availability of std::locale::category members + // (e.g. std::locale::collate), which are defined in the dylib. +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY + + // This controls the availability of atomic operations on std::shared_ptr + // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared + // lock table located in the dylib. +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR + + // These macros control the availability of all parts of that + // depend on something in the dylib. +# define _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP + + // This controls the availability of std::to_chars. +# define _LIBCPP_AVAILABILITY_TO_CHARS + + // This controls the availability of the C++20 synchronization library, + // which requires shared library support for various operations + // (see libcxx/src/atomic.cpp). +# define _LIBCPP_AVAILABILITY_SYNC + +#elif defined(__APPLE__) + +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ + __attribute__((availability(macosx,strict,introduced=10.13))) \ + __attribute__((availability(ios,strict,introduced=11.0))) \ + __attribute__((availability(tvos,strict,introduced=11.0))) \ + __attribute__((availability(watchos,strict,introduced=4.0))) +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ + __attribute__((availability(ios,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM \ + __attribute__((availability(macosx,strict,introduced=10.15))) \ + __attribute__((availability(ios,strict,introduced=13.0))) \ + __attribute__((availability(tvos,strict,introduced=13.0))) \ + __attribute__((availability(watchos,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ + _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") +# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") +# define _LIBCPP_AVAILABILITY_TO_CHARS \ + _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_SYNC \ + __attribute__((unavailable)) + +#else + +// ...New vendors can add availability markup here... + +# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" + +#endif + +// Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS. +// Those are defined in terms of the availability attributes above, and +// should not be vendor-specific. +#if defined(_LIBCPP_NO_EXCEPTIONS) +# define _LIBCPP_AVAILABILITY_FUTURE +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +#else +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +#endif // _LIBCPP___AVAILABILITY diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1359,105 +1359,6 @@ #define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR #endif -// Decide whether to use availability macros. -#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ - !defined(_LIBCXXABI_BUILDING_LIBRARY) && \ - !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ - __has_feature(attribute_availability_with_strict) && \ - __has_feature(attribute_availability_in_templates) && \ - __has_extension(pragma_clang_attribute_external_declaration) -# ifdef __APPLE__ -# define _LIBCPP_USE_AVAILABILITY_APPLE -# endif -#endif - -// Define availability macros. -#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ - __attribute__((availability(macosx,strict,introduced=10.13))) \ - __attribute__((availability(ios,strict,introduced=11.0))) \ - __attribute__((availability(tvos,strict,introduced=11.0))) \ - __attribute__((availability(watchos,strict,introduced=4.0))) -# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ - _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ - _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ - __attribute__((availability(ios,strict,introduced=6.0))) -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -# define _LIBCPP_AVAILABILITY_FILESYSTEM \ - __attribute__((availability(macosx,strict,introduced=10.15))) \ - __attribute__((availability(ios,strict,introduced=13.0))) \ - __attribute__((availability(tvos,strict,introduced=13.0))) \ - __attribute__((availability(watchos,strict,introduced=6.0))) -# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ - _Pragma("clang attribute push(__attribute__((availability(macosx,strict,introduced=10.15))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") -# define _LIBCPP_AVAILABILITY_TO_CHARS \ - _LIBCPP_AVAILABILITY_FILESYSTEM -# define _LIBCPP_AVAILABILITY_SYNC \ - __attribute__((unavailable)) -#else -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX -# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE -# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR -# define _LIBCPP_AVAILABILITY_FILESYSTEM -# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP -# define _LIBCPP_AVAILABILITY_TO_CHARS -# define _LIBCPP_AVAILABILITY_SYNC -#endif - -// Define availability that depends on _LIBCPP_NO_EXCEPTIONS. -#ifdef _LIBCPP_NO_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_FUTURE -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS -#else -# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS -#endif - #if defined(_LIBCPP_COMPILER_IBM) #define _LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO #endif diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in --- a/libcxx/include/__config_site.in +++ b/libcxx/include/__config_site.in @@ -26,6 +26,7 @@ #cmakedefine _LIBCPP_HAS_THREAD_API_WIN32 #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS +#cmakedefine _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME #ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION #cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@ diff --git a/libcxx/include/__locale b/libcxx/include/__locale --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -11,6 +11,7 @@ #define _LIBCPP___LOCALE #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -11,6 +11,7 @@ #define _LIBCPP_THREADING_SUPPORT #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/any b/libcxx/include/any --- a/libcxx/include/any +++ b/libcxx/include/any @@ -81,6 +81,7 @@ */ #include +#include <__availability> #include #include #include diff --git a/libcxx/include/atomic b/libcxx/include/atomic --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -573,6 +573,7 @@ */ #include <__config> +#include <__availability> #include <__threading_support> #include #include diff --git a/libcxx/include/barrier b/libcxx/include/barrier --- a/libcxx/include/barrier +++ b/libcxx/include/barrier @@ -44,6 +44,7 @@ */ #include <__config> +#include <__availability> #include #ifndef _LIBCPP_HAS_NO_TREE_BARRIER # include diff --git a/libcxx/include/charconv b/libcxx/include/charconv --- a/libcxx/include/charconv +++ b/libcxx/include/charconv @@ -74,6 +74,7 @@ */ #include <__config> +#include <__availability> #include <__errc> #include #include diff --git a/libcxx/include/chrono b/libcxx/include/chrono --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -824,6 +824,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/exception b/libcxx/include/exception --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -77,6 +77,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -230,6 +230,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/fstream b/libcxx/include/fstream --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -180,6 +180,7 @@ */ #include <__config> +#include <__availability> #include #include #include <__locale> diff --git a/libcxx/include/future b/libcxx/include/future --- a/libcxx/include/future +++ b/libcxx/include/future @@ -362,6 +362,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/latch b/libcxx/include/latch --- a/libcxx/include/latch +++ b/libcxx/include/latch @@ -39,6 +39,7 @@ */ #include <__config> +#include <__availability> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -665,6 +665,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/new b/libcxx/include/new --- a/libcxx/include/new +++ b/libcxx/include/new @@ -87,6 +87,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/optional b/libcxx/include/optional --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -147,6 +147,7 @@ */ #include <__config> +#include <__availability> #include <__debug> #include <__functional_base> #include diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore --- a/libcxx/include/semaphore +++ b/libcxx/include/semaphore @@ -46,6 +46,7 @@ */ #include <__config> +#include <__availability> #include <__threading_support> #include #include diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex --- a/libcxx/include/shared_mutex +++ b/libcxx/include/shared_mutex @@ -123,6 +123,7 @@ */ #include <__config> +#include <__availability> #include _LIBCPP_PUSH_MACROS diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -57,6 +57,7 @@ */ #include <__config> +#include <__availability> #include #include #include diff --git a/libcxx/include/variant b/libcxx/include/variant --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -197,6 +197,7 @@ */ #include <__config> +#include <__availability> #include <__tuple> #include #include diff --git a/libcxx/src/optional.cpp b/libcxx/src/optional.cpp --- a/libcxx/src/optional.cpp +++ b/libcxx/src/optional.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "optional" +#include "__availability" namespace std { diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -135,6 +135,29 @@ # with various forms of the target triple to make it easier to write XFAIL or # UNSUPPORTED markup for tests that are known to fail on a particular triple. # +# More specifically, when the `use_system_cxx_lib` parameter is enabled, then +# assuming the `target_triple` is set to `x86_64-apple-macosx10.12`, the +# following features will be made available: +# - with_system_cxx_lib=macosx +# - with_system_cxx_lib=macosx10.12 +# - with_system_cxx_lib=x86_64-apple-macosx10.12 +# +# These features can be used to XFAIL a test that fails when deployed on (or is +# compiled for) an older system. For example, if the test exhibits a bug in the +# libc on a particular system version, or if the test uses a symbol that is not +# available on an older version of the dylib, it can be marked as XFAIL with +# one of the above features. +# +# It is sometimes useful to check that a test fails specifically when compiled +# for a given deployment target. For example, this is the case when testing +# availability markup, where we want to make sure that using the annotated +# facility on a deployment target that doesn't support it will fail at compile +# time, not at runtime. This can be achieved by creating a `.compile.pass.cpp` +# and XFAILing it for the right deployment target. If the test doesn't fail at +# compile-time like it's supposed to, the test will XPASS. Another option is to +# create a `.verify.cpp` test that checks for the right errors, and mark that +# test as requiring `with_system_cxx_lib=`. +# # TODO: This is very unclean -- we assume that the 'use_system_cxx_lib' parameter # is set before this feature gets detected, and we also set a dummy name # for the main feature. We also take for granted that `target_triple` diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -81,7 +81,7 @@ AddFeature('use_system_cxx_lib') ] if useSystem else [ # If we're testing upstream libc++, disable availability markup, - # which is not relevant for non-shipped flabors of libc++. + # which is not relevant for non-shipped flavors of libc++. AddCompileFlag('-D_LIBCPP_DISABLE_AVAILABILITY') ]),