Cthulhu  0.2.10
Cthulhu compiler collection
analyze.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #pragma once
4 
5 #include <ctu_config.h>
6 
7 #include "core/compiler.h"
8 
13 
18 
19 // work around gcc bug where attributes are reported as available in C11 mode
20 // but are not actually available.
21 #if CT_HAS_ATTRIBUTE(nodiscard) && CT_CPLUSPLUS && !defined(__GNUC__)
22 # define CT_NODISCARD [[nodiscard]]
23 #endif
24 
25 #if defined(_PREFAST_)
26 # include <sal.h>
27 # ifndef CT_NODISCARD
28 # define CT_NODISCARD _Check_return_
29 # endif
30 
31 # define RET_DOMAIN(cmp, it) _Ret_range_(cmp, it)
32 # define RET_NOTNULL _Ret_notnull_
33 # define RET_INSPECT _Must_inspect_result_
34 
35 # define IN_NOTNULL _In_
36 # define IN_STRING _In_z_
37 # define IN_DOMAIN(cmp, it) _In_range_(cmp, it)
38 
39 # define OUT_NOTNULL _Out_
40 
41 # define INOUT_NOTNULL _Inout_
42 
43 # define STA_PRESENT 1
44 
45  // other annotations
46 # define STA_DECL _Use_decl_annotations_
47 
48  // return value annotations
49 # define STA_RET_NEVER _Analysis_noreturn_
50 # define STA_RET_RANGE(lo, hi) _Ret_range_(lo, hi)
51 # define STA_RET_NOTNULL _Ret_notnull_
52 # define STA_RET_STRING _Ret_z_
53 
54  // success/failure annotations
55 # define STA_SUCCESS(expr) _Success_(expr)
56 # define STA_SUCCESS_TYPE(expr) _Return_type_success_(expr)
57 # define STA_LAST_ERROR _Post_equals_last_error_
58 
59  // struct annotations
60 # define STA_FIELD_SIZE(of) _Field_size_(of)
61 # define STA_FIELD_STRING _Field_z_
62 # define STA_FIELD_RANGE(lo, hi) _Field_range_(lo, hi)
63 
64  // array parameter annotations
65 # define STA_UPDATES(size) _Inout_updates_(size)
66 # define STA_READS(size) _In_reads_(size)
67 # define STA_WRITES(size) _Out_writes_(size)
68 
69  // string parameter annotations
70 # define STA_UPDATES_CSTRING(size) _Inout_updates_z_(size)
71 # define STA_READS_CSTRING(size) _In_reads_z_(size)
72 # define STA_WRITES_CSTRING(size) _Out_writes_z_(size)
73 
74  // format string parameter annotations
75 # define STA_FORMAT_STRING _Printf_format_string_
76 
77  // out parameter annotations
78 # define STA_OUT_OPT _Out_opt_
79 # define STA_OUT_CSTRING _Out_z_
80 # define STA_OUT_RANGE(lo, hi) _Out_range_(lo, hi)
81 # define STA_OUT_INVALID _Post_ptr_invalid_
82 
83  // in parameter annotations
84 # define STA_IN_RANGE(lo, hi) _In_range_(lo, hi)
85 
86  // inout parameter annotations
87 # define STA_INOUT _Inout_
88 # define STA_INOUT_OPT _Inout_opt_
89 # define STA_INOUT_CSTRING _Inout_z_
90 #else
91 # define RET_DOMAIN(cmp, it)
92 # define RET_NOTNULL
93 # define RET_INSPECT
94 
95 # define IN_NOTNULL
96 # define IN_STRING
97 # define IN_DOMAIN(cmp, it)
98 
99 # define OUT_NOTNULL
100 
101 # define INOUT_NOTNULL
102 
103  // other annotations
104 # define STA_DECL
105 
106  // return value annotations
107 # define STA_RET_NEVER
108 # define STA_RET_RANGE(lo, hi)
109 # define STA_RET_NOTNULL
110 # define STA_RET_STRING
111 
112  // success/failure annotations
113 # define STA_SUCCESS(expr)
114 # define STA_SUCCESS_TYPE(expr)
115 # define STA_LAST_ERROR
116 
117  // struct annotations
118 # define STA_FIELD_SIZE(of)
119 # define STA_FIELD_STRING
120 # define STA_FIELD_RANGE(lo, hi)
121 
122  // array parameter annotations
123 # define STA_UPDATES(size)
124 # define STA_READS(size)
125 # define STA_WRITES(size)
126 
127  // string parameter annotations
128 # define STA_UPDATES_CSTRING(size)
129 # define STA_READS_CSTRING(size)
130 # define STA_WRITES_CSTRING(size)
131 
132  // format string parameter annotations
133 # define STA_FORMAT_STRING
134 
135  // out parameter annotations
136 # define STA_OUT_OPT
137 # define STA_OUT_CSTRING
138 # define STA_OUT_RANGE(lo, hi)
139 # define STA_OUT_INVALID
140 
141  // in parameter annotations
142 # define STA_IN_RANGE(lo, hi)
143 
144  // inout parameter annotations
145 # define STA_INOUT
146 # define STA_INOUT_OPT
147 # define STA_INOUT_CSTRING
148 #endif
149 
150 #define CT_NORETURN STA_RET_NEVER CT_NORETURN_IMPL
151 
152 #define STA_RELEASE IN_NOTNULL STA_OUT_INVALID
153 
159 
160 #if __clang_major__ >= 3
161 # define STA_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
162 #elif __GNUC__ >= 4
163 # define STA_PRINTF(a, b) __attribute__((format(printf, a, b)))
164 #else
165 # define STA_PRINTF(a, b)
166 #endif
167 
168 #if __GNUC__ >= 11
169 # define CT_GNU_ATTRIB(...) __attribute__((__VA_ARGS__))
170 # define CT_CLANG_ATTRIB(...)
171 # define CT_ATTRIB(...) __attribute__((__VA_ARGS__))
172 #elif __clang_major__ >= 10
173 # define CT_GNU_ATTRIB(...)
174 # define CT_CLANG_ATTRIB(...) __attribute__((__VA_ARGS__))
175 # define CT_ATTRIB(...) __attribute__((__VA_ARGS__))
176 #else
177 # define CT_ATTRIB(...)
178 # define CT_GNU_ATTRIB(...)
179 # define CT_CLANG_ATTRIB(...)
180 #endif
181 
182 #if defined(_MSC_VER)
183 # define CT_DECLSPEC(...) __declspec(__VA_ARGS__)
184 #else
185 # define CT_DECLSPEC(...)
186 #endif
187 
188 #ifndef IN_NOTNULL
189 # define IN_NOTNULL CT_CLANG_ATTRIB(nonnull)
190 #endif
191 
198 
199 #ifndef CT_NODISCARD
200 # define CT_NODISCARD CT_ATTRIB(warn_unused_result)
201 #endif
202 
215 
216 // TODO: this is a bit of a hack to make tests work properly
217 // both gcc and clang will optimize away calls to pure/const functions
218 // if they can statically prove that the function will cause an assertion.
219 // In our test suite we test assertion cases so we need to have a way to disable
220 // this optimization. This may technically be UB.
221 #if CT_DISABLE_FN_PURITY
222 # define CT_NOALIAS
223 # define CT_CONSTFN
224 # define CT_PUREFN
225 #else
226 # define CT_NOALIAS CT_DECLSPEC(noalias)
227 # define CT_CONSTFN CT_ATTRIB(const)
228 # define CT_PUREFN CT_ATTRIB(pure)
229 #endif
230 
235 
236 // clang doesnt support passing a deallocate function to attribute((malloc))
237 #if defined(__clang__)
238 # define CT_ALLOC(...) __attribute__((malloc))
239 #elif defined(__GNUC__)
240 # define CT_ALLOC(...) __attribute__((malloc(__VA_ARGS__)))
241 #elif defined(_MSC_VER)
242 # define CT_ALLOC(...) __declspec(restrict) __declspec(allocator)
243 #else
244 # define CT_ALLOC(...)
245 #endif
246 
247 #define CT_ALLOC_SIZE(...) CT_ATTRIB(alloc_size(__VA_ARGS__))
248 
249 #if CT_CPLUSPLUS
250 # if defined(_MSC_VER)
251 # define CT_RESTRICT __restrict
252 # elif defined(__clang__)
253 # define CT_RESTRICT __restrict
254 # elif defined(__GNUC__)
255 # define CT_RESTRICT __restrict__
256 # else
257 # define CT_RESTRICT
258 # endif
259 #else
260 # define CT_RESTRICT restrict
261 #endif
262 
267 
268 #define CT_HOTFN CT_ATTRIB(hot)
269 #define CT_COLDFN CT_ATTRIB(cold)
270 
271 #ifndef RET_NOTNULL
272 # define RET_NOTNULL CT_ATTRIB(returns_nonnull)
273 #endif
274 
275 #if !defined(STA_FIELD_SIZE) && CT_HAS_ATTRIBUTE(counted_by)
276 # define STA_FIELD_SIZE(of) __attribute__((counted_by(of)))
277 #endif
278 
279 #ifndef CT_NODISCARD
280 # define CT_NODISCARD
281 #endif
282 
283 #ifdef WITH_DOXYGEN
284 # define CT_NODISCARD 0
285 # define RET_NOTNULL 0
286 # define IN_NOTNULL 0
287 #endif
288 
291 
294 
297 
302 
307 
310 
317 
320 
323 
328 
333 
336 
343 
346 
349 
352