On 17 January 2013 00:21, Jonathan Wakely wrote: > This fixes a regression since 4.6 when -Wsystem-headers is used. The > initialization of the __atomic_flag_base base class has a narrowing > conversion from int (the macro) to either bool or unsigned char. The > patch fixes it by calling a constexpr function which implicitly > converts the value to the return type instead of doing the conversion > inside a braced-init-list. Doing that requires naming the return > type, so I defined a new typedef for to avoid duplicating the > preprocessor conditional. The patch also adds a missing assignment > operator in atomic<bool>. > > PR libstdc++/56012 > * include/bits/atomic_base.h (atomic_flag): Fix narrowing conversion. > * testsuite/29_atomics/atomic/operators/56012.cc: New. > > PR libstdc++/56011 > * include/std/atomic (atomic<bool>::operator=(bool) volatile): Add > missing overload. > * testsuite/29_atomics/atomic/operators/56011.cc: New. > > Tested x86_64-linux, it's a regression so I want to commit it to the > trunk and 4.7 branch, any objections from the atomics experts?
Committed to trunk, 4.7 to follow soon.
commit 9f33378b56382e14dce6279d40d44c268de714f8 Author: Jonathan Wakely <jwakely....@gmail.com> Date: Tue Feb 26 23:40:56 2013 +0000 PR libstdc++/56012 * include/bits/atomic_base.h (atomic_flag): Fix narrowing conversion. * testsuite/29_atomics/atomic/operators/56012.cc: New. PR libstdc++/56011 * include/std/atomic (atomic<bool>::operator=(bool) volatile): Add missing overload. * testsuite/29_atomics/atomic/operators/56011.cc: New. diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index b44e990..609fe8b 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -239,6 +239,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct atomic<_Tp*>; + /* The target's "set" value for test-and-set may not be exactly 1. */ +#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 + typedef bool __atomic_flag_data_type; +#else + typedef unsigned char __atomic_flag_data_type; +#endif /** * @brief Base type for atomic_flag. @@ -254,12 +260,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __atomic_flag_base { - /* The target's "set" value for test-and-set may not be exactly 1. */ -#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1 - bool _M_i; -#else - unsigned char _M_i; -#endif + __atomic_flag_data_type _M_i; }; _GLIBCXX_END_EXTERN_C @@ -277,7 +278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Conversion to ATOMIC_FLAG_INIT. constexpr atomic_flag(bool __i) noexcept - : __atomic_flag_base({ __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0 }) + : __atomic_flag_base{ _S_init(__i) } { } bool @@ -313,6 +314,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_clear (&_M_i, __m); } + + private: + static constexpr __atomic_flag_data_type + _S_init(bool __i) + { return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; } }; diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index 8ed53eb..813f574 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -69,6 +69,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(bool __i) noexcept { return _M_base.operator=(__i); } + bool + operator=(bool __i) volatile noexcept + { return _M_base.operator=(__i); } + operator bool() const noexcept { return _M_base.load(); } diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/operators/56011.cc b/libstdc++-v3/testsuite/29_atomics/atomic/operators/56011.cc new file mode 100644 index 0000000..1d77a55 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/operators/56011.cc @@ -0,0 +1,29 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2013 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/>. + +#include <atomic> +void test01() +{ + using namespace std; + volatile atomic<bool> ab1 __attribute__((unused)); + ab1 = true; + volatile atomic_bool ab2 __attribute__((unused)); + ab2 = true; +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_flag/cons/56012.cc b/libstdc++-v3/testsuite/29_atomics/atomic_flag/cons/56012.cc new file mode 100644 index 0000000..64f3b972 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic_flag/cons/56012.cc @@ -0,0 +1,26 @@ +// { dg-options "-std=gnu++0x -Wsystem-headers -Wnarrowing" } +// { dg-do compile } + +// Copyright (C) 2013 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/>. + +#include <atomic> +void test01() +{ + using namespace std; + atomic_flag af __attribute__((unused)) = ATOMIC_FLAG_INIT; +}