Use gdb_bfd_sections in get_stap_base_address
[deliverable/binutils-gdb.git] / gdb / unittests / enum-flags-selftests.c
CommitLineData
04902b09
PA
1/* Self tests for enum-flags for GDB, the GNU debugger.
2
3 Copyright (C) 2016-2020 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 "gdbsupport/enum-flags.h"
22#include "gdbsupport/valid-expr.h"
23#include "gdbsupport/selftest.h"
24
25namespace selftests {
26namespace enum_flags_tests {
27
28/* The (real) enum types used in CHECK_VALID. Their names match the
29 template parameter names of the templates defined by CHECK_VALID to
30 make it simpler to use. They could be named differently. */
31
32/* A "real enum". */
33enum RE
34 {
35 RE_FLAG1 = 1 << 1,
36 RE_FLAG2 = 1 << 2,
37 };
38
39/* Another "real enum". */
40enum RE2
41 {
42 RE2_FLAG1 = 1 << 1,
43 RE2_FLAG2 = 1 << 2,
44 };
45
46/* An unsigned "real enum". */
47enum URE : unsigned
48 {
49 URE_FLAG1 = 1 << 1,
50 URE_FLAG2 = 1 << 2,
51 URE_FLAG3 = 0xffffffff,
52 };
53
54/* A non-flags enum. */
55enum NF
56 {
57 NF_FLAG1 = 1 << 1,
58 NF_FLAG2 = 1 << 2,
59 };
60
61/* The corresponding "enum flags" types. */
62DEF_ENUM_FLAGS_TYPE (RE, EF);
63DEF_ENUM_FLAGS_TYPE (RE2, EF2);
64DEF_ENUM_FLAGS_TYPE (URE, UEF);
65
66#if HAVE_IS_TRIVIALLY_COPYABLE
67
68/* So that std::vectors of types that have enum_flags fields can
69 reallocate efficiently memcpy. */
70gdb_static_assert (std::is_trivially_copyable<EF>::value);
71
72#endif
73
74/* A couple globals used as lvalues in the CHECK_VALID expressions
75 below. Their names (and types) match the uppercase type names
76 exposed by CHECK_VALID just to make the expressions easier to
77 follow. */
78static RE re ATTRIBUTE_UNUSED;
79static EF ef ATTRIBUTE_UNUSED;
80
81/* First, compile-time tests that:
82
83 - make sure that incorrect operations with mismatching enum types
84 are caught at compile time.
85
86 - make sure that the same operations but involving the right enum
87 types do compile and that they return the correct type.
88*/
89
90#define CHECK_VALID(VALID, EXPR_TYPE, EXPR) \
91 CHECK_VALID_EXPR_6 (EF, RE, EF2, RE2, UEF, URE, VALID, EXPR_TYPE, EXPR)
92
93typedef std::underlying_type<RE>::type und;
94
95/* Test construction / conversion from/to different types. */
96
97/* RE/EF -> underlying (explicit) */
98CHECK_VALID (true, und, und (RE ()))
99CHECK_VALID (true, und, und (EF ()))
100
101/* RE/EF -> int (explicit) */
102CHECK_VALID (true, int, int (RE ()))
103CHECK_VALID (true, int, int (EF ()))
104
105/* other -> RE */
106
107/* You can construct a raw enum value from an int explicitly to punch
108 a hole in the type system if need to. */
109CHECK_VALID (true, RE, RE (1))
110CHECK_VALID (true, RE, RE (RE2 ()))
111CHECK_VALID (false, void, RE (EF2 ()))
112CHECK_VALID (true, RE, RE (RE ()))
113CHECK_VALID (false, void, RE (EF ()))
114
115/* other -> EF. */
116
117/* As expected, enum-flags is a stronger type than the backing raw
118 enum. Unlike with raw enums, you can't construct an enum flags
119 from an integer nor from an unrelated enum type explicitly. Add an
120 intermediate conversion via the raw enum if you really need it. */
121CHECK_VALID (false, void, EF (1))
122CHECK_VALID (false, void, EF (1u))
123CHECK_VALID (false, void, EF (RE2 ()))
124CHECK_VALID (false, void, EF (EF2 ()))
125CHECK_VALID (true, EF, EF (RE ()))
126CHECK_VALID (true, EF, EF (EF ()))
127
128/* Test operators. */
129
130/* operator OP (raw_enum, int) */
131
132CHECK_VALID (false, void, RE () | 1)
133CHECK_VALID (false, void, RE () & 1)
134CHECK_VALID (false, void, RE () ^ 1)
135
136/* operator OP (int, raw_enum) */
137
138CHECK_VALID (false, void, 1 | RE ())
139CHECK_VALID (false, void, 1 & RE ())
140CHECK_VALID (false, void, 1 ^ RE ())
141
142/* operator OP (enum_flags, int) */
143
144CHECK_VALID (false, void, EF () | 1)
145CHECK_VALID (false, void, EF () & 1)
146CHECK_VALID (false, void, EF () ^ 1)
147
148/* operator OP (int, enum_flags) */
149
150CHECK_VALID (false, void, 1 | EF ())
151CHECK_VALID (false, void, 1 & EF ())
152CHECK_VALID (false, void, 1 ^ EF ())
153
154/* operator OP (raw_enum, raw_enum) */
155
156CHECK_VALID (false, void, RE () | RE2 ())
157CHECK_VALID (false, void, RE () & RE2 ())
158CHECK_VALID (false, void, RE () ^ RE2 ())
159CHECK_VALID (true, RE, RE () | RE ())
160CHECK_VALID (true, RE, RE () & RE ())
161CHECK_VALID (true, RE, RE () ^ RE ())
162
163/* operator OP (enum_flags, raw_enum) */
164
165CHECK_VALID (false, void, EF () | RE2 ())
166CHECK_VALID (false, void, EF () & RE2 ())
167CHECK_VALID (false, void, EF () ^ RE2 ())
168CHECK_VALID (true, EF, EF () | RE ())
169CHECK_VALID (true, EF, EF () & RE ())
170CHECK_VALID (true, EF, EF () ^ RE ())
171
172/* operator OP= (raw_enum, raw_enum), rvalue ref on the lhs. */
173
174CHECK_VALID (false, void, RE () |= RE2 ())
175CHECK_VALID (false, void, RE () &= RE2 ())
176CHECK_VALID (false, void, RE () ^= RE2 ())
177CHECK_VALID (false, void, RE () |= RE ())
178CHECK_VALID (false, void, RE () &= RE ())
179CHECK_VALID (false, void, RE () ^= RE ())
180
181/* operator OP= (raw_enum, raw_enum), lvalue ref on the lhs. */
182
183CHECK_VALID (false, void, re |= RE2 ())
184CHECK_VALID (false, void, re &= RE2 ())
185CHECK_VALID (false, void, re ^= RE2 ())
186CHECK_VALID (true, RE&, re |= RE ())
187CHECK_VALID (true, RE&, re &= RE ())
188CHECK_VALID (true, RE&, re ^= RE ())
189
190/* operator OP= (enum_flags, raw_enum), rvalue ref on the lhs. */
191
192CHECK_VALID (false, void, EF () |= RE2 ())
193CHECK_VALID (false, void, EF () &= RE2 ())
194CHECK_VALID (false, void, EF () ^= RE2 ())
195CHECK_VALID (false, void, EF () |= RE ())
196CHECK_VALID (false, void, EF () &= RE ())
197CHECK_VALID (false, void, EF () ^= RE ())
198
199/* operator OP= (enum_flags, raw_enum), lvalue ref on the lhs. */
200
201CHECK_VALID (false, void, ef |= RE2 ())
202CHECK_VALID (false, void, ef &= RE2 ())
203CHECK_VALID (false, void, ef ^= RE2 ())
204CHECK_VALID (true, EF&, ef |= EF ())
205CHECK_VALID (true, EF&, ef &= EF ())
206CHECK_VALID (true, EF&, ef ^= EF ())
207
208/* operator OP= (enum_flags, enum_flags), rvalue ref on the lhs. */
209
210CHECK_VALID (false, void, EF () |= EF2 ())
211CHECK_VALID (false, void, EF () &= EF2 ())
212CHECK_VALID (false, void, EF () ^= EF2 ())
213CHECK_VALID (false, void, EF () |= EF ())
214CHECK_VALID (false, void, EF () &= EF ())
215CHECK_VALID (false, void, EF () ^= EF ())
216
217/* operator OP= (enum_flags, enum_flags), lvalue ref on the lhs. */
218
219CHECK_VALID (false, void, ef |= EF2 ())
220CHECK_VALID (false, void, ef &= EF2 ())
221CHECK_VALID (false, void, ef ^= EF2 ())
222CHECK_VALID (true, EF&, ef |= EF ())
223CHECK_VALID (true, EF&, ef &= EF ())
224CHECK_VALID (true, EF&, ef ^= EF ())
225
226/* operator~ (raw_enum) */
227
228CHECK_VALID (false, void, ~RE ())
229CHECK_VALID (true, URE, ~URE ())
230
231/* operator~ (enum_flags) */
232
233CHECK_VALID (false, void, ~EF ())
234CHECK_VALID (true, UEF, ~UEF ())
235
236/* Check ternary operator. This exercises implicit conversions. */
237
238CHECK_VALID (true, EF, true ? EF () : RE ())
239CHECK_VALID (true, EF, true ? RE () : EF ())
240
241/* These are valid, but it's not a big deal since you won't be able to
242 assign the resulting integer to an enum or an enum_flags without a
243 cast.
244
245 The latter two tests are disabled on older GCCs because they
246 incorrectly fail with gcc 4.8 and 4.9 at least. Running the test
247 outside a SFINAE context shows:
248
249 invalid user-defined conversion from ‘EF’ to ‘RE2’
250
251 They've been confirmed to compile/pass with gcc 5.3, gcc 7.1 and
252 clang 3.7. */
253
254CHECK_VALID (true, int, true ? EF () : EF2 ())
255CHECK_VALID (true, int, true ? EF2 () : EF ())
256#if GCC_VERSION >= 5003 || defined __clang__
257CHECK_VALID (true, int, true ? EF () : RE2 ())
258CHECK_VALID (true, int, true ? RE2 () : EF ())
259#endif
260
261/* Same, but with an unsigned enum. */
262
263typedef unsigned int uns;
264
265CHECK_VALID (true, uns, true ? EF () : UEF ())
266CHECK_VALID (true, uns, true ? UEF () : EF ())
267#if GCC_VERSION >= 5003 || defined __clang__
268CHECK_VALID (true, uns, true ? EF () : URE ())
269CHECK_VALID (true, uns, true ? URE () : EF ())
270#endif
271
272/* Unfortunately this can't work due to the way C++ computes the
273 return type of the ternary conditional operator. int isn't
274 implicitly convertible to the raw enum type, so the type of the
275 expression is int. And then int is not implicitly convertible to
276 enum_flags.
277
278 GCC 4.8 fails to compile this test with:
279 error: operands to ?: have different types ‘enum_flags<RE>’ and ‘int’
280 Confirmed to work with gcc 4.9, 5.3 and clang 3.7.
281*/
282#if GCC_VERSION >= 4009 || defined __clang__
283CHECK_VALID (false, void, true ? EF () : 0)
284CHECK_VALID (false, void, true ? 0 : EF ())
285#endif
286
287/* Check that the ++/--/<</>>/<<=/>>= operators are deleted. */
288
289CHECK_VALID (false, void, RE ()++)
290CHECK_VALID (false, void, ++RE ())
291CHECK_VALID (false, void, --RE ())
292CHECK_VALID (false, void, RE ()--)
293
294CHECK_VALID (false, void, RE () << 1)
295CHECK_VALID (false, void, RE () >> 1)
296CHECK_VALID (false, void, EF () << 1)
297CHECK_VALID (false, void, EF () >> 1)
298
299CHECK_VALID (false, void, RE () <<= 1)
300CHECK_VALID (false, void, RE () >>= 1)
301CHECK_VALID (false, void, EF () <<= 1)
302CHECK_VALID (false, void, EF () >>= 1)
303
304/* Test comparison operators. */
305
306CHECK_VALID (false, void, EF () == EF2 ())
307CHECK_VALID (false, void, EF () == RE2 ())
308CHECK_VALID (false, void, RE () == EF2 ())
309
310CHECK_VALID (true, bool, EF (RE (1)) == EF (RE (1)))
311CHECK_VALID (true, bool, EF (RE (1)) == RE (1))
312CHECK_VALID (true, bool, RE (1) == EF (RE (1)))
313
314CHECK_VALID (false, void, EF () != EF2 ())
315CHECK_VALID (false, void, EF () != RE2 ())
316CHECK_VALID (false, void, RE () != EF2 ())
317
318/* On clang, disable -Wenum-compare due to "error: comparison of two
319 values with different enumeration types [-Werror,-Wenum-compare]".
320 clang doesn't suppress -Wenum-compare in SFINAE contexts. Not a
321 big deal since misuses like these in GDB will be caught by -Werror
322 anyway. This check is here mainly for completeness. */
323#if defined __clang__
324# pragma GCC diagnostic push
325# pragma GCC diagnostic ignored "-Wenum-compare"
326#endif
327CHECK_VALID (true, bool, RE () == RE2 ())
328CHECK_VALID (true, bool, RE () != RE2 ())
329#if defined __clang__
330# pragma GCC diagnostic pop
331#endif
332
333CHECK_VALID (true, bool, EF (RE (1)) != EF (RE (2)))
334CHECK_VALID (true, bool, EF (RE (1)) != RE (2))
335CHECK_VALID (true, bool, RE (1) != EF (RE (2)))
336
337CHECK_VALID (true, bool, EF () == 0)
338
339/* Check we didn't disable/delete comparison between non-flags enums
340 and unrelated types by mistake. */
341CHECK_VALID (true, bool, NF (1) == NF (1))
342CHECK_VALID (true, bool, NF (1) == int (1))
343CHECK_VALID (true, bool, NF (1) == char (1))
344
345/* -------------------------------------------------------------------- */
346
347/* Follows misc tests that exercise the API. Some are compile time,
348 when possible, others are run time. */
349
350enum test_flag
351 {
352 FLAG1 = 1 << 1,
353 FLAG2 = 1 << 2,
354 FLAG3 = 1 << 3,
355 };
356
357enum test_uflag : unsigned
358 {
359 UFLAG1 = 1 << 1,
360 UFLAG2 = 1 << 2,
361 UFLAG3 = 1 << 3,
362 };
363
364DEF_ENUM_FLAGS_TYPE (test_flag, test_flags);
365DEF_ENUM_FLAGS_TYPE (test_uflag, test_uflags);
366
367static void
368self_test ()
369{
370 /* Check that default construction works. */
371 {
372 constexpr test_flags f;
373
374 gdb_static_assert (f == 0);
375 }
376
377 /* Check that assignment from zero works. */
378 {
379 test_flags f (FLAG1);
380
381 SELF_CHECK (f == FLAG1);
382
383 f = 0;
384
385 SELF_CHECK (f == 0);
386 }
387
388 /* Check that construction from zero works. */
389 {
390 constexpr test_flags zero1 = 0;
391 constexpr test_flags zero2 (0);
392 constexpr test_flags zero3 {0};
393 constexpr test_flags zero4 = {0};
394
395 gdb_static_assert (zero1 == 0);
396 gdb_static_assert (zero2 == 0);
397 gdb_static_assert (zero3 == 0);
398 gdb_static_assert (zero4 == 0);
399 }
400
401 /* Check construction from enum value. */
402 {
403 gdb_static_assert (test_flags (FLAG1) == FLAG1);
404 gdb_static_assert (test_flags (FLAG2) != FLAG1);
405 }
406
407 /* Check copy/assignment. */
408 {
409 constexpr test_flags src = FLAG1;
410
411 constexpr test_flags f1 = src;
412 constexpr test_flags f2 (src);
413 constexpr test_flags f3 {src};
414 constexpr test_flags f4 = {src};
415
416 gdb_static_assert (f1 == FLAG1);
417 gdb_static_assert (f2 == FLAG1);
418 gdb_static_assert (f3 == FLAG1);
419 gdb_static_assert (f4 == FLAG1);
420 }
421
422 /* Check moving. */
423 {
424 test_flags src = FLAG1;
425 test_flags dst = 0;
426
427 dst = std::move (src);
428 SELF_CHECK (dst == FLAG1);
429 }
430
431 /* Check construction from an 'or' of multiple bits. For this to
432 work, operator| must be overridden to return an enum type. The
433 builtin version would return int instead and then the conversion
434 to test_flags would fail. */
435 {
436 constexpr test_flags f = FLAG1 | FLAG2;
437 gdb_static_assert (f == (FLAG1 | FLAG2));
438 }
439
440 /* Similarly, check that "FLAG1 | FLAG2" on the rhs of an assignment
441 operator works. */
442 {
443 test_flags f = 0;
444 f |= FLAG1 | FLAG2;
445 SELF_CHECK (f == (FLAG1 | FLAG2));
446
447 f &= FLAG1 | FLAG2;
448 SELF_CHECK (f == (FLAG1 | FLAG2));
449
450 f ^= FLAG1 | FLAG2;
451 SELF_CHECK (f == 0);
452 }
453
454 /* Check explicit conversion to int works. */
455 {
456 constexpr int some_bits (FLAG1 | FLAG2);
457
458 /* And comparison with int works too. */
459 gdb_static_assert (some_bits == (FLAG1 | FLAG2));
460 gdb_static_assert (some_bits == test_flags (FLAG1 | FLAG2));
461 }
462
463 /* Check operator| and operator|=. Particularly interesting is
464 making sure that putting the enum value on the lhs side of the
465 expression works (FLAG | f). */
466 {
467 test_flags f = FLAG1;
468 f |= FLAG2;
469 SELF_CHECK (f == (FLAG1 | FLAG2));
470 }
471 {
472 test_flags f = FLAG1;
473 f = f | FLAG2;
474 SELF_CHECK (f == (FLAG1 | FLAG2));
475 }
476 {
477 test_flags f = FLAG1;
478 f = FLAG2 | f;
479 SELF_CHECK (f == (FLAG1 | FLAG2));
480 }
481
482 /* Check the &/&= operators. */
483 {
484 test_flags f = FLAG1 & FLAG2;
485 SELF_CHECK (f == 0);
486
487 f = FLAG1 | FLAG2;
488 f &= FLAG2;
489 SELF_CHECK (f == FLAG2);
490
491 f = FLAG1 | FLAG2;
492 f = f & FLAG2;
493 SELF_CHECK (f == FLAG2);
494
495 f = FLAG1 | FLAG2;
496 f = FLAG2 & f;
497 SELF_CHECK (f == FLAG2);
498 }
499
500 /* Check the ^/^= operators. */
501 {
502 constexpr test_flags f = FLAG1 ^ FLAG2;
503 gdb_static_assert (f == (FLAG1 ^ FLAG2));
504 }
505
506 {
507 test_flags f = FLAG1 ^ FLAG2;
508 f ^= FLAG3;
509 SELF_CHECK (f == (FLAG1 | FLAG2 | FLAG3));
510 f = f ^ FLAG3;
511 SELF_CHECK (f == (FLAG1 | FLAG2));
512 f = FLAG3 ^ f;
513 SELF_CHECK (f == (FLAG1 | FLAG2 | FLAG3));
514 }
515
516 /* Check operator~. Note this only compiles with unsigned
517 flags. */
518 {
519 constexpr test_uflags f1 = ~UFLAG1;
520 constexpr test_uflags f2 = ~f1;
521 gdb_static_assert (f2 == UFLAG1);
522 }
523
524 /* Check the ternary operator. */
525
526 {
527 /* raw enum, raw enum */
528 constexpr test_flags f1 = true ? FLAG1 : FLAG2;
529 gdb_static_assert (f1 == FLAG1);
530 constexpr test_flags f2 = false ? FLAG1 : FLAG2;
531 gdb_static_assert (f2 == FLAG2);
532 }
533
534 {
535 /* enum flags, raw enum */
536 constexpr test_flags src = FLAG1;
537 constexpr test_flags f1 = true ? src : FLAG2;
538 gdb_static_assert (f1 == FLAG1);
539 constexpr test_flags f2 = false ? src : FLAG2;
540 gdb_static_assert (f2 == FLAG2);
541 }
542
543 {
544 /* enum flags, enum flags */
545 constexpr test_flags src1 = FLAG1;
546 constexpr test_flags src2 = FLAG2;
547 constexpr test_flags f1 = true ? src1 : src2;
548 gdb_static_assert (f1 == src1);
549 constexpr test_flags f2 = false ? src1 : src2;
550 gdb_static_assert (f2 == src2);
551 }
552
553 /* Check that we can use flags in switch expressions (requires
554 unambiguous conversion to integer). Also check that we can use
555 operator| in switch cases, where only constants are allowed.
556 This should work because operator| is constexpr. */
557 {
558 test_flags f = FLAG1 | FLAG2;
559 bool ok = false;
560
561 switch (f)
562 {
563 case FLAG1:
564 break;
565 case FLAG2:
566 break;
567 case FLAG1 | FLAG2:
568 ok = true;
569 break;
570 }
571
572 SELF_CHECK (ok);
573 }
574}
575
576} /* namespace enum_flags_tests */
577} /* namespace selftests */
578
579void _initialize_enum_flags_selftests ();
580
581void
582_initialize_enum_flags_selftests ()
583{
584 selftests::register_test ("enum-flags",
585 selftests::enum_flags_tests::self_test);
586}
This page took 0.065133 seconds and 4 git commands to generate.