1// { dg-require-atomic-builtins "" }
2// { dg-options "-std=gnu++11" }
3
4// Copyright (C) 2012-2015 Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 3, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING3.  If not see
19// <http://www.gnu.org/licenses/>.
20
21#include <atomic>
22#include <cstdlib> //std::abs
23#include <testsuite_hooks.h>
24
25// libstdc++/51811
26// pointer arithimetic vs. atomic<_Tp*> specialization
27int main(void)
28{
29  bool test __attribute__((unused)) = true;
30
31  using namespace std;
32
33  typedef int 	value_type;
34  const size_t n = 2;
35  value_type value = 42;
36  atomic<value_type*> p, p2, p3;
37
38  // operator++
39  {
40    p = &value;
41    p2 = p++;
42    VERIFY (p != p2);
43
44    value_type* vp(p);
45    value_type* vp2(p2);
46    ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
47    VERIFY ( std::abs(dist) == sizeof(value_type));
48
49    p = &value;
50    p3 = ++p;
51    VERIFY (p == p3);
52  }
53
54  // operator--
55  {
56    p = &value;
57    p2 = p--;
58    VERIFY (p != p2);
59
60    value_type* vp(p);
61    value_type* vp2(p2);
62    ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
63    VERIFY ( std::abs(dist) == sizeof(value_type));
64
65    p = &value;
66    p3 = --p;
67    VERIFY (p == p3);
68  }
69
70  // operator+=
71  {
72    p = &value;
73    value_type* vp(p);
74    p+=n;
75    value_type* vp2(p);
76    ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
77    VERIFY ( std::abs(dist) == sizeof(value_type) * n);
78  }
79
80  // operator-=
81  {
82    p = &value;
83    value_type* vp(p);
84    p-=n;
85    value_type* vp2(p);
86    ptrdiff_t dist = reinterpret_cast<char*>(vp) - reinterpret_cast<char*>(vp2);
87    VERIFY ( std::abs(dist) == sizeof(value_type) * n);
88  }
89
90  return 0;
91}
92