[libcxx] r180945 - Stephan Tolksdorf: fixes the issue in the <atomic> header and adds corresponding tests. I've used macros to fall back to a user-provided default constructor if _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS (though I suspect that there won't be many users defining that macro).

Howard Hinnant hhinnant at apple.com
Thu May 2 13:18:43 PDT 2013


Author: hhinnant
Date: Thu May  2 15:18:43 2013
New Revision: 180945

URL: http://llvm.org/viewvc/llvm-project?rev=180945&view=rev
Log:
Stephan Tolksdorf: fixes the issue in the <atomic> header and adds corresponding tests. I've used macros to fall back to a user-provided default constructor if _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS (though I suspect that there won't be many users defining that macro).

The tests use placement new to check that atomic values get properly zero-initialized. I had to modify the atomic_is_lock_free test, because default initialization of an object of const type 'const A' (aka 'const atomic<int>') requires a user-provided default constructor.

Modified:
    libcxx/trunk/CREDITS.TXT
    libcxx/trunk/include/__config
    libcxx/trunk/include/atomic
    libcxx/trunk/test/atomics/atomics.flag/default.pass.cpp
    libcxx/trunk/test/atomics/atomics.types.generic/address.pass.cpp
    libcxx/trunk/test/atomics/atomics.types.generic/bool.pass.cpp
    libcxx/trunk/test/atomics/atomics.types.generic/integral.pass.cpp
    libcxx/trunk/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp

Modified: libcxx/trunk/CREDITS.TXT
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/CREDITS.TXT?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/CREDITS.TXT (original)
+++ libcxx/trunk/CREDITS.TXT Thu May  2 15:18:43 2013
@@ -48,6 +48,10 @@ N: Argyrios Kyrtzidis
 E: kyrtzidis at apple.com
 D: Bug fixes.
 
+N: Bruce Mitchener, Jr.
+E: bruce.mitchener at gmail.com
+D: Emscripten-related changes.
+
 N: Michel Morin
 E: mimomorin at gmail.com
 D: Minor patches to is_convertible.
@@ -78,6 +82,10 @@ N: Joerg Sonnenberger
 E: joerg at NetBSD.org
 D: NetBSD port.
 
+N: Stephan Tolksdorf
+E: st at quanttec.com
+D: Minor <atomic> fix
+
 N: Michael van der Westhuizen
 E: r1mikey at gmail dot com
 
@@ -93,7 +101,3 @@ N: Jeffrey Yasskin
 E: jyasskin at gmail.com
 E: jyasskin at google.com
 D: Linux fixes.
-
-N: Bruce Mitchener, Jr.
-E: bruce.mitchener at gmail.com
-D: Emscripten-related changes.

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Thu May  2 15:18:43 2013
@@ -216,7 +216,9 @@ typedef __char32_t char32_t;
 #  define _LIBCPP_NORETURN __attribute__ ((noreturn))
 #endif
 
+#if !(__has_feature(cxx_defaulted_functions))
 #define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#endif  // !(__has_feature(cxx_defaulted_functions))
 
 #if !(__has_feature(cxx_deleted_functions))
 #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS
@@ -422,6 +424,12 @@ template <unsigned> struct __static_asse
 #define _LIBCPP_CONSTEXPR constexpr
 #endif
 
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+#define _LIBCPP_DEFAULT {}
+#else
+#define _LIBCPP_DEFAULT = default;
+#endif
+
 #ifdef __GNUC__
 #define _NOALIAS __attribute__((__malloc__))
 #else

Modified: libcxx/trunk/include/atomic
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/include/atomic (original)
+++ libcxx/trunk/include/atomic Thu May  2 15:18:43 2013
@@ -622,7 +622,12 @@ struct __atomic_base  // false
         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
 
     _LIBCPP_INLINE_VISIBILITY
-    __atomic_base() _NOEXCEPT {} // = default;
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    __atomic_base() _NOEXCEPT = default;
+#else
+    __atomic_base() _NOEXCEPT : __a_() {}
+#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
@@ -645,7 +650,7 @@ struct __atomic_base<_Tp, true>
 {
     typedef __atomic_base<_Tp, false> __base;
     _LIBCPP_INLINE_VISIBILITY
-    __atomic_base() _NOEXCEPT {} // = default;
+    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
 
@@ -726,7 +731,7 @@ struct atomic
 {
     typedef __atomic_base<_Tp> __base;
     _LIBCPP_INLINE_VISIBILITY
-    atomic() _NOEXCEPT {} // = default;
+    atomic() _NOEXCEPT _LIBCPP_DEFAULT
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
 
@@ -746,7 +751,7 @@ struct atomic<_Tp*>
 {
     typedef __atomic_base<_Tp*> __base;
     _LIBCPP_INLINE_VISIBILITY
-    atomic() _NOEXCEPT {} // = default;
+    atomic() _NOEXCEPT _LIBCPP_DEFAULT
     _LIBCPP_INLINE_VISIBILITY
     _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
 
@@ -1367,7 +1372,12 @@ typedef struct atomic_flag
         {__c11_atomic_store(&__a_, false, __m);}
 
     _LIBCPP_INLINE_VISIBILITY
-    atomic_flag() _NOEXCEPT {} // = default;
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+    atomic_flag() _NOEXCEPT = default;
+#else
+    atomic_flag() _NOEXCEPT : __a_() {}
+#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+
     _LIBCPP_INLINE_VISIBILITY
     atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
 

Modified: libcxx/trunk/test/atomics/atomics.flag/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/atomics/atomics.flag/default.pass.cpp?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/test/atomics/atomics.flag/default.pass.cpp (original)
+++ libcxx/trunk/test/atomics/atomics.flag/default.pass.cpp Thu May  2 15:18:43 2013
@@ -14,9 +14,18 @@
 // atomic_flag() = default;
 
 #include <atomic>
+#include <new>
 #include <cassert>
 
 int main()
 {
     std::atomic_flag f;
+
+    {
+        typedef std::atomic_flag A;
+        _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
+        A& zero = *new (storage) A();
+        assert(!zero.test_and_set());
+        zero.~A();
+    }
 }

Modified: libcxx/trunk/test/atomics/atomics.types.generic/address.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/atomics/atomics.types.generic/address.pass.cpp?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/test/atomics/atomics.types.generic/address.pass.cpp (original)
+++ libcxx/trunk/test/atomics/atomics.types.generic/address.pass.cpp Thu May  2 15:18:43 2013
@@ -66,6 +66,7 @@
 // };
 
 #include <atomic>
+#include <new>
 #include <type_traits>
 #include <cassert>
 
@@ -112,6 +113,13 @@ do_test()
     assert(obj == T(5*sizeof(X)));
     assert((obj -= std::ptrdiff_t(3)) == T(2*sizeof(X)));
     assert(obj == T(2*sizeof(X)));
+
+    {
+        _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23};
+        A& zero = *new (storage) A();    
+        assert(zero == 0);
+        zero.~A();
+    }
 }
 
 template <class A, class T>

Modified: libcxx/trunk/test/atomics/atomics.types.generic/bool.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/atomics/atomics.types.generic/bool.pass.cpp?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/test/atomics/atomics.types.generic/bool.pass.cpp (original)
+++ libcxx/trunk/test/atomics/atomics.types.generic/bool.pass.cpp Thu May  2 15:18:43 2013
@@ -50,6 +50,7 @@
 // typedef atomic<bool> atomic_bool;
 
 #include <atomic>
+#include <new>
 #include <cassert>
 
 int main()
@@ -219,4 +220,11 @@ int main()
         assert((obj = true) == true);
         assert(obj == true);
     }
+    {
+        typedef std::atomic<bool> A;
+        _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
+        A& zero = *new (storage) A();    
+        assert(zero == false);
+        zero.~A();
+    }
 }

Modified: libcxx/trunk/test/atomics/atomics.types.generic/integral.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/atomics/atomics.types.generic/integral.pass.cpp?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/test/atomics/atomics.types.generic/integral.pass.cpp (original)
+++ libcxx/trunk/test/atomics/atomics.types.generic/integral.pass.cpp Thu May  2 15:18:43 2013
@@ -85,6 +85,7 @@
 // };
 
 #include <atomic>
+#include <new>
 #include <cassert>
 
 template <class A, class T>
@@ -143,6 +144,13 @@ do_test()
     assert(obj == T(7));
     assert((obj ^= T(0xF)) == T(8));
     assert(obj == T(8));
+
+    {
+        _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23};
+        A& zero = *new (storage) A();    
+        assert(zero == 0);
+        zero.~A();
+    }
 }
 
 template <class A, class T>

Modified: libcxx/trunk/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp?rev=180945&r1=180944&r2=180945&view=diff
==============================================================================
--- libcxx/trunk/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp (original)
+++ libcxx/trunk/test/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp Thu May  2 15:18:43 2013
@@ -24,10 +24,10 @@ void
 test()
 {
     typedef std::atomic<T> A;
-    const A ct;
-    bool b1 = std::atomic_is_lock_free(&ct);
-    const volatile A cvt;
-    bool b2 = std::atomic_is_lock_free(&cvt);
+    A t;
+    bool b1 = std::atomic_is_lock_free(static_cast<const A*>(&t));
+    volatile A vt;
+    bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&vt));
 }
 
 struct A





More information about the cfe-commits mailing list