GDB (xrefs)
offset-type-selftests.c
Go to the documentation of this file.
1 /* Self tests for offset types for GDB, the GNU debugger.
2 
3  Copyright (C) 2017-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
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.
11 
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.
16 
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/>. */
19 
20 #include "defs.h"
21 #include "selftest.h"
22 #include "common/offset-type.h"
23 #include "common/underlying.h"
24 #include "common/valid-expr.h"
25 
26 namespace selftests {
27 namespace offset_type {
28 
29 DEFINE_OFFSET_TYPE (off_A, unsigned int);
30 DEFINE_OFFSET_TYPE (off_B, unsigned int);
31 
32 /* First, compile-time tests that:
33 
34  - make sure that incorrect operations with mismatching types are
35  caught at compile time.
36 
37  - make sure that the same operations but involving the right types
38  do compile and that they return the correct type.
39 */
40 
41 #define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \
42  CHECK_VALID_EXPR_2 (off_A, off_B, VALID, EXPR_TYPE, EXPR)
43 
44 off_A lval_a {};
45 off_B lval_b {};
46 
48 
49 /* Offset +/- underlying. */
50 
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 {});
55 
56 /* Add offset types. Both same and different. */
57 
58 CHECK_VALID (false, void, off_A {} + off_A {});
59 CHECK_VALID (false, void, off_A {} + off_B {});
60 
61 /* Subtract offset types. Both same and different. */
62 
63 CHECK_VALID (false, void, off_B {} - off_A {});
64 CHECK_VALID (true, undrl, off_A {} - off_A {});
65 
66 /* Add/assign offset types. Both same and different. */
67 
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 {});
72 
73 /* operator OP+= (offset, underlying), lvalue ref on the lhs. */
74 
75 CHECK_VALID (true, off_A&, lval_a += undrl {});
76 CHECK_VALID (true, off_A&, lval_a -= undrl {});
77 
78 /* operator OP+= (offset, underlying), rvalue ref on the lhs. */
79 
80 CHECK_VALID (false, void, off_A {} += undrl {});
81 CHECK_VALID (false, void, off_A {} -= undrl {});
82 
83 /* Rel ops, with same type. */
84 
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 {});
89 
90 /* Rel ops, with unrelated offset types. */
91 
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 {});
96 
97 /* Rel ops, with unrelated types. */
98 
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 {});
103 
104 static void
106 {
107  /* Test op+ and op-. */
108  {
109  constexpr off_A a {};
110  static_assert (to_underlying (a) == 0, "");
111 
112  {
113  constexpr off_A res1 = a + 2;
114  static_assert (to_underlying (res1) == 2, "");
115 
116  constexpr off_A res2 = res1 - 1;
117  static_assert (to_underlying (res2) == 1, "");
118  }
119 
120  {
121  constexpr off_A res1 = 2 + a;
122  static_assert (to_underlying (res1) == 2, "");
123 
124  constexpr off_A res2 = 3 - res1;
125  static_assert (to_underlying (res2) == 1, "");
126  }
127  }
128 
129  /* Test op+= and op-=. */
130  {
131  off_A o {};
132 
133  o += 10;
134  SELF_CHECK (to_underlying (o) == 10);
135  o -= 5;
136  SELF_CHECK (to_underlying (o) == 5);
137  }
138 
139  /* Test op-. */
140  {
141  constexpr off_A o1 = (off_A) 10;
142  constexpr off_A o2 = (off_A) 20;
143 
144  constexpr unsigned int delta = o2 - o1;
145 
146  static_assert (delta == 10, "");
147  }
148 
149  /* Test <, <=, >, >=. */
150  {
151  constexpr off_A o1 = (off_A) 10;
152  constexpr off_A o2 = (off_A) 20;
153 
154  static_assert (o1 < o2, "");
155  static_assert (!(o2 < o1), "");
156 
157  static_assert (o2 > o1, "");
158  static_assert (!(o1 > o2), "");
159 
160  static_assert (o1 <= o2, "");
161  static_assert (!(o2 <= o1), "");
162 
163  static_assert (o2 >= o1, "");
164  static_assert (!(o1 >= o2), "");
165 
166  static_assert (o1 <= o1, "");
167  static_assert (o1 >= o1, "");
168  }
169 }
170 
171 } /* namespace offset_type */
172 } /* namespace selftests */
173 
174 void
176 {
178 }
CHECK_VALID(true, off_A, off_A {}+undrl {})
void _initialize_offset_type_selftests()
constexpr std::underlying_type< E >::type to_underlying(E val) noexcept
Definition: underlying.h:27
uint32_t offset_type
Definition: dwarf2read.c:164
static const char * type
Definition: language.c:113
std::underlying_type< off_A >::type undrl
void register_test(const std::string &name, selftest *test)
Definition: selftest.c:52
DEFINE_OFFSET_TYPE(off_A, unsigned int)
#define SELF_CHECK(VALUE)
Definition: selftest.h:67