ldionne created this revision.
ldionne added reviewers: EricWF, vsapsai.
Herald added subscribers: cfe-commits, dexonsmith, christof.

The aligned allocation and deallocation functions were added in the dylib
in Mac OSX 10.13. This commit does two things: first, it adds availability
markup to those functions such that clients targetting older OSes get a
compiler error instead of a link error if they try to use these functions.

Secondly, it makes sure that the library itself does not use these functions
when targetting older OSes.

rdar://problem/34223934
rdar://problem/42826941


Repository:
  rCXX libc++

https://reviews.llvm.org/D50205

Files:
  libcxx/include/__config
  libcxx/include/memory
  libcxx/include/new
  
libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
  
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
  libcxx/test/support/test_macros.h

Index: libcxx/test/support/test_macros.h
===================================================================
--- libcxx/test/support/test_macros.h
+++ libcxx/test/support/test_macros.h
@@ -182,7 +182,7 @@
 #define TEST_NORETURN [[noreturn]]
 #endif
 
-#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
+#if defined(_LIBCPP_DONT_USE_ALIGNED_ALLOCATION) || \
   (!(TEST_STD_VER > 14 || \
     (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606L)))
 #define TEST_HAS_NO_ALIGNED_ALLOCATION
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
@@ -13,6 +13,13 @@
 // NOTE: GCC doesn't provide a -faligned-allocation flag
 // XFAIL: no-aligned-allocation && !gcc
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // test operator new replacement
 
 #include <new>
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
@@ -17,6 +17,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // NOTE: gcc doesn't provide -faligned-allocation flag to test for
 // XFAIL: no-aligned-allocation && !gcc
 
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
@@ -16,6 +16,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // asan and msan will not call the new handler.
 // UNSUPPORTED: sanitizer-new-delete
 
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
@@ -16,6 +16,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // asan and msan will not call the new handler.
 // UNSUPPORTED: sanitizer-new-delete
 
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
@@ -23,6 +23,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // On Windows libc++ doesn't provide its own definitions for new/delete
 // but instead depends on the ones in VCRuntime. However VCRuntime does not
 // yet provide aligned new/delete definitions so this test fails to compile/link.
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
@@ -13,6 +13,13 @@
 // NOTE: GCC doesn't provide the -faligned-allocation flag to test for
 // XFAIL: no-aligned-allocation && !gcc
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // test operator new replacement
 
 #include <new>
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
@@ -17,6 +17,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // XFAIL: no-aligned-allocation && !gcc
 
 // On Windows libc++ doesn't provide its own definitions for new/delete
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
@@ -22,6 +22,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // On Windows libc++ doesn't provide its own definitions for new/delete
 // but instead depends on the ones in VCRuntime. However VCRuntime does not
 // yet provide aligned new/delete definitions so this test fails to compile/link.
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
@@ -22,6 +22,12 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
 
 // On Windows libc++ doesn't provide its own definitions for new/delete
 // but instead depends on the ones in VCRuntime. However VCRuntime does not
Index: libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
===================================================================
--- libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
+++ libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
@@ -24,6 +24,13 @@
 // XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
 
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
+
 // On Windows libc++ doesn't provide its own definitions for new/delete
 // but instead depends on the ones in VCRuntime. However VCRuntime does not
 // yet provide aligned new/delete definitions so this test fails to compile/link.
Index: libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
===================================================================
--- libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
+++ libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
@@ -20,8 +20,15 @@
 // XFAIL: with_system_cxx_lib=macosx10.11
 // XFAIL: with_system_cxx_lib=macosx10.10
 // XFAIL: with_system_cxx_lib=macosx10.9
-// XFAIL: with_system_cxx_lib=macosx10.7
 // XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
+// XFAIL: availability=macosx10.12
+// XFAIL: availability=macosx10.11
+// XFAIL: availability=macosx10.10
+// XFAIL: availability=macosx10.9
+// XFAIL: availability=macosx10.8
+// XFAIL: availability=macosx10.7
 
 // RUN: %build -faligned-allocation
 // RUN: %run
Index: libcxx/include/new
===================================================================
--- libcxx/include/new
+++ libcxx/include/new
@@ -114,6 +114,12 @@
 # define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
 #endif
 
+// Aligned allocation functions were added to the dylib in macos 10.13, so
+// don't use them in the library if we target an OS that might not have them.
+#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \
+      (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300)
+#  define _LIBCPP_DONT_USE_ALIGNED_ALLOCATION
+#endif
 
 #if !__has_builtin(__builtin_operator_new) || \
    __has_builtin(__builtin_operator_new) < 201802L || \
@@ -206,18 +212,18 @@
 #endif
 
 #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
-_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
-_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
-_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
-_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
 #ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
 _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
 #endif
 
-_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
-_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
-_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
-_LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE _LIBCPP_OVERRIDABLE_FUNC_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
 #ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
 _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
 #endif
@@ -241,7 +247,7 @@
 }
 
 inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t __align) {
-#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#ifndef _LIBCPP_DONT_USE_ALIGNED_ALLOCATION
   if (__is_overaligned_for_new(__align)) {
     const align_val_t __align_val = static_cast<align_val_t>(__align);
 # ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
@@ -261,7 +267,7 @@
 }
 
 inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __align) {
-#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#ifndef _LIBCPP_DONT_USE_ALIGNED_ALLOCATION
   if (__is_overaligned_for_new(__align)) {
     const align_val_t __align_val = static_cast<align_val_t>(__align);
 # ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE
Index: libcxx/include/memory
===================================================================
--- libcxx/include/memory
+++ libcxx/include/memory
@@ -2015,7 +2015,7 @@
         __n = __m;
     while (__n > 0)
     {
-#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+#if !defined(_LIBCPP_DONT_USE_ALIGNED_ALLOCATION)
     if (__is_overaligned_for_new(__alignof(_Tp)))
         {
             std::align_val_t __al =
Index: libcxx/include/__config
===================================================================
--- libcxx/include/__config
+++ libcxx/include/__config
@@ -991,7 +991,6 @@
 #  endif
 #endif // defined(__APPLE__)
 
-
 #if defined(__APPLE__) || defined(__FreeBSD__)
 #define _LIBCPP_HAS_DEFAULTRUNELOCALE
 #endif
@@ -1274,6 +1273,8 @@
 #  define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR                               \
      __attribute__((availability(macosx,strict,introduced=10.9)))              \
      __attribute__((availability(ios,strict,introduced=7.0)))
+#  define _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE                              \
+     __attribute__((availability(macosx,strict,introduced=10.13)))
 #else
 #  define _LIBCPP_AVAILABILITY_SHARED_MUTEX
 #  define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
@@ -1285,6 +1286,7 @@
 #  define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
 #  define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
 #  define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
+#  define _LIBCPP_AVAILABILITY_ALIGNED_NEW_DELETE
 #endif
 
 // Define availability that depends on _LIBCPP_NO_EXCEPTIONS.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to