mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-12 05:13:50 +08:00
re PR libstdc++/51811 ([C++0x] Incorrect increment/decrement of atomic pointers)
2012-02-03 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/51811 * include/bits/atomic_base.h (atomic<_Tp*>): Fix offsets. * testsuite/29_atomics/atomic/operators/51811.cc: New. * testsuite/29_atomics/atomic/operators/pointer_partial_void.cc: New. From-SVN: r183875
This commit is contained in:
parent
3bc05470eb
commit
4035739819
@ -1,3 +1,10 @@
|
||||
2012-02-03 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
PR libstdc++/51811
|
||||
* include/bits/atomic_base.h (atomic<_Tp*>): Fix offsets.
|
||||
* testsuite/29_atomics/atomic/operators/51811.cc: New.
|
||||
* testsuite/29_atomics/atomic/operators/pointer_partial_void.cc: New.
|
||||
|
||||
2012-02-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/abi/post/i386-linux-gnu/baseline_symbols.txt: Update.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- C++ -*- header.
|
||||
|
||||
// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012 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
|
||||
@ -621,6 +621,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
__pointer_type _M_p;
|
||||
|
||||
// Factored out to facilitate explicit specialization.
|
||||
constexpr ptrdiff_t
|
||||
_M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
|
||||
|
||||
constexpr ptrdiff_t
|
||||
_M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
|
||||
|
||||
public:
|
||||
__atomic_base() noexcept = default;
|
||||
~__atomic_base() noexcept = default;
|
||||
@ -669,43 +676,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
__pointer_type
|
||||
operator++() noexcept
|
||||
{ return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
|
||||
{ return __atomic_add_fetch(&_M_p, _M_type_size(1),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator++() volatile noexcept
|
||||
{ return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
|
||||
{ return __atomic_add_fetch(&_M_p, _M_type_size(1),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator--() noexcept
|
||||
{ return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
|
||||
{ return __atomic_sub_fetch(&_M_p, _M_type_size(1),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator--() volatile noexcept
|
||||
{ return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
|
||||
{ return __atomic_sub_fetch(&_M_p, _M_type_size(1),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator+=(ptrdiff_t __d) noexcept
|
||||
{ return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
|
||||
{ return __atomic_add_fetch(&_M_p, _M_type_size(__d),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator+=(ptrdiff_t __d) volatile noexcept
|
||||
{ return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
|
||||
{ return __atomic_add_fetch(&_M_p, _M_type_size(__d),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator-=(ptrdiff_t __d) noexcept
|
||||
{ return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
|
||||
{ return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
__pointer_type
|
||||
operator-=(ptrdiff_t __d) volatile noexcept
|
||||
{ return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
|
||||
{ return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
|
||||
memory_order_seq_cst); }
|
||||
|
||||
bool
|
||||
is_lock_free() const noexcept
|
||||
{ return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
|
||||
{ return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
|
||||
|
||||
bool
|
||||
is_lock_free() const volatile noexcept
|
||||
{ return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
|
||||
{ return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
|
||||
|
||||
void
|
||||
store(__pointer_type __p,
|
||||
@ -789,22 +804,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__pointer_type
|
||||
fetch_add(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_add(&_M_p, __d, __m); }
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
|
||||
|
||||
__pointer_type
|
||||
fetch_add(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_add(&_M_p, __d, __m); }
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
|
||||
|
||||
__pointer_type
|
||||
fetch_sub(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_sub(&_M_p, __d, __m); }
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
|
||||
|
||||
__pointer_type
|
||||
fetch_sub(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_sub(&_M_p, __d, __m); }
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
|
||||
};
|
||||
|
||||
// @} group atomics
|
||||
|
90
libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
Normal file
90
libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
Normal file
@ -0,0 +1,90 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// Copyright (C) 2012 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>
|
||||
#include <cstdlib> //std::abs
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// libstdc++/51811
|
||||
// pointer arithimetic vs. atomic<_Tp*> specialization
|
||||
int main(void)
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef int value_type;
|
||||
const size_t n = 2;
|
||||
value_type value = 42;
|
||||
atomic<value_type*> p, p2, p3;
|
||||
|
||||
// operator++
|
||||
{
|
||||
p = &value;
|
||||
p2 = p++;
|
||||
VERIFY (p != p2);
|
||||
|
||||
value_type* vp(p);
|
||||
value_type* vp2(p2);
|
||||
ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
|
||||
VERIFY ( std::abs(dist) == sizeof(value_type));
|
||||
|
||||
p = &value;
|
||||
p3 = ++p;
|
||||
VERIFY (p == p3);
|
||||
}
|
||||
|
||||
// operator--
|
||||
{
|
||||
p = &value;
|
||||
p2 = p--;
|
||||
VERIFY (p != p2);
|
||||
|
||||
value_type* vp(p);
|
||||
value_type* vp2(p2);
|
||||
ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
|
||||
VERIFY ( std::abs(dist) == sizeof(value_type));
|
||||
|
||||
p = &value;
|
||||
p3 = --p;
|
||||
VERIFY (p == p3);
|
||||
}
|
||||
|
||||
// operator+=
|
||||
{
|
||||
p = &value;
|
||||
value_type* vp(p);
|
||||
p+=n;
|
||||
value_type* vp2(p);
|
||||
ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
|
||||
VERIFY ( std::abs(dist) == sizeof(value_type) * n);
|
||||
}
|
||||
|
||||
// operator-=
|
||||
{
|
||||
p = &value;
|
||||
value_type* vp(p);
|
||||
p-=n;
|
||||
value_type* vp2(p);
|
||||
ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
|
||||
VERIFY ( std::abs(dist) == sizeof(value_type) * n);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
// { dg-options "-std=gnu++0x" }
|
||||
|
||||
// Copyright (C) 2012 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>
|
||||
#include <cstdlib> //std::abs
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// pointer arithimetic vs. atomic<void*>.
|
||||
// atomic<void*> vs. explicitly specialized w/o operators, like atomic_bool?
|
||||
int main(void)
|
||||
{
|
||||
// bool test __attribute__((unused)) = true;
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef int value_type;
|
||||
const size_t n = 2;
|
||||
value_type value = 42;
|
||||
value_type* p = &value;
|
||||
void* vp = p;
|
||||
ptrdiff_t dist(0);
|
||||
|
||||
atomic<void*> a(vp);
|
||||
|
||||
// operator++
|
||||
void* vp2(a);
|
||||
a++;
|
||||
void* vp3(a);
|
||||
dist = reinterpret_cast<char*>(vp2) - reinterpret_cast<char*>(vp3);
|
||||
// VERIFY ( std::abs(dist) == sizeof(void*));
|
||||
|
||||
// operator--
|
||||
void* vp4(a);
|
||||
a--;
|
||||
void* vp5(a);
|
||||
dist = reinterpret_cast<char*>(vp4) - reinterpret_cast<char*>(vp5);
|
||||
// VERIFY ( std::abs(dist) == sizeof(void*));
|
||||
|
||||
// operator+=
|
||||
void* vp6(a);
|
||||
a+=n;
|
||||
void* vp7(a);
|
||||
dist = reinterpret_cast<char*>(vp6) - reinterpret_cast<char*>(vp7);
|
||||
// VERIFY ( std::abs(dist) == sizeof(void*) * n);
|
||||
|
||||
// operator-=
|
||||
void* vp8(a);
|
||||
a-=n;
|
||||
void* vp9(a);
|
||||
dist = reinterpret_cast<char*>(vp8) - reinterpret_cast<char*>(vp9);
|
||||
//VERIFY ( std::abs(dist) == sizeof(void*) * n);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user