Skip to content

Commit fa21c5d

Browse files
ldionnetstellar
authored andcommitted
[libc++] Make feature-test macros consistent with availability macros
Before this patch, feature-test macros didn't take special availability markup into account, which means that feature-test macros can sometimes appear to "lie". For example, if you compile in C++20 mode and target macOS 10.13, the __cpp_lib_filesystem feature-test macro will be provided even though the <filesystem> declarations are marked as unavailable. This patch fixes that. rdar://68142369 Differential Revision: https://reviews.llvm.org/D94983 (cherry picked from commit 76fc357)
1 parent 5cb4200 commit fa21c5d

File tree

11 files changed

+192
-139
lines changed

11 files changed

+192
-139
lines changed

libcxx/include/__availability

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@
4343
// as unavailable. When vendors decide to ship the feature as part of their
4444
// shared library, they can update the markup appropriately.
4545
//
46+
// Furthermore, many features in the standard library have corresponding
47+
// feature-test macros. When a feature is made unavailable on some deployment
48+
// target, a macro should be defined to signal that it is unavailable. That
49+
// macro can then be picked up when feature-test macros are generated (see
50+
// generate_feature_test_macro_components.py) to make sure that feature-test
51+
// macros don't announce a feature as being implemented if it has been marked
52+
// as unavailable.
53+
//
4654
// Note that this mechanism is disabled by default in the "upstream" libc++.
4755
// Availability annotations are only meaningful when shipping libc++ inside
4856
// a platform (i.e. as a system library), and so vendors that want them should
@@ -76,6 +84,8 @@
7684
// This controls the availability of std::shared_mutex and std::shared_timed_mutex,
7785
// which were added to the dylib later.
7886
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
87+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
88+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
7989

8090
// These macros control the availability of std::bad_optional_access and
8191
// other exception types. These were put in the shared library to prevent
@@ -114,6 +124,7 @@
114124
# define _LIBCPP_AVAILABILITY_FILESYSTEM
115125
# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
116126
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
127+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
117128

118129
// This controls the availability of std::to_chars.
119130
# define _LIBCPP_AVAILABILITY_TO_CHARS
@@ -122,6 +133,10 @@
122133
// which requires shared library support for various operations
123134
// (see libcxx/src/atomic.cpp).
124135
# define _LIBCPP_AVAILABILITY_SYNC
136+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
137+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
138+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
139+
// # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
125140

126141
#elif defined(__APPLE__)
127142

@@ -130,6 +145,14 @@
130145
__attribute__((availability(ios,strict,introduced=10.0))) \
131146
__attribute__((availability(tvos,strict,introduced=10.0))) \
132147
__attribute__((availability(watchos,strict,introduced=3.0)))
148+
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
149+
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
150+
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
151+
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
152+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex
153+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex
154+
# endif
155+
133156
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
134157
__attribute__((availability(macosx,strict,introduced=10.13))) \
135158
__attribute__((availability(ios,strict,introduced=11.0))) \
@@ -139,27 +162,34 @@
139162
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
140163
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
141164
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
165+
142166
# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
143167
__attribute__((availability(macosx,strict,introduced=10.12))) \
144168
__attribute__((availability(ios,strict,introduced=10.0))) \
145169
__attribute__((availability(tvos,strict,introduced=10.0))) \
146170
__attribute__((availability(watchos,strict,introduced=3.0)))
171+
147172
# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
148173
__attribute__((availability(macosx,strict,introduced=10.12))) \
149174
__attribute__((availability(ios,strict,introduced=10.0))) \
150175
__attribute__((availability(tvos,strict,introduced=10.0))) \
151176
__attribute__((availability(watchos,strict,introduced=3.0)))
177+
152178
# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \
153179
__attribute__((availability(ios,strict,introduced=6.0)))
180+
154181
# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
155182
__attribute__((availability(macosx,strict,introduced=10.9))) \
156183
__attribute__((availability(ios,strict,introduced=7.0)))
184+
157185
# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
158186
__attribute__((availability(macosx,strict,introduced=10.9))) \
159187
__attribute__((availability(ios,strict,introduced=7.0)))
188+
160189
# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
161190
__attribute__((availability(macosx,strict,introduced=10.9))) \
162191
__attribute__((availability(ios,strict,introduced=7.0)))
192+
163193
# define _LIBCPP_AVAILABILITY_FILESYSTEM \
164194
__attribute__((availability(macosx,strict,introduced=10.15))) \
165195
__attribute__((availability(ios,strict,introduced=13.0))) \
@@ -175,10 +205,23 @@
175205
_Pragma("clang attribute pop") \
176206
_Pragma("clang attribute pop") \
177207
_Pragma("clang attribute pop")
208+
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \
209+
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \
210+
(defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \
211+
(defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000)
212+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem
213+
# endif
214+
178215
# define _LIBCPP_AVAILABILITY_TO_CHARS \
179216
_LIBCPP_AVAILABILITY_FILESYSTEM
217+
218+
// Note: Those are not ABI-stable yet, so we can't ship them.
180219
# define _LIBCPP_AVAILABILITY_SYNC \
181220
__attribute__((unavailable))
221+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait
222+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier
223+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch
224+
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore
182225

183226
#else
184227

libcxx/include/version

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ __cpp_lib_void_t 201411L <type_traits>
184184
# define __cpp_lib_quoted_string_io 201304L
185185
# define __cpp_lib_result_of_sfinae 201210L
186186
# define __cpp_lib_robust_nonmodifying_seq_ops 201304L
187-
# if !defined(_LIBCPP_HAS_NO_THREADS)
187+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex)
188188
# define __cpp_lib_shared_timed_mutex 201402L
189189
# endif
190190
# define __cpp_lib_string_udls 201304L
@@ -213,7 +213,9 @@ __cpp_lib_void_t 201411L <type_traits>
213213
# define __cpp_lib_clamp 201603L
214214
# define __cpp_lib_enable_shared_from_this 201603L
215215
// # define __cpp_lib_execution 201603L
216-
# define __cpp_lib_filesystem 201703L
216+
# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
217+
# define __cpp_lib_filesystem 201703L
218+
# endif
217219
# define __cpp_lib_gcd_lcm 201606L
218220
// # define __cpp_lib_hardware_interference_size 201703L
219221
# if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
@@ -241,7 +243,7 @@ __cpp_lib_void_t 201411L <type_traits>
241243
# define __cpp_lib_raw_memory_algorithms 201606L
242244
# define __cpp_lib_sample 201603L
243245
# define __cpp_lib_scoped_lock 201703L
244-
# if !defined(_LIBCPP_HAS_NO_THREADS)
246+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex)
245247
# define __cpp_lib_shared_mutex 201505L
246248
# endif
247249
# define __cpp_lib_shared_ptr_arrays 201611L
@@ -279,10 +281,10 @@ __cpp_lib_void_t 201411L <type_traits>
279281
# if !defined(_LIBCPP_HAS_NO_THREADS)
280282
// # define __cpp_lib_atomic_value_initialization 201911L
281283
# endif
282-
# if !defined(_LIBCPP_HAS_NO_THREADS)
284+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
283285
# define __cpp_lib_atomic_wait 201907L
284286
# endif
285-
# if !defined(_LIBCPP_HAS_NO_THREADS)
287+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
286288
# define __cpp_lib_barrier 201907L
287289
# endif
288290
// # define __cpp_lib_bind_front 201907L
@@ -326,7 +328,7 @@ __cpp_lib_void_t 201411L <type_traits>
326328
# if !defined(_LIBCPP_HAS_NO_THREADS)
327329
// # define __cpp_lib_jthread 201911L
328330
# endif
329-
# if !defined(_LIBCPP_HAS_NO_THREADS)
331+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
330332
# define __cpp_lib_latch 201907L
331333
# endif
332334
# define __cpp_lib_list_remove_return_type 201806L
@@ -336,7 +338,7 @@ __cpp_lib_void_t 201411L <type_traits>
336338
// # define __cpp_lib_polymorphic_allocator 201902L
337339
// # define __cpp_lib_ranges 201811L
338340
# define __cpp_lib_remove_cvref 201711L
339-
# if !defined(_LIBCPP_HAS_NO_THREADS)
341+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore)
340342
# define __cpp_lib_semaphore 201907L
341343
# endif
342344
# define __cpp_lib_shift 201806L

libcxx/test/std/input.output/filesystems/fs.req.macros/feature_macro.pass.cpp

Lines changed: 0 additions & 30 deletions
This file was deleted.

libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@
248248
# endif
249249
# endif
250250

251-
# if !defined(_LIBCPP_HAS_NO_THREADS)
251+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
252252
# ifndef __cpp_lib_atomic_wait
253253
# error "__cpp_lib_atomic_wait should be defined in c++20"
254254
# endif
@@ -257,7 +257,7 @@
257257
# endif
258258
# else
259259
# ifdef __cpp_lib_atomic_wait
260-
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
260+
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait) is not defined!"
261261
# endif
262262
# endif
263263

@@ -367,7 +367,7 @@
367367
# endif
368368
# endif
369369

370-
# if !defined(_LIBCPP_HAS_NO_THREADS)
370+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait)
371371
# ifndef __cpp_lib_atomic_wait
372372
# error "__cpp_lib_atomic_wait should be defined in c++2b"
373373
# endif
@@ -376,7 +376,7 @@
376376
# endif
377377
# else
378378
# ifdef __cpp_lib_atomic_wait
379-
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
379+
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait) is not defined!"
380380
# endif
381381
# endif
382382

libcxx/test/std/language.support/support.limits/support.limits.general/barrier.version.pass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
#elif TEST_STD_VER == 20
4646

47-
# if !defined(_LIBCPP_HAS_NO_THREADS)
47+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
4848
# ifndef __cpp_lib_barrier
4949
# error "__cpp_lib_barrier should be defined in c++20"
5050
# endif
@@ -53,13 +53,13 @@
5353
# endif
5454
# else
5555
# ifdef __cpp_lib_barrier
56-
# error "__cpp_lib_barrier should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
56+
# error "__cpp_lib_barrier should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier) is not defined!"
5757
# endif
5858
# endif
5959

6060
#elif TEST_STD_VER > 20
6161

62-
# if !defined(_LIBCPP_HAS_NO_THREADS)
62+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier)
6363
# ifndef __cpp_lib_barrier
6464
# error "__cpp_lib_barrier should be defined in c++2b"
6565
# endif
@@ -68,7 +68,7 @@
6868
# endif
6969
# else
7070
# ifdef __cpp_lib_barrier
71-
# error "__cpp_lib_barrier should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
71+
# error "__cpp_lib_barrier should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier) is not defined!"
7272
# endif
7373
# endif
7474

libcxx/test/std/language.support/support.limits/support.limits.general/filesystem.version.pass.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,17 @@
5151
# error "__cpp_lib_char8_t should not be defined before c++20"
5252
# endif
5353

54-
# ifndef __cpp_lib_filesystem
55-
# error "__cpp_lib_filesystem should be defined in c++17"
56-
# endif
57-
# if __cpp_lib_filesystem != 201703L
58-
# error "__cpp_lib_filesystem should have the value 201703L in c++17"
54+
# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
55+
# ifndef __cpp_lib_filesystem
56+
# error "__cpp_lib_filesystem should be defined in c++17"
57+
# endif
58+
# if __cpp_lib_filesystem != 201703L
59+
# error "__cpp_lib_filesystem should have the value 201703L in c++17"
60+
# endif
61+
# else
62+
# ifdef __cpp_lib_filesystem
63+
# error "__cpp_lib_filesystem should not be defined when !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) is not defined!"
64+
# endif
5965
# endif
6066

6167
#elif TEST_STD_VER == 20
@@ -73,11 +79,17 @@
7379
# endif
7480
# endif
7581

76-
# ifndef __cpp_lib_filesystem
77-
# error "__cpp_lib_filesystem should be defined in c++20"
78-
# endif
79-
# if __cpp_lib_filesystem != 201703L
80-
# error "__cpp_lib_filesystem should have the value 201703L in c++20"
82+
# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
83+
# ifndef __cpp_lib_filesystem
84+
# error "__cpp_lib_filesystem should be defined in c++20"
85+
# endif
86+
# if __cpp_lib_filesystem != 201703L
87+
# error "__cpp_lib_filesystem should have the value 201703L in c++20"
88+
# endif
89+
# else
90+
# ifdef __cpp_lib_filesystem
91+
# error "__cpp_lib_filesystem should not be defined when !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) is not defined!"
92+
# endif
8193
# endif
8294

8395
#elif TEST_STD_VER > 20
@@ -95,11 +107,17 @@
95107
# endif
96108
# endif
97109

98-
# ifndef __cpp_lib_filesystem
99-
# error "__cpp_lib_filesystem should be defined in c++2b"
100-
# endif
101-
# if __cpp_lib_filesystem != 201703L
102-
# error "__cpp_lib_filesystem should have the value 201703L in c++2b"
110+
# if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem)
111+
# ifndef __cpp_lib_filesystem
112+
# error "__cpp_lib_filesystem should be defined in c++2b"
113+
# endif
114+
# if __cpp_lib_filesystem != 201703L
115+
# error "__cpp_lib_filesystem should have the value 201703L in c++2b"
116+
# endif
117+
# else
118+
# ifdef __cpp_lib_filesystem
119+
# error "__cpp_lib_filesystem should not be defined when !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) is not defined!"
120+
# endif
103121
# endif
104122

105123
#endif // TEST_STD_VER > 20

libcxx/test/std/language.support/support.limits/support.limits.general/latch.version.pass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
#elif TEST_STD_VER == 20
4646

47-
# if !defined(_LIBCPP_HAS_NO_THREADS)
47+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
4848
# ifndef __cpp_lib_latch
4949
# error "__cpp_lib_latch should be defined in c++20"
5050
# endif
@@ -53,13 +53,13 @@
5353
# endif
5454
# else
5555
# ifdef __cpp_lib_latch
56-
# error "__cpp_lib_latch should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
56+
# error "__cpp_lib_latch should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch) is not defined!"
5757
# endif
5858
# endif
5959

6060
#elif TEST_STD_VER > 20
6161

62-
# if !defined(_LIBCPP_HAS_NO_THREADS)
62+
# if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch)
6363
# ifndef __cpp_lib_latch
6464
# error "__cpp_lib_latch should be defined in c++2b"
6565
# endif
@@ -68,7 +68,7 @@
6868
# endif
6969
# else
7070
# ifdef __cpp_lib_latch
71-
# error "__cpp_lib_latch should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
71+
# error "__cpp_lib_latch should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch) is not defined!"
7272
# endif
7373
# endif
7474

0 commit comments

Comments
 (0)