1 /* Self tests for offset types for GDB, the GNU debugger.
3 Copyright (C) 2017-2024 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/>. */
20 #include "gdbsupport/selftest.h"
21 #include "gdbsupport/offset-type.h"
22 #include "gdbsupport/underlying.h"
23 #include "gdbsupport/valid-expr.h"
26 namespace offset_type
{
28 DEFINE_OFFSET_TYPE (off_A
, unsigned int);
29 DEFINE_OFFSET_TYPE (off_B
, unsigned int);
31 /* First, compile-time tests that:
33 - make sure that incorrect operations with mismatching types are
34 caught at compile time.
36 - make sure that the same operations but involving the right types
37 do compile and that they return the correct type.
40 #define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \
41 CHECK_VALID_EXPR_2 (off_A, off_B, VALID, EXPR_TYPE, EXPR)
46 using undrl
= std::underlying_type
<off_A
>::type
;
48 /* Offset +/- underlying. */
50 CHECK_VALID (true, off_A
, off_A
{} + undrl
{});
51 CHECK_VALID (true, off_A
, off_A
{} - undrl
{});
52 CHECK_VALID (true, off_A
, undrl
{} + off_A
{});
53 CHECK_VALID (true, off_A
, undrl
{} - off_A
{});
55 /* Add offset types. Both same and different. */
57 CHECK_VALID (false, void, off_A
{} + off_A
{});
58 CHECK_VALID (false, void, off_A
{} + off_B
{});
60 /* Subtract offset types. Both same and different. */
62 CHECK_VALID (false, void, off_B
{} - off_A
{});
63 CHECK_VALID (true, undrl
, off_A
{} - off_A
{});
65 /* Add/assign offset types. Both same and different. */
67 CHECK_VALID (false, void, lval_a
+= off_A
{});
68 CHECK_VALID (false, void, lval_a
+= off_B
{});
69 CHECK_VALID (false, void, lval_a
-= off_A
{});
70 CHECK_VALID (false, void, lval_a
-= off_B
{});
72 /* operator OP+= (offset, underlying), lvalue ref on the lhs. */
74 CHECK_VALID (true, off_A
&, lval_a
+= undrl
{});
75 CHECK_VALID (true, off_A
&, lval_a
-= undrl
{});
77 /* operator OP+= (offset, underlying), rvalue ref on the lhs. */
79 CHECK_VALID (false, void, off_A
{} += undrl
{});
80 CHECK_VALID (false, void, off_A
{} -= undrl
{});
82 /* Rel ops, with same type. */
84 CHECK_VALID (true, bool, off_A
{} < off_A
{});
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
{});
89 /* Rel ops, with unrelated offset types. */
91 CHECK_VALID (false, void, off_A
{} < off_B
{});
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
{});
96 /* Rel ops, with unrelated types. */
98 CHECK_VALID (false, void, off_A
{} < undrl
{});
99 CHECK_VALID (false, void, off_A
{} > undrl
{});
100 CHECK_VALID (false, void, off_A
{} <= undrl
{});
101 CHECK_VALID (false, void, off_A
{} >= undrl
{});
106 /* Test op+ and op-. */
108 constexpr off_A a
{};
109 static_assert (to_underlying (a
) == 0, "");
112 constexpr off_A res1
= a
+ 2;
113 static_assert (to_underlying (res1
) == 2, "");
115 constexpr off_A res2
= res1
- 1;
116 static_assert (to_underlying (res2
) == 1, "");
120 constexpr off_A res1
= 2 + a
;
121 static_assert (to_underlying (res1
) == 2, "");
123 constexpr off_A res2
= 3 - res1
;
124 static_assert (to_underlying (res2
) == 1, "");
128 /* Test op+= and op-=. */
133 SELF_CHECK (to_underlying (o
) == 10);
135 SELF_CHECK (to_underlying (o
) == 5);
140 constexpr off_A o1
= (off_A
) 10;
141 constexpr off_A o2
= (off_A
) 20;
143 constexpr unsigned int delta
= o2
- o1
;
145 static_assert (delta
== 10, "");
148 /* Test <, <=, >, >=. */
150 constexpr off_A o1
= (off_A
) 10;
151 constexpr off_A o2
= (off_A
) 20;
153 static_assert (o1
< o2
, "");
154 static_assert (!(o2
< o1
), "");
156 static_assert (o2
> o1
, "");
157 static_assert (!(o1
> o2
), "");
159 static_assert (o1
<= o2
, "");
160 static_assert (!(o2
<= o1
), "");
162 static_assert (o2
>= o1
, "");
163 static_assert (!(o1
>= o2
), "");
165 static_assert (o1
<= o1
, "");
166 static_assert (o1
>= o1
, "");
170 } /* namespace offset_type */
171 } /* namespace selftests */
173 void _initialize_offset_type_selftests ();
175 _initialize_offset_type_selftests ()
177 selftests::register_test ("offset_type", selftests::offset_type::run_tests
);