aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJing Yu <jingyu@google.com>2012-07-20 17:27:57 +0000
committerJing Yu <jingyu@google.com>2012-07-20 17:27:57 +0000
commit101655302af1cf686413629f8de98fe8c98f2b56 (patch)
treeb88600c67f63cfe9d53b06f7b7575989c26c1a07
parent118659f5c1e15a7ce535c0cc044119ed3af981db (diff)
2012-07-19 Jing Yu <jingyu@google.com>
Backport r183875 to fix wrong atomic<_Tp*> add_fetch. PR libstdc++/51811, Google ref b/6702865 * include/bits/atomic_0.h (atomic<_Tp*>): Fix offsets. * include/bits/atomic_2.h: Likewise. * testsuite/29_atomics/atomic/operators/51811.cc: New. * testsuite/29_atomics/atomic/operators/pointer_partial_void.cc: New. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6@189724 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog.google-4_69
-rw-r--r--libstdc++-v3/include/bits/atomic_0.h8
-rw-r--r--libstdc++-v3/include/bits/atomic_2.h8
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc90
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/operators/pointer_partial_void.cc71
5 files changed, 178 insertions, 8 deletions
diff --git a/libstdc++-v3/ChangeLog.google-4_6 b/libstdc++-v3/ChangeLog.google-4_6
index 313d3627845..f5e631adaab 100644
--- a/libstdc++-v3/ChangeLog.google-4_6
+++ b/libstdc++-v3/ChangeLog.google-4_6
@@ -1,3 +1,12 @@
+2012-07-20 Jing Yu <jingyu@google.com>
+
+ Backport r183875 to fix wrong atomic<_Tp*> add_fetch.
+ PR libstdc++/51811, Google ref b/6702865
+ * include/bits/atomic_0.h (atomic<_Tp*>): Fix offsets.
+ * include/bits/atomic_2.h: Likewise.
+ * testsuite/29_atomics/atomic/operators/51811.cc: New.
+ * testsuite/29_atomics/atomic/operators/pointer_partial_void.cc: New.
+
2012-04-02 Jeffrey Yasskin <jyasskin@google.com>
Simple fix for PR-52822.
diff --git a/libstdc++-v3/include/bits/atomic_0.h b/libstdc++-v3/include/bits/atomic_0.h
index 84ff779ef05..25c029b08cb 100644
--- a/libstdc++-v3/include/bits/atomic_0.h
+++ b/libstdc++-v3/include/bits/atomic_0.h
@@ -620,7 +620,7 @@ namespace __atomic0
__return_pointer_type
fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
{
- void* __v = _ATOMIC_MODIFY_(this, +=, __d, __m);
+ void* __v = _ATOMIC_MODIFY_(this, +=, __d * sizeof(_PTp), __m);
return reinterpret_cast<__return_pointer_type>(__v);
}
@@ -628,14 +628,14 @@ namespace __atomic0
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile
{
- void* __v = _ATOMIC_MODIFY_(this, +=, __d, __m);
+ void* __v = _ATOMIC_MODIFY_(this, +=, __d * sizeof(_PTp), __m);
return reinterpret_cast<__return_pointer_type>(__v);
}
__return_pointer_type
fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
{
- void* __v = _ATOMIC_MODIFY_(this, -=, __d, __m);
+ void* __v = _ATOMIC_MODIFY_(this, -=, __d * sizeof(_PTp), __m);
return reinterpret_cast<__return_pointer_type>(__v);
}
@@ -643,7 +643,7 @@ namespace __atomic0
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile
{
- void* __v = _ATOMIC_MODIFY_(this, -=, __d, __m);
+ void* __v = _ATOMIC_MODIFY_(this, -=, __d * sizeof(_PTp), __m);
return reinterpret_cast<__return_pointer_type>(__v);
}
};
diff --git a/libstdc++-v3/include/bits/atomic_2.h b/libstdc++-v3/include/bits/atomic_2.h
index f95beca55c7..abf070a1c7a 100644
--- a/libstdc++-v3/include/bits/atomic_2.h
+++ b/libstdc++-v3/include/bits/atomic_2.h
@@ -644,21 +644,21 @@ namespace __atomic2
__pointer_type
fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
- { return __sync_fetch_and_add(&_M_p, __d); }
+ { return __sync_fetch_and_add(&_M_p, __d * sizeof(_PTp)); }
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile
- { return __sync_fetch_and_add(&_M_p, __d); }
+ { return __sync_fetch_and_add(&_M_p, __d * sizeof(_PTp)); }
__pointer_type
fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
- { return __sync_fetch_and_sub(&_M_p, __d); }
+ { return __sync_fetch_and_sub(&_M_p, __d * sizeof(_PTp)); }
__pointer_type
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile
- { return __sync_fetch_and_sub(&_M_p, __d); }
+ { return __sync_fetch_and_sub(&_M_p, __d * sizeof(_PTp)); }
};
} // namespace __atomic2
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc b/libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
new file mode 100644
index 00000000000..7c234f2ff02
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/operators/51811.cc
@@ -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;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/operators/pointer_partial_void.cc b/libstdc++-v3/testsuite/29_atomics/atomic/operators/pointer_partial_void.cc
new file mode 100644
index 00000000000..fcc9708da4f
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/operators/pointer_partial_void.cc
@@ -0,0 +1,71 @@
+// { dg-require-atomic-builtins "" }
+// { 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;
+}