blob: ed8b541291af9910ff1df25ac2628d773b6b8841 [file] [log] [blame]
Howard Hinnant91e2f262010-12-07 20:46:14 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Jonathan Roelofs8d86b2e2014-09-05 19:45:05 +00009//
10// UNSUPPORTED: libcpp-has-no-threads
11// ... test crashes clang
Howard Hinnant91e2f262010-12-07 20:46:14 +000012
13// <atomic>
14
15// template <class Integral>
16// Integral
17// atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op);
18//
19// template <class Integral>
20// Integral
21// atomic_fetch_sub(atomic<Integral>* obj, Integral op);
22//
23// template <class T>
24// T*
25// atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op);
26//
27// template <class T>
28// T*
29// atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op);
30
31#include <atomic>
Richard Smith9efdc0b2012-04-19 00:50:47 +000032#include <type_traits>
Howard Hinnant91e2f262010-12-07 20:46:14 +000033#include <cassert>
34
35template <class T>
Dan Albert1d4a1ed2016-05-25 22:36:09 -070036void
37test()
38{
Howard Hinnant91e2f262010-12-07 20:46:14 +000039 {
40 typedef std::atomic<T> A;
41 A t;
42 std::atomic_init(&t, T(3));
43 assert(std::atomic_fetch_sub(&t, T(2)) == T(3));
44 assert(t == T(1));
45 }
46 {
47 typedef std::atomic<T> A;
48 volatile A t;
49 std::atomic_init(&t, T(3));
50 assert(std::atomic_fetch_sub(&t, T(2)) == T(3));
51 assert(t == T(1));
52 }
Dan Albert1d4a1ed2016-05-25 22:36:09 -070053}
Howard Hinnant91e2f262010-12-07 20:46:14 +000054
Eric Fiselier00f4a492015-08-19 17:21:46 +000055template <class T>
Dan Albert1d4a1ed2016-05-25 22:36:09 -070056void
57testp()
Eric Fiselier00f4a492015-08-19 17:21:46 +000058{
59 {
60 typedef std::atomic<T> A;
61 typedef typename std::remove_pointer<T>::type X;
62 A t;
63 std::atomic_init(&t, T(3*sizeof(X)));
64 assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
65 assert(t == T(1*sizeof(X)));
66 }
67 {
68 typedef std::atomic<T> A;
69 typedef typename std::remove_pointer<T>::type X;
70 volatile A t;
71 std::atomic_init(&t, T(3*sizeof(X)));
72 assert(std::atomic_fetch_sub(&t, 2) == T(3*sizeof(X)));
73 assert(t == T(1*sizeof(X)));
74 }
75}
76
Dan Albert1d4a1ed2016-05-25 22:36:09 -070077struct A
78{
79 int i;
80
81 explicit A(int d = 0) noexcept {i=d;}
82 A(const A& a) : i(a.i) {}
83 A(const volatile A& a) : i(a.i) {}
84
85 void operator=(const volatile A& a) volatile {i = a.i;}
86
87 friend bool operator==(const A& x, const A& y)
88 {return x.i == y.i;}
89};
90
Howard Hinnant91e2f262010-12-07 20:46:14 +000091int main()
92{
Dan Albert1d4a1ed2016-05-25 22:36:09 -070093 test<char>();
94 test<signed char>();
95 test<unsigned char>();
96 test<short>();
97 test<unsigned short>();
98 test<int>();
99 test<unsigned int>();
100 test<long>();
101 test<unsigned long>();
102 test<long long>();
103 test<unsigned long long>();
104 test<wchar_t>();
105#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
106 test<char16_t>();
107 test<char32_t>();
108#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
Howard Hinnant91e2f262010-12-07 20:46:14 +0000109 testp<int*>();
110 testp<const int*>();
111}