[libcxx-commits] [libcxx] 2eadbc8 - [libc++] Rework the whole availability markup implementation

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 5 09:28:58 PST 2020


Author: Louis Dionne
Date: 2020-11-05T12:28:52-05:00
New Revision: 2eadbc86142bab5b46dfeb55d8bd6724234278bb

URL: https://github.com/llvm/llvm-project/commit/2eadbc86142bab5b46dfeb55d8bd6724234278bb
DIFF: https://github.com/llvm/llvm-project/commit/2eadbc86142bab5b46dfeb55d8bd6724234278bb.diff

LOG: [libc++] Rework the whole availability markup implementation

Currently, vendor-specific availability markup is enabled by default.
This means that even when building against trunk libc++, the headers
will by default prevent you from using some features that were not
released in the dylib on your target platform. This is a source of
frustration since people building libc++ from sources are usually not
trying to use some vendor's released dylib.

For that reason, I've been thinking for a long time that availability
annotations should be off by default, which is the primary change that
this commit enables.

In addition, it reworks the implementation to make it easier for new
vendors to add availability annotations for their platform, and it
refreshes the documentation to reflect the current state of the codebase.

Finally, a CMake configuration option is added to control whether
availability annotations should be turned on for the flavor of libc++
being created. The intent is for vendors like Apple to turn it on, and
for the upstream libc++ to leave it off (the default).

Differential Revision: https://reviews.llvm.org/D90843

Added: 
    libcxx/include/__availability

Modified: 
    libcxx/CMakeLists.txt
    libcxx/cmake/caches/Apple.cmake
    libcxx/include/CMakeLists.txt
    libcxx/include/__config
    libcxx/include/__config_site.in
    libcxx/include/__locale
    libcxx/include/__threading_support
    libcxx/include/any
    libcxx/include/atomic
    libcxx/include/barrier
    libcxx/include/charconv
    libcxx/include/chrono
    libcxx/include/exception
    libcxx/include/filesystem
    libcxx/include/fstream
    libcxx/include/future
    libcxx/include/latch
    libcxx/include/memory
    libcxx/include/new
    libcxx/include/optional
    libcxx/include/semaphore
    libcxx/include/shared_mutex
    libcxx/include/typeinfo
    libcxx/include/variant
    libcxx/src/optional.cpp
    libcxx/utils/libcxx/test/features.py
    libcxx/utils/libcxx/test/params.py

Removed: 
    libcxx/docs/DesignDocs/AvailabilityMarkup.rst


################################################################################
diff  --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 356c76f09c82..9d01b17721ac 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -121,6 +121,13 @@ option(LIBCXX_ENABLE_LOCALIZATION
    the C locale API (e.g. embedded). When localization is not supported,
    several parts of the library will be disabled: <iostream>, <regex>, <locale>
    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_NO_VCRUNTIME _LIBCPP_NO_VCRUNTIME)
 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
index e6221cd4a584..fbe85b1e9caf 100644
--- a/libcxx/cmake/caches/Apple.cmake
+++ b/libcxx/cmake/caches/Apple.cmake
@@ -11,6 +11,7 @@ set(LIBCXX_TYPEINFO_COMPARISON_IMPLEMENTATION "1" CACHE STRING "")
 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
index 26975a737068..000000000000
--- 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 <https://clang.llvm.org/docs/AttributeReference.html#availability>`_
-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=<something>`.

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index a413139ee36d..aab02768e5b7 100644
--- 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
index 000000000000..db2267c8eb16
--- /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 <filesystem> 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
index 7cdcd9a7275e..eeef9c53a9f7 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1359,105 +1359,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
 #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
index 8141d3c419f4..7f4a429f1788 100644
--- 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
index 63508bd84887..125adcf68c84 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -11,6 +11,7 @@
 #define _LIBCPP___LOCALE
 
 #include <__config>
+#include <__availability>
 #include <string>
 #include <memory>
 #include <utility>

diff  --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support
index 6501217c2741..fe770a81c115 100644
--- a/libcxx/include/__threading_support
+++ b/libcxx/include/__threading_support
@@ -11,6 +11,7 @@
 #define _LIBCPP_THREADING_SUPPORT
 
 #include <__config>
+#include <__availability>
 #include <chrono>
 #include <iosfwd>
 #include <errno.h>

diff  --git a/libcxx/include/any b/libcxx/include/any
index 51731b75aeac..968c9769ee36 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -81,6 +81,7 @@ namespace std {
 */
 
 #include <experimental/__config>
+#include <__availability>
 #include <memory>
 #include <typeinfo>
 #include <type_traits>

diff  --git a/libcxx/include/atomic b/libcxx/include/atomic
index 7458275815fe..f00f7b8a01a0 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -573,6 +573,7 @@ template <class T>
 */
 
 #include <__config>
+#include <__availability>
 #include <__threading_support>
 #include <cstddef>
 #include <cstdint>

diff  --git a/libcxx/include/barrier b/libcxx/include/barrier
index 58e3eef9cfe5..6589499ddb4d 100644
--- a/libcxx/include/barrier
+++ b/libcxx/include/barrier
@@ -44,6 +44,7 @@ namespace std
 */
 
 #include <__config>
+#include <__availability>
 #include <atomic>
 #ifndef _LIBCPP_HAS_NO_TREE_BARRIER
 # include <memory>

diff  --git a/libcxx/include/charconv b/libcxx/include/charconv
index b64000242a7e..c830457154d7 100644
--- a/libcxx/include/charconv
+++ b/libcxx/include/charconv
@@ -74,6 +74,7 @@ namespace std {
 */
 
 #include <__config>
+#include <__availability>
 #include <__errc>
 #include <type_traits>
 #include <limits>

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index 117aab31907f..7b53a0d48965 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -824,6 +824,7 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 */
 
 #include <__config>
+#include <__availability>
 #include <ctime>
 #include <type_traits>
 #include <ratio>

diff  --git a/libcxx/include/exception b/libcxx/include/exception
index 8e32979f5749..a668539be899 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -77,6 +77,7 @@ template <class E> void rethrow_if_nested(const E& e);
 */
 
 #include <__config>
+#include <__availability>
 #include <cstddef>
 #include <cstdlib>
 #include <type_traits>

diff  --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index 5783ed3560ba..a39184c4a27d 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -230,6 +230,7 @@
 */
 
 #include <__config>
+#include <__availability>
 #include <cstddef>
 #include <cstdlib>
 #include <chrono>

diff  --git a/libcxx/include/fstream b/libcxx/include/fstream
index e9138998bf11..98897f49866b 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -180,6 +180,7 @@ typedef basic_fstream<wchar_t> wfstream;
 */
 
 #include <__config>
+#include <__availability>
 #include <ostream>
 #include <istream>
 #include <__locale>

diff  --git a/libcxx/include/future b/libcxx/include/future
index 295b6ac5d6ee..409fa8e90b87 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -362,6 +362,7 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
 */
 
 #include <__config>
+#include <__availability>
 #include <system_error>
 #include <memory>
 #include <chrono>

diff  --git a/libcxx/include/latch b/libcxx/include/latch
index f669f5860d34..67fca97ac778 100644
--- a/libcxx/include/latch
+++ b/libcxx/include/latch
@@ -39,6 +39,7 @@ namespace std
 */
 
 #include <__config>
+#include <__availability>
 #include <atomic>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 25f940a14ef6..b12a2a99d3f6 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -665,6 +665,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 */
 
 #include <__config>
+#include <__availability>
 #include <type_traits>
 #include <typeinfo>
 #include <cstddef>

diff  --git a/libcxx/include/new b/libcxx/include/new
index e21c22bc2ed1..66747b04d4d7 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -87,6 +87,7 @@ void  operator delete[](void* ptr, void*) noexcept;
 */
 
 #include <__config>
+#include <__availability>
 #include <exception>
 #include <type_traits>
 #include <cstddef>

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index a147d69da00f..6cd51482e926 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -147,6 +147,7 @@ template<class T>
 */
 
 #include <__config>
+#include <__availability>
 #include <__debug>
 #include <__functional_base>
 #include <functional>

diff  --git a/libcxx/include/semaphore b/libcxx/include/semaphore
index 447bc2f385d1..8f6316273bff 100644
--- a/libcxx/include/semaphore
+++ b/libcxx/include/semaphore
@@ -46,6 +46,7 @@ using binary_semaphore = counting_semaphore<1>;
 */
 
 #include <__config>
+#include <__availability>
 #include <__threading_support>
 #include <atomic>
 #include <cassert>

diff  --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index fcafd8c0f44f..5448d8a80715 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -123,6 +123,7 @@ template <class Mutex>
 */
 
 #include <__config>
+#include <__availability>
 #include <version>
 
 _LIBCPP_PUSH_MACROS

diff  --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo
index 7e76da538796..7818ed37d0c8 100644
--- a/libcxx/include/typeinfo
+++ b/libcxx/include/typeinfo
@@ -57,6 +57,7 @@ public:
 */
 
 #include <__config>
+#include <__availability>
 #include <exception>
 #include <cstddef>
 #include <cstdint>

diff  --git a/libcxx/include/variant b/libcxx/include/variant
index a7471f8592d6..0830d3dde1b7 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -197,6 +197,7 @@ namespace std {
 */
 
 #include <__config>
+#include <__availability>
 #include <__tuple>
 #include <array>
 #include <exception>

diff  --git a/libcxx/src/optional.cpp b/libcxx/src/optional.cpp
index 3aaf5ea553ef..86d013b3504f 100644
--- 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
index efafd871af74..51f9296c31f8 100644
--- 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=<something>`.
+#
 # 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
index d8dc01203146..6cb6d405ab8b 100644
--- 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')
             ]),
 


        


More information about the libcxx-commits mailing list