1 /* Self tests for offset types for GDB, the GNU debugger.
3 Copyright (C) 2017-2019 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program 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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "common/selftest.h"
22 #include "common/offset-type.h"
23 #include "common/underlying.h"
24 #include "common/valid-expr.h"
27 namespace offset_type
{
29 DEFINE_OFFSET_TYPE (off_A
, unsigned int);
30 DEFINE_OFFSET_TYPE (off_B
, unsigned int);
32 /* First, compile-time tests that:
34 - make sure that incorrect operations with mismatching types are
35 caught at compile time.
37 - make sure that the same operations but involving the right types
38 do compile and that they return the correct type.
41 #define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \
42 CHECK_VALID_EXPR_2 (off_A, off_B, VALID, EXPR_TYPE, EXPR)
47 using undrl
= std::underlying_type
<off_A
>::type
;
49 /* Offset +/- underlying. */
51 CHECK_VALID (true, off_A
, off_A
{} + undrl
{});
52 CHECK_VALID (true, off_A
, off_A
{} - undrl
{});
53 CHECK_VALID (true, off_A
, undrl
{} + off_A
{});
54 CHECK_VALID (true, off_A
, undrl
{} - off_A
{});
56 /* Add offset types. Both same and different. */
58 CHECK_VALID (false, void, off_A
{} + off_A
{});
59 CHECK_VALID (false, void, off_A
{} + off_B
{});
61 /* Subtract offset types. Both same and different. */
63 CHECK_VALID (false, void, off_B
{} - off_A
{});
64 CHECK_VALID (true, undrl
, off_A
{} - off_A
{});
66 /* Add/assign offset types. Both same and different. */
68 CHECK_VALID (false, void, lval_a
+= off_A
{});
69 CHECK_VALID (false, void, lval_a
+= off_B
{});
70 CHECK_VALID (false, void, lval_a
-= off_A
{});
71 CHECK_VALID (false, void, lval_a
-= off_B
{});
73 /* operator OP+= (offset, underlying), lvalue ref on the lhs. */
75 CHECK_VALID (true, off_A
&, lval_a
+= undrl
{});
76 CHECK_VALID (true, off_A
&, lval_a
-= undrl
{});
78 /* operator OP+= (offset, underlying), rvalue ref on the lhs. */
80 CHECK_VALID (false, void, off_A
{} += undrl
{});
81 CHECK_VALID (false, void, off_A
{} -= undrl
{});
83 /* Rel ops, with same type. */
85 CHECK_VALID (true, bool, off_A
{} < off_A
{});
86 CHECK_VALID (true, bool, off_A
{} > off_A
{});
87 CHECK_VALID (true, bool, off_A
{} <= off_A
{});
88 CHECK_VALID (true, bool, off_A
{} >= off_A
{});
90 /* Rel ops, with unrelated offset types. */
92 CHECK_VALID (false, void, off_A
{} < off_B
{});
93 CHECK_VALID (false, void, off_A
{} > off_B
{});
94 CHECK_VALID (false, void, off_A
{} <= off_B
{});
95 CHECK_VALID (false, void, off_A
{} >= off_B
{});
97 /* Rel ops, with unrelated types. */
99 CHECK_VALID (false, void, off_A
{} < undrl
{});
100 CHECK_VALID (false, void, off_A
{} > undrl
{});
101 CHECK_VALID (false, void, off_A
{} <= undrl
{});
102 CHECK_VALID (false, void, off_A
{} >= undrl
{});
107 /* Test op+ and op-. */
109 constexpr off_A a
{};
110 static_assert (to_underlying (a
) == 0, "");
113 constexpr off_A res1
= a
+ 2;
114 static_assert (to_underlying (res1
) == 2, "");
116 constexpr off_A res2
= res1
- 1;
117 static_assert (to_underlying (res2
) == 1, "");
121 constexpr off_A res1
= 2 + a
;
122 static_assert (to_underlying (res1
) == 2, "");
124 constexpr off_A res2
= 3 - res1
;
125 static_assert (to_underlying (res2
) == 1, "");
129 /* Test op+= and op-=. */
134 SELF_CHECK (to_underlying (o
) == 10);
136 SELF_CHECK (to_underlying (o
) == 5);
141 constexpr off_A o1
= (off_A
) 10;
142 constexpr off_A o2
= (off_A
) 20;
144 constexpr unsigned int delta
= o2
- o1
;
146 static_assert (delta
== 10, "");
149 /* Test <, <=, >, >=. */
151 constexpr off_A o1
= (off_A
) 10;
152 constexpr off_A o2
= (off_A
) 20;
154 static_assert (o1
< o2
, "");
155 static_assert (!(o2
< o1
), "");
157 static_assert (o2
> o1
, "");
158 static_assert (!(o1
> o2
), "");
160 static_assert (o1
<= o2
, "");
161 static_assert (!(o2
<= o1
), "");
163 static_assert (o2
>= o1
, "");
164 static_assert (!(o1
>= o2
), "");
166 static_assert (o1
<= o1
, "");
167 static_assert (o1
>= o1
, "");
171 } /* namespace offset_type */
172 } /* namespace selftests */
175 _initialize_offset_type_selftests ()
177 selftests::register_test ("offset_type", selftests::offset_type::run_tests
);