gdb: fix vfork with multiple threads
[deliverable/binutils-gdb.git] / gdbsupport / valid-expr.h
CommitLineData
9c541725
PA
1/* Compile-time valid expression checker for GDB, the GNU debugger.
2
3666a048 3 Copyright (C) 2017-2021 Free Software Foundation, Inc.
9c541725
PA
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/* Helper macros used to build compile-time unit tests that make sure
21 that invalid expressions that should not compile would not compile,
22 and that expressions that should compile do compile, and have the
23 right type. This is mainly used to verify that some utility's API
24 is really as safe as intended. */
25
26#ifndef COMMON_VALID_EXPR_H
27#define COMMON_VALID_EXPR_H
28
268a13a5
TT
29#include "gdbsupport/preprocessor.h"
30#include "gdbsupport/traits.h"
9c541725
PA
31
32/* Macro that uses SFINAE magic to detect whether the EXPR expression
33 is either valid or ill-formed, at compile time, without actually
34 producing compile-time errors. I.e., check that bad uses of the
35 types (e.g., involving mismatching types) would be caught at
36 compile time. If the expression is valid, also check whether the
37 expression has the right type.
38
39 EXPR must be defined in terms of some of the template parameters,
40 so that template substitution failure discards the overload instead
41 of causing a real compile error. TYPES is thus the list of types
42 involved in the expression, and TYPENAMES is the same list, but
43 with each element prefixed by "typename". These are passed as
44 template parameter types to the templates within the macro.
45
46 VALID is a boolean that indicates whether the expression is
47 supposed to be valid or invalid.
48
49 EXPR_TYPE is the expected type of EXPR. Only meaningful iff VALID
50 is true. If VALID is false, then you must pass "void" as expected
51 type.
52
53 Each invocation of the macro is wrapped in its own namespace to
54 avoid ODR violations. The generated namespace only includes the
55 line number, so client code should wrap sets of calls in a
56 test-specific namespace too, to fully guarantee uniqueness between
57 the multiple clients in the codebase. */
58#define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \
59 namespace CONCAT (check_valid_expr, __LINE__) { \
60 \
de38d64a
PA
61 template <TYPENAMES, typename = decltype (EXPR)> \
62 struct archetype \
63 { \
64 }; \
9c541725 65 \
de38d64a 66 static_assert (gdb::is_detected_exact<archetype<TYPES, EXPR_TYPE>, \
1945192c 67 archetype, TYPES>::value == VALID, \
9c541725 68 ""); \
9c541725
PA
69 } /* namespace */
70
71/* A few convenience macros that support expressions involving a
72 varying numbers of types. If you need more types, feel free to add
73 another variant. */
74
75#define CHECK_VALID_EXPR_1(T1, VALID, EXPR_TYPE, EXPR) \
cf08fb29
PA
76 CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1), \
77 ESC_PARENS (T1), \
9c541725
PA
78 VALID, EXPR_TYPE, EXPR)
79
80#define CHECK_VALID_EXPR_2(T1, T2, VALID, EXPR_TYPE, EXPR) \
cf08fb29
PA
81 CHECK_VALID_EXPR_INT (ESC_PARENS(typename T1, typename T2), \
82 ESC_PARENS (T1, T2), \
9c541725
PA
83 VALID, EXPR_TYPE, EXPR)
84
85#define CHECK_VALID_EXPR_3(T1, T2, T3, VALID, EXPR_TYPE, EXPR) \
cf08fb29
PA
86 CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, typename T3), \
87 ESC_PARENS (T1, T2, T3), \
9c541725
PA
88 VALID, EXPR_TYPE, EXPR)
89
90#define CHECK_VALID_EXPR_4(T1, T2, T3, T4, VALID, EXPR_TYPE, EXPR) \
cf08fb29
PA
91 CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \
92 typename T3, typename T4), \
93 ESC_PARENS (T1, T2, T3, T4), \
9c541725
PA
94 VALID, EXPR_TYPE, EXPR)
95
04902b09
PA
96#define CHECK_VALID_EXPR_5(T1, T2, T3, T4, T5, VALID, EXPR_TYPE, EXPR) \
97 CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \
98 typename T3, typename T4, \
99 typename T5), \
100 ESC_PARENS (T1, T2, T3, T4, T5), \
101 VALID, EXPR_TYPE, EXPR)
102
103#define CHECK_VALID_EXPR_6(T1, T2, T3, T4, T5, T6, \
104 VALID, EXPR_TYPE, EXPR) \
105 CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \
106 typename T3, typename T4, \
107 typename T5, typename T6), \
108 ESC_PARENS (T1, T2, T3, T4, T5, T6), \
109 VALID, EXPR_TYPE, EXPR)
110
9c541725 111#endif /* COMMON_VALID_EXPR_H */
This page took 0.311736 seconds and 4 git commands to generate.