gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdbsupport / poison.h
CommitLineData
b0b92aeb
PA
1/* Poison symbols at compile time.
2
b811d2c2 3 Copyright (C) 2017-2020 Free Software Foundation, Inc.
b0b92aeb
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#ifndef COMMON_POISON_H
21#define COMMON_POISON_H
22
23#include "traits.h"
284a0e3c 24#include "obstack.h"
b0b92aeb
PA
25
26/* Poison memset of non-POD types. The idea is catching invalid
27 initialization of non-POD structs that is easy to be introduced as
28 side effect of refactoring. For example, say this:
29
30 struct S { VEC(foo_s) *m_data; };
31
32is converted to this at some point:
33
34 struct S {
35 S() { m_data.reserve (10); }
36 std::vector<foo> m_data;
37 };
38
39and old code was initializing S objects like this:
40
41 struct S s;
42 memset (&s, 0, sizeof (S)); // whoops, now wipes vector.
43
44Declaring memset as deleted for non-POD types makes the memset above
45be a compile-time error. */
46
47/* Helper for SFINAE. True if "T *" is memsettable. I.e., if T is
48 either void, or POD. */
49template<typename T>
50struct IsMemsettable
51 : gdb::Or<std::is_void<T>,
52 std::is_pod<T>>
53{};
54
55template <typename T,
56 typename = gdb::Requires<gdb::Not<IsMemsettable<T>>>>
57void *memset (T *s, int c, size_t n) = delete;
58
debed3db
PA
59#if HAVE_IS_TRIVIALLY_COPYABLE
60
b0b92aeb
PA
61/* Similarly, poison memcpy and memmove of non trivially-copyable
62 types, which is undefined. */
63
64/* True if "T *" is relocatable. I.e., copyable with memcpy/memmove.
65 I.e., T is either trivially copyable, or void. */
66template<typename T>
67struct IsRelocatable
68 : gdb::Or<std::is_void<T>,
69 std::is_trivially_copyable<T>>
70{};
71
72/* True if both source and destination are relocatable. */
73
74template <typename D, typename S>
75using BothAreRelocatable
76 = gdb::And<IsRelocatable<D>, IsRelocatable<S>>;
77
78template <typename D, typename S,
79 typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
80void *memcpy (D *dest, const S *src, size_t n) = delete;
81
82template <typename D, typename S,
83 typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>>
84void *memmove (D *dest, const S *src, size_t n) = delete;
85
debed3db
PA
86#endif /* HAVE_IS_TRIVIALLY_COPYABLE */
87
8172f16b
SM
88/* Poison XNEW and friends to catch usages of malloc-style allocations on
89 objects that require new/delete. */
90
91template<typename T>
284a0e3c
SM
92#if HAVE_IS_TRIVIALLY_CONSTRUCTIBLE
93using IsMallocable = std::is_trivially_constructible<T>;
94#else
95using IsMallocable = std::true_type;
96#endif
8172f16b
SM
97
98template<typename T>
99using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>;
100
101template <typename T, typename = gdb::Requires<gdb::Not<IsFreeable<T>>>>
102void free (T *ptr) = delete;
103
104template<typename T>
105static T *
106xnew ()
107{
108 static_assert (IsMallocable<T>::value, "Trying to use XNEW with a non-POD \
109data type. Use operator new instead.");
110 return XNEW (T);
111}
112
113#undef XNEW
114#define XNEW(T) xnew<T>()
115
116template<typename T>
117static T *
118xcnew ()
119{
120 static_assert (IsMallocable<T>::value, "Trying to use XCNEW with a non-POD \
121data type. Use operator new instead.");
122 return XCNEW (T);
123}
124
125#undef XCNEW
126#define XCNEW(T) xcnew<T>()
127
128template<typename T>
129static void
130xdelete (T *p)
131{
132 static_assert (IsFreeable<T>::value, "Trying to use XDELETE with a non-POD \
133data type. Use operator delete instead.");
134 XDELETE (p);
135}
136
137#undef XDELETE
6d83e819 138#define XDELETE(P) xdelete (P)
8172f16b
SM
139
140template<typename T>
141static T *
142xnewvec (size_t n)
143{
144 static_assert (IsMallocable<T>::value, "Trying to use XNEWVEC with a \
145non-POD data type. Use operator new[] (or std::vector) instead.");
146 return XNEWVEC (T, n);
147}
148
149#undef XNEWVEC
150#define XNEWVEC(T, N) xnewvec<T> (N)
151
152template<typename T>
153static T *
154xcnewvec (size_t n)
155{
156 static_assert (IsMallocable<T>::value, "Trying to use XCNEWVEC with a \
157non-POD data type. Use operator new[] (or std::vector) instead.");
158 return XCNEWVEC (T, n);
159}
160
161#undef XCNEWVEC
162#define XCNEWVEC(T, N) xcnewvec<T> (N)
163
164template<typename T>
165static T *
166xresizevec (T *p, size_t n)
167{
168 static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVEC with a \
169non-POD data type.");
170 return XRESIZEVEC (T, p, n);
171}
172
173#undef XRESIZEVEC
174#define XRESIZEVEC(T, P, N) xresizevec<T> (P, N)
175
176template<typename T>
177static void
178xdeletevec (T *p)
179{
180 static_assert (IsFreeable<T>::value, "Trying to use XDELETEVEC with a \
181non-POD data type. Use operator delete[] (or std::vector) instead.");
182 XDELETEVEC (p);
183}
184
185#undef XDELETEVEC
186#define XDELETEVEC(P) xdeletevec (P)
187
188template<typename T>
189static T *
190xnewvar (size_t s)
191{
192 static_assert (IsMallocable<T>::value, "Trying to use XNEWVAR with a \
193non-POD data type.");
194 return XNEWVAR (T, s);;
195}
196
197#undef XNEWVAR
198#define XNEWVAR(T, S) xnewvar<T> (S)
199
200template<typename T>
201static T *
202xcnewvar (size_t s)
203{
204 static_assert (IsMallocable<T>::value, "Trying to use XCNEWVAR with a \
205non-POD data type.");
206 return XCNEWVAR (T, s);
207}
208
209#undef XCNEWVAR
210#define XCNEWVAR(T, S) xcnewvar<T> (S)
211
212template<typename T>
213static T *
214xresizevar (T *p, size_t s)
215{
216 static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVAR with a \
217non-POD data type.");
218 return XRESIZEVAR (T, p, s);
219}
220
221#undef XRESIZEVAR
222#define XRESIZEVAR(T, P, S) xresizevar<T> (P, S)
223
284a0e3c
SM
224template<typename T>
225static T *
226xobnew (obstack *ob)
227{
228 static_assert (IsMallocable<T>::value, "Trying to use XOBNEW with a \
229non-POD data type.");
230 return XOBNEW (ob, T);
231}
232
233#undef XOBNEW
234#define XOBNEW(O, T) xobnew<T> (O)
235
236template<typename T>
237static T *
238xobnewvec (obstack *ob, size_t n)
239{
240 static_assert (IsMallocable<T>::value, "Trying to use XOBNEWVEC with a \
241non-POD data type.");
242 return XOBNEWVEC (ob, T, n);
243}
244
245#undef XOBNEWVEC
246#define XOBNEWVEC(O, T, N) xobnewvec<T> (O, N)
247
b0b92aeb 248#endif /* COMMON_POISON_H */
This page took 0.285168 seconds and 4 git commands to generate.