+2020-01-13 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/58605
+ * include/bits/atomic_base.h (__cpp_lib_atomic_value_initialization):
+ Define.
+ (__atomic_flag_base, __atomic_base, __atomic_base<_PTp*>)
+ (__atomic_float): Add default member initializer for C++20.
+ * include/std/atomic (atomic): Likewise.
+ (atomic::atomic()): Remove noexcept-specifier on default constructor.
+ * include/std/version (__cpp_lib_atomic_value_initialization): Define.
+ * testsuite/29_atomics/atomic/cons/assign_neg.cc: Adjust dg-error line
+ number.
+ * testsuite/29_atomics/atomic/cons/copy_neg.cc: Likewise.
+ * testsuite/29_atomics/atomic/cons/value_init.cc: New test.
+ * testsuite/29_atomics/atomic_flag/cons/value_init.cc: New test.
+ * testsuite/29_atomics/atomic_flag/requirements/trivial.cc: Adjust
+ expected result for is_trivially_default_constructible.
+ * testsuite/29_atomics/atomic_float/requirements.cc: Likewise.
+ * testsuite/29_atomics/atomic_float/value_init.cc: New test.
+ * testsuite/29_atomics/atomic_integral/cons/assign_neg.cc: Likewise.
+ * testsuite/29_atomics/atomic_integral/cons/copy_neg.cc: Likewise.
+ * testsuite/29_atomics/atomic_integral/cons/value_init.cc
+ * testsuite/29_atomics/atomic_integral/requirements/trivial.cc: Adjust
+ expected results for is_trivially_default_constructible.
+ * testsuite/util/testsuite_common_types.h (has_trivial_dtor): Add
+ new test generator.
+
2020-01-10 Jonathan Wakely <jwakely@redhat.com>
* testsuite/util/testsuite_iterators.h: Improve comment.
template<typename _IntTp>
struct __atomic_base;
+#if __cplusplus <= 201703L
+# define _GLIBCXX20_INIT(I)
+#else
+# define __cpp_lib_atomic_value_initialization 201911L
+# define _GLIBCXX20_INIT(I) = I
+#endif
#define ATOMIC_VAR_INIT(_VI) { _VI }
struct __atomic_flag_base
{
- __atomic_flag_data_type _M_i;
+ __atomic_flag_data_type _M_i _GLIBCXX20_INIT({});
};
_GLIBCXX_END_EXTERN_C
static constexpr int _S_alignment =
sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp);
- alignas(_S_alignment) __int_type _M_i;
+ alignas(_S_alignment) __int_type _M_i _GLIBCXX20_INIT(0);
public:
__atomic_base() noexcept = default;
private:
typedef _PTp* __pointer_type;
- __pointer_type _M_p;
+ __pointer_type _M_p _GLIBCXX20_INIT(nullptr);
// Factored out to facilitate explicit specialization.
constexpr ptrdiff_t
{ return __atomic_impl::__sub_fetch_flt(&_M_fp, __i); }
private:
- alignas(_S_alignment) _Fp _M_fp;
+ alignas(_S_alignment) _Fp _M_fp _GLIBCXX20_INIT(0);
};
+#undef _GLIBCXX20_INIT
template<typename _Tp,
bool = is_integral_v<_Tp>, bool = is_floating_point_v<_Tp>>
{ return _M_base.compare_exchange_strong(__i1, __i2, __m); }
};
+#if __cplusplus <= 201703L
+# define _GLIBCXX20_INIT(I)
+#else
+# define _GLIBCXX20_INIT(I) = I
+#endif
/**
* @brief Generic atomic type, primary class template.
static constexpr int _S_alignment
= _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
- alignas(_S_alignment) _Tp _M_i;
+ alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
static_assert(__is_trivially_copyable(_Tp),
"std::atomic requires a trivially copyable type");
"Incomplete or zero-sized types are not supported");
public:
- atomic() noexcept = default;
+ atomic() = default;
~atomic() noexcept = default;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
{ return compare_exchange_strong(__e, __i, __m,
__cmpexch_failure_order(__m)); }
};
-
+#undef _GLIBCXX20_INIT
/// Partial specialization for pointer types.
template<typename _Tp>
#if __cplusplus > 201703L
// c++2a
#define __cpp_lib_atomic_ref 201806L
+#define __cpp_lib_atomic_value_initialization 201911L
#define __cpp_lib_bitops 201907L
#define __cpp_lib_bounded_array_traits 201902L
#if __cpp_concepts
return 0;
}
-// { dg-error "deleted" "" { target *-*-* } 639 }
+// { dg-error "deleted" "" { target *-*-* } 659 }
// { dg-prune-output "include" }
return 0;
}
-// { dg-error "deleted" "" { target *-*-* } 678 }
+// { dg-error "deleted" "" { target *-*-* } 698 }
// { dg-prune-output "include" }
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+
+#ifndef __cpp_lib_atomic_value_initialization
+# error "Feature test macro for atomic value-initialization is missing"
+#elif __cpp_lib_atomic_value_initialization < 201911L
+# error "Feature test macro for atomic value-initialization has wrong value"
+#endif
+
+#include <testsuite_hooks.h>
+
+struct A
+{
+ constexpr A() : val(42) { }
+ int val;
+};
+
+constexpr std::atomic<A> a;
+
+void
+test01()
+{
+ VERIFY(a.load().val == 42);
+ static_assert(!std::is_nothrow_default_constructible_v<std::atomic<A>>);
+}
+
+struct B
+{
+ constexpr B() noexcept : val(99) { }
+ int val;
+};
+
+constexpr std::atomic<B> b;
+
+void
+test02()
+{
+ VERIFY(b.load().val == 99);
+ static_assert(std::is_nothrow_default_constructible_v<std::atomic<B>>);
+}
+
+constexpr std::atomic<int*> c;
+
+void
+test03()
+{
+ VERIFY(c.load() == nullptr);
+ static_assert(std::is_nothrow_default_constructible_v<std::atomic<int*>>);
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::atomic_flag f;
+ VERIFY(!f.test_and_set());
+ VERIFY(f.test_and_set());
+ static_assert(std::is_nothrow_default_constructible_v<std::atomic_flag>);
+}
+
+int
+main()
+{
+ test01();
+}
void test01()
{
+#if __cplusplus <= 201703L
__gnu_test::has_trivial_cons_dtor test;
+#else
+ __gnu_test::has_trivial_dtor test;
+#endif
test.operator()<std::atomic_flag>();
}
{
using A = std::atomic<float>;
static_assert( std::is_standard_layout_v<A> );
- static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( !std::is_trivially_default_constructible_v<A> );
static_assert( std::is_trivially_destructible_v<A> );
static_assert( std::is_same_v<A::value_type, float> );
static_assert( std::is_same_v<A::difference_type, A::value_type> );
{
using A = std::atomic<double>;
static_assert( std::is_standard_layout_v<A> );
- static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( !std::is_trivially_default_constructible_v<A> );
static_assert( std::is_trivially_destructible_v<A> );
static_assert( std::is_same_v<A::value_type, double> );
static_assert( std::is_same_v<A::difference_type, A::value_type> );
{
using A = std::atomic<long double>;
static_assert( std::is_standard_layout_v<A> );
- static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( !std::is_trivially_default_constructible_v<A> );
static_assert( std::is_trivially_destructible_v<A> );
static_assert( std::is_same_v<A::value_type, long double> );
static_assert( std::is_same_v<A::difference_type, A::value_type> );
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+constexpr std::atomic<double> a;
+
+void
+test01()
+{
+ VERIFY(a.load() == 0);
+ static_assert(std::is_nothrow_default_constructible_v<std::atomic<double>>);
+}
+
+int
+main()
+{
+ test01();
+}
return 0;
}
-// { dg-error "deleted" "" { target *-*-* } 639 }
+// { dg-error "deleted" "" { target *-*-* } 659 }
// { dg-prune-output "include" }
return 0;
}
-// { dg-error "deleted" "" { target *-*-* } 678 }
+// { dg-error "deleted" "" { target *-*-* } 698 }
// { dg-prune-output "include" }
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+constexpr std::atomic<int> a;
+
+void
+test01()
+{
+ VERIFY(a.load() == 0);
+ static_assert(std::is_nothrow_default_constructible_v<std::atomic<int>>);
+}
+
+int
+main()
+{
+ test01();
+}
void test01()
{
+#if __cplusplus <= 201703L
__gnu_test::has_trivial_cons_dtor test;
+#else
+ __gnu_test::has_trivial_dtor test;
+#endif
__gnu_cxx::typelist::apply_generator(test,
__gnu_test::atomic_integrals::type());
}
}
};
- // Generator to test standard layout
struct has_trivial_cons_dtor
{
template<typename _Tp>
}
};
+ struct has_trivial_dtor
+ {
+ template<typename _Tp>
+ void
+ operator()()
+ {
+ struct _Concept
+ {
+ void __constraint()
+ {
+ typedef std::is_trivially_destructible<_Tp> dtor_p;
+ static_assert(dtor_p::value, "destructor not trivial");
+ }
+ };
+
+ void (_Concept::*__x)() __attribute__((unused))
+ = &_Concept::__constraint;
+ }
+ };
+
+ // Generator to test standard layout
struct standard_layout
{
template<typename _Tp>