commit 6d5bde9f90e7f1470d3f8d53b3288e6832f536df Author: Jonathan Wakely Date: Thu Apr 28 11:45:22 2016 +0100 libstdc++/70766 use std::addressof instead of operator& PR libstdc++/70766 * include/bits/basic_ios.tcc (basic_ios::_M_cache_locale): Use __addressof. * include/bits/stream_iterator.h (istream_iterator, ostream_iterator): Likewise. * include/std/atomic (atomic<_Tp>): Likewise. * include/std/shared_mutex (shared_lock): Likewise. * testsuite/24_iterators/istream_iterator/70766.cc: New test. * testsuite/24_iterators/ostream_iterator/70766.cc : New test. * testsuite/29_atomics/atomic/60695.cc: Adjust dg-error line number. * testsuite/29_atomics/atomic/70766.cc: New test. * testsuite/30_threads/shared_lock/70766.cc: New test. diff --git a/libstdc++-v3/include/bits/basic_ios.tcc b/libstdc++-v3/include/bits/basic_ios.tcc index 6c2ea11..0469220 100644 --- a/libstdc++-v3/include/bits/basic_ios.tcc +++ b/libstdc++-v3/include/bits/basic_ios.tcc @@ -157,17 +157,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc) { if (__builtin_expect(has_facet<__ctype_type>(__loc), true)) - _M_ctype = &use_facet<__ctype_type>(__loc); + _M_ctype = std::__addressof(use_facet<__ctype_type>(__loc)); else _M_ctype = 0; if (__builtin_expect(has_facet<__num_put_type>(__loc), true)) - _M_num_put = &use_facet<__num_put_type>(__loc); + _M_num_put = std::__addressof(use_facet<__num_put_type>(__loc)); else _M_num_put = 0; if (__builtin_expect(has_facet<__num_get_type>(__loc), true)) - _M_num_get = &use_facet<__num_get_type>(__loc); + _M_num_get = std::__addressof(use_facet<__num_get_type>(__loc)); else _M_num_get = 0; } diff --git a/libstdc++-v3/include/bits/stream_iterator.h b/libstdc++-v3/include/bits/stream_iterator.h index f9c6ba6..4afba4e 100644 --- a/libstdc++-v3/include/bits/stream_iterator.h +++ b/libstdc++-v3/include/bits/stream_iterator.h @@ -66,7 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// Construct start of input stream iterator. istream_iterator(istream_type& __s) - : _M_stream(&__s) + : _M_stream(std::__addressof(__s)) { _M_read(); } istream_iterator(const istream_iterator& __obj) @@ -84,7 +84,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } const _Tp* - operator->() const { return &(operator*()); } + operator->() const { return std::__addressof((operator*())); } istream_iterator& operator++() @@ -168,7 +168,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION public: /// Construct from an ostream. - ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream_type& __s) + : _M_stream(std::__addressof(__s)), _M_string(0) {} /** * Construct from an ostream. diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index bdc1f25..3c8ece8 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -39,6 +39,7 @@ #else #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -222,17 +223,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept - { __atomic_store(&_M_i, &__i, __m); } + { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } void store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept - { __atomic_store(&_M_i, &__i, __m); } + { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); } _Tp load(memory_order __m = memory_order_seq_cst) const noexcept { _Tp tmp; - __atomic_load(&_M_i, &tmp, __m); + __atomic_load(std::__addressof(_M_i), std::__addressof(tmp), __m); return tmp; } @@ -240,7 +241,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION load(memory_order __m = memory_order_seq_cst) const volatile noexcept { _Tp tmp; - __atomic_load(&_M_i, &tmp, __m); + __atomic_load(std::__addressof(_M_i), std::__addressof(tmp), __m); return tmp; } @@ -248,7 +249,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { _Tp tmp; - __atomic_exchange(&_M_i, &__i, &tmp, __m); + __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), + std::__addressof(tmp), __m); return tmp; } @@ -257,7 +259,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION memory_order __m = memory_order_seq_cst) volatile noexcept { _Tp tmp; - __atomic_exchange(&_M_i, &__i, &tmp, __m); + __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), + std::__addressof(tmp), __m); return tmp; } @@ -265,14 +268,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); + return __atomic_compare_exchange(std::__addressof(_M_i), + std::__addressof(__e), + std::__addressof(__i), + true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); + return __atomic_compare_exchange(std::__addressof(_M_i), + std::__addressof(__e), + std::__addressof(__i), + true, __s, __f); } bool @@ -291,14 +300,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); + return __atomic_compare_exchange(std::__addressof(_M_i), + std::__addressof(__e), + std::__addressof(__i), + false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); + return __atomic_compare_exchange(std::__addressof(_M_i), + std::__addressof(__e), + std::__addressof(__i), + false, __s, __f); } bool diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex index d87ac56..6ca322b 100644 --- a/libstdc++-v3/include/std/shared_mutex +++ b/libstdc++-v3/include/std/shared_mutex @@ -550,27 +550,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION shared_lock() noexcept : _M_pm(nullptr), _M_owns(false) { } explicit - shared_lock(mutex_type& __m) : _M_pm(&__m), _M_owns(true) + shared_lock(mutex_type& __m) + : _M_pm(std::__addressof(__m)), _M_owns(true) { __m.lock_shared(); } shared_lock(mutex_type& __m, defer_lock_t) noexcept - : _M_pm(&__m), _M_owns(false) { } + : _M_pm(std::__addressof(__m)), _M_owns(false) { } shared_lock(mutex_type& __m, try_to_lock_t) - : _M_pm(&__m), _M_owns(__m.try_lock_shared()) { } + : _M_pm(std::__addressof(__m)), _M_owns(__m.try_lock_shared()) { } shared_lock(mutex_type& __m, adopt_lock_t) - : _M_pm(&__m), _M_owns(true) { } + : _M_pm(std::__addressof(__m)), _M_owns(true) { } template shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) - : _M_pm(&__m), _M_owns(__m.try_lock_shared_until(__abs_time)) { } + : _M_pm(std::__addressof(__m)), + _M_owns(__m.try_lock_shared_until(__abs_time)) { } template shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) - : _M_pm(&__m), _M_owns(__m.try_lock_shared_for(__rel_time)) { } + : _M_pm(std::__addressof(__m)), + _M_owns(__m.try_lock_shared_for(__rel_time)) { } ~shared_lock() { diff --git a/libstdc++-v3/testsuite/24_iterators/istream_iterator/70766.cc b/libstdc++-v3/testsuite/24_iterators/istream_iterator/70766.cc new file mode 100644 index 0000000..3018e34 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istream_iterator/70766.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include +#include + +namespace adl +{ + template + void operator&(const T&) = delete; + + struct traits : std::char_traits { }; + + struct X { void f() const { } }; + + std::basic_istream& + operator>>(std::basic_istream& is, X&) + { return is; } +} + +void +test01() +{ + std::basic_istream is(nullptr); + std::istream_iterator ii(is); + ii->f(); +} diff --git a/libstdc++-v3/testsuite/24_iterators/ostream_iterator/70766.cc b/libstdc++-v3/testsuite/24_iterators/ostream_iterator/70766.cc new file mode 100644 index 0000000..1f6b943 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/ostream_iterator/70766.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include +#include + +namespace adl +{ + template + void operator&(const T&) = delete; + + struct traits : std::char_traits { }; +} + +void +test01() +{ + std::basic_ostream os(nullptr); + std::ostream_iterator oi(os); +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc index ddd1b2c..5977d54 100644 --- a/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc +++ b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc @@ -27,4 +27,4 @@ struct X { char stuff[0]; // GNU extension, type has zero size }; -std::atomic a; // { dg-error "not supported" "" { target *-*-* } 181 } +std::atomic a; // { dg-error "not supported" "" { target *-*-* } 182 } diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/70766.cc b/libstdc++-v3/testsuite/29_atomics/atomic/70766.cc new file mode 100644 index 0000000..1390e4e --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/70766.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +#include + +namespace adl +{ + template + void operator&(const T&) = delete; + + struct X { + int i; + }; +} + +void +test01() +{ + adl::X x; + std::atomic a; + a.store(x); + x = a.load(); + x = a.exchange(x); + a.compare_exchange_weak(x, x); + a.compare_exchange_strong(x, x); +} + +void +test02() +{ + adl::X x; + volatile std::atomic a; + a.store(x); + x = a.load(); + x = a.exchange(x); + a.compare_exchange_weak(x, x); + a.compare_exchange_strong(x, x); +} diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/70766.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/70766.cc new file mode 100644 index 0000000..940b7b1 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/shared_lock/70766.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile } + +#include + +namespace adl +{ + template + void operator&(const T&) = delete; + + struct M : std::shared_timed_mutex { }; +} + +void +test01() +{ + using namespace std::chrono_literals; + + adl::M m; + std::shared_lock l1(m); + std::shared_lock l2(m, std::defer_lock); + std::shared_lock l3(m, std::try_to_lock); + m.lock_shared(); + std::shared_lock l4(m, std::adopt_lock); + std::shared_lock l5(m, std::chrono::system_clock::now() + 1ms); + std::shared_lock l6(m, 1ms); +}