BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_annotation.h
Go to the documentation of this file.
1
/// @file bsls_annotation.h
2
///
3
/// The content of this file has been pre-processed for Doxygen.
4
///
5
6
7
// bsls_annotation.h -*-C++-*-
8
#ifndef INCLUDED_BSLS_ANNOTATION
9
#define INCLUDED_BSLS_ANNOTATION
10
11
#include <
bsls_ident.h
>
12
BSLS_IDENT
(
"$Id: $"
)
13
14
/// @defgroup bsls_annotation bsls_annotation
15
/// @brief Provide support for compiler annotations for compile-time safety.
16
/// @addtogroup bsl
17
/// @{
18
/// @addtogroup bsls
19
/// @{
20
/// @addtogroup bsls_annotation
21
/// @{
22
///
23
/// <h1> Outline </h1>
24
/// * <a href="#bsls_annotation-purpose"> Purpose</a>
25
/// * <a href="#bsls_annotation-classes"> Classes </a>
26
/// * <a href="#bsls_annotation-macros"> Macros </a>
27
/// * <a href="#bsls_annotation-description"> Description </a>
28
/// * <a href="#bsls_annotation-function-annotations"> Function Annotations </a>
29
/// * <a href="#bsls_annotation-function-variable-and-type-annotations"> Function, Variable, and Type Annotations </a>
30
/// * <a href="#bsls_annotation-usage"> Usage </a>
31
///
32
/// # Purpose {#bsls_annotation-purpose}
33
/// Provide support for compiler annotations for compile-time safety.
34
///
35
/// # Classes {#bsls_annotation-classes}
36
///
37
///
38
/// # Macros {#bsls_annotation-macros}
39
///
40
/// - BSLS_ANNOTATION_ALLOC_SIZE(x): optimize when returning memory
41
/// - BSLS_ANNOTATION_ALLOC_SIZE_MUL(x, y): optimize when returning memory
42
/// - BSLS_ANNOTATION_ANALYZER_NORETURN: analyzers treat function as noreturn
43
/// - BSLS_ANNOTATION_ERROR("msg"): emit error message and fail compilation
44
/// - BSLS_ANNOTATION_WARNING("msg"): emit warning message during compilation
45
/// - BSLS_ANNOTATION_PRINTF(s, n): validate `printf` format and arguments
46
/// - BSLS_ANNOTATION_SCANF(s, n): validate `scanf` format and arguments
47
/// - BSLS_ANNOTATION_FORMAT(n): validate `printf` format in `n`th argument
48
/// - BSLS_ANNOTATION_ARG_NON_NULL(...): warn if listed arguments are NULL
49
/// - BSLS_ANNOTATION_ARGS_NON_NULL: warn if any arguments are NULL
50
/// - BSLS_ANNOTATION_NULL_TERMINATED: warn if last argument is non-NULL
51
/// - BSLS_ANNOTATION_NULL_TERMINATED_AT(x): warn if argument at `x` is non-NULL
52
/// - BSLS_ANNOTATION_WARN_UNUSED_RESULT: warn if annotated function result used
53
/// - BSLS_ANNOTATION_NODISCARD: warn if annotated function result is not used
54
/// - BSLS_ANNOTATION_DEPRECATED: warn if annotated entity is used
55
/// - BSLS_ANNOTATION_USED: emit annotated entity even if not referenced
56
/// - BSLS_ANNOTATION_UNUSED: do not warn if annotated entity is unused
57
/// - BSLS_ANNOTATION_NORETURN: error if function returns normally
58
/// - BSLS_ANNOTATION_FALLTHROUGH: do not warn if case fall through
59
///
60
/// @deprecated See package `bsla`.
61
///
62
/// # Description {#bsls_annotation-description}
63
/// This component provides a suite of preprocessor macros that
64
/// define compiler-specific compile-time annotations. These macros, which
65
/// correspond to various compiler features, can be used to annotate code for
66
/// specific compile-time safety checks.
67
///
68
/// For the most part, these compile-time annotations are supported only when
69
/// the `BSLS_PLATFORM_CMP_GNU` or `BSLS_PLATFORM_CMP_CLANG` preprocessor macro
70
/// is defined. Other compilers may implement a few annotations, but the macros
71
/// should be expected to work only with compilers for which
72
/// `BSLS_PLATFORM_CMP_GNU` or `BSLS_PLATFORM_CMP_CLANG` is defined.
73
///
74
/// ## Function Annotations {#bsls_annotation-function-annotations}
75
///
76
///
77
/// The following macros pertain to function declarations (only):
78
///
79
/// @code
80
/// BSLS_ANNOTATION_ALLOC_SIZE(x)
81
/// BSLS_ANNOTATION_ALLOC_SIZE_MUL(x, y)
82
/// @endcode
83
/// This annotation is used to inform the compiler that the return value of the
84
/// so-annotated function is the address of an allocated block of memory whose
85
/// size (in bytes) is given by one or two of the function parameters. Certain
86
/// compilers use this information to improve the correctness of built-in
87
/// object-size functions (e.g., `__builtin_object_size` with
88
/// `BSLS_PLATFORM_CMP_GNU` or `BSLS_PLATFORM_CMP_CLANG`).
89
///
90
/// The function parameter(s) denoting the size of the block are specified by
91
/// one or two integer arguments supplied to the macro. The allocated size (in
92
/// bytes) is either the value of the single function argument or the product of
93
/// the two arguments. Argument numbering starts at one. For example:
94
/// @code
95
/// void *my_calloc(size_t, size_t) BSLS_ANNOTATION_ALLOC_SIZE_MUL(1, 2);
96
/// void my_realloc(void *, size_t) BSLS_ANNOTATION_ALLOC_SIZE(2);
97
/// @endcode
98
///
99
/// @code
100
/// BSLS_ANNOTATION_ERROR("message")
101
/// BSLS_ANNOTATION_WARNING("message")
102
/// @endcode
103
/// This annotation, when used, will cause a compile-time error (or warning)
104
/// when a call to the so-annotated function is not removed through dead-code
105
/// elimination or other optimizations. While it is possible to leave the
106
/// function undefined, thus incurring a link-time failure, with the use of this
107
/// macro the invalid call will be diagnosed earlier (i.e., at compile time),
108
/// and the diagnostic will include the exact location of the function call.
109
///
110
/// @code
111
/// BSLS_ANNOTATION_PRINTF(stringIndex, firstToCheck)
112
/// BSLS_ANNOTATION_SCANF(stringIndex, firstToCheck)
113
/// @endcode
114
/// These annotations perform additional compile-time checks on so-annotated
115
/// functions that take `printf`-style arguments, which should be type-checked
116
/// against a format string.
117
///
118
/// The `stringIndex` parameter is the one-based index to the `const` format
119
/// string. The `firstToCheck` parameter is the one-based index to the first
120
/// variable argument to type-check against that format string. For example:
121
/// @code
122
/// extern int my_printf(void *obj, const char *format, ...)
123
/// BSLS_ANNOTATION_PRINTF(2, 3);
124
/// @endcode
125
///
126
/// @code
127
/// BSLS_ANNOTATION_FORMAT(stringIndex)
128
/// @endcode
129
/// This annotation specifies that the so-annotated function takes an argument
130
/// parameter that is a valid format string for a `printf`-style function and
131
/// returns a format string that is consistent with that format. This allows
132
/// format strings manipulated by translation functions to be checked against
133
/// arguments. Without this annotation, attempting to manipulate the format
134
/// string via this kind of function might generate warnings about non-literal
135
/// formats. For example:
136
/// @code
137
/// const char *translateFormat(const char *locale, const char *format)
138
/// BSLS_ANNOTATION_FORMAT(2);
139
/// @endcode
140
/// On a conforming compiler, this will validate the "Mike" argument against the
141
/// `format` specification passed to `translateFormat`.
142
/// @code
143
/// printf(translateFormat("FR", "Name: %s"), "Mike");
144
/// @endcode
145
///
146
/// @code
147
/// BSLS_ANNOTATION_ARG_NON_NULL(...)
148
/// BSLS_ANNOTATION_ARGS_NON_NULL
149
/// @endcode
150
/// These annotations are used to tell the compiler that a function argument
151
/// must not be null. If the compiler determines that a null pointer is passed
152
/// to an argument slot marked by this annotation, a warning is issued. If the
153
/// `BSLS_ANNOTATION_ARG_NON_NULL` annotation is used, it expects a variable
154
/// list of argument slots to be specified. An argument slot is a one-based
155
/// index of the argument in the function parameters. The
156
/// `BSLS_ANNOTATION_ARGS_NON_NULL` annotation specifies that all pointer
157
/// arguments must not be null.
158
///
159
/// @code
160
/// BSLS_ANNOTATION_NULL_TERMINATED
161
/// BSLS_ANNOTATION_NULL_TERMINATED_AT(x)
162
/// @endcode
163
/// This annotation ensures that a parameter in a function call is an explicit
164
/// `NULL`. The annotation is valid only on variadic functions. By default,
165
/// the sentinel is located at position 0, the last parameter of the function
166
/// call. If an optional position is specified, the sentinel must be located at
167
/// that index, counting backwards from the end of the argument list.
168
///
169
/// @code
170
/// BSLS_ANNOTATION_NODISCARD
171
/// @endcode
172
/// This annotation causes a warning to be emitted if the caller of a
173
/// so-annotated function does not use its return value. This is useful for
174
/// functions where not checking the result is either a security problem or
175
/// always a bug, such as with the `realloc` function.
176
///
177
/// @code
178
/// BSLS_ANNOTATION_WARN_UNUSED_RESULT
179
/// @endcode
180
/// This deprecated macro is an older name for BSLS_ANNOTATION_NODISCARD.
181
///
182
/// @code
183
/// BSLS_ANNOTATION_NORETURN
184
/// @endcode
185
/// This annotation is used to tell the compiler that a specified function will
186
/// not return in a normal fashion. The function can still exit via other means
187
/// such as throwing an exception or aborting the process.
188
///
189
/// @code
190
/// BSLS_ANNOTATION_ANALYZER_NORETURN
191
/// @endcode
192
/// This annotation is used to tell static analyzers (particularly clang-tidy)
193
/// that they should not consider situations where the specified function
194
/// returns normally. This annotation does not have any impact on actual
195
/// generated code (where `BSLS_ANNOTATION_NORETURN` might) and should be used
196
/// in cases where a function cannot be marked `[[noreturn]]` but should be
197
/// treated as such anyway.
198
///
199
/// @code
200
/// BSLS_ANNOTATION_FALLTHROUGH
201
/// @endcode
202
/// This annotation should be placed as a the statement before a `case` in a
203
/// `switch` statement that is expceted to allow control to fall through instead
204
/// of ending with a `break`, `continue`, or `return`. This will prevent
205
/// compilers from warning about fallthrough.
206
///
207
/// ## Function, Variable, and Type Annotations {#bsls_annotation-function-variable-and-type-annotations}
208
///
209
///
210
/// The following macros pertain to function, variable, and type declarations:
211
/// @code
212
/// BSLS_ANNOTATION_DEPRECATED
213
/// @endcode
214
/// This annotation will, when used, cause a compile-time warning if the
215
/// so-annotated function, variable, or type is used anywhere within the source
216
/// file. This is useful, for example, when identifying functions that are
217
/// expected to be removed in a future version of a library. The warning
218
/// includes the location of the declaration of the deprecated entity to enable
219
/// users to find further information about the deprecation, or what they should
220
/// use instead. For example:
221
/// @code
222
/// int oldFnc() BSLS_ANNOTATION_DEPRECATED;
223
/// int oldFnc();
224
/// int (*fncPtr)() = oldFnc;
225
/// @endcode
226
/// In the above code, the third line results in a compiler warning.
227
///
228
/// @code
229
/// BSLS_ANNOTATION_USED
230
/// @endcode
231
/// This annotation indicates that the so-annotated function, variable, or type
232
/// must be emitted even if it appears that the variable is not referenced.
233
///
234
/// @code
235
/// BSLS_ANNOTATION_UNUSED
236
/// @endcode
237
/// This annotation indicates that the so-annotated function, variable, or type
238
/// is possibly unused and the compiler should not generate a warning for the
239
/// unused identifier.
240
///
241
/// ## Usage {#bsls_annotation-usage}
242
///
243
///
244
/// Function annotations must be specified after the function declaration, prior
245
/// to the terminating semi-colon:
246
/// @code
247
/// void function() BSLS_ANNOTATION_ABC BSLS_ANNOTATION_XYZ;
248
/// @endcode
249
/// Annotations cannot be specified on function definitions, only on
250
/// declarations.
251
///
252
/// Variable annotations must be specified after the variable declaration, prior
253
/// to the terminating semi-colon:
254
/// @code
255
/// int foo BSLS_ANNOTATION_ABC BSLS_ANNOTATION_XYZ;
256
/// @endcode
257
/// @}
258
/** @} */
259
/** @} */
260
261
/** @addtogroup bsl
262
* @{
263
*/
264
/** @addtogroup bsls
265
* @{
266
*/
267
/** @addtogroup bsls_annotation
268
* @{
269
*/
270
271
#include <bsls_compilerfeatures.h>
272
#include <
bsls_deprecate.h
>
273
#include <
bsls_platform.h
>
274
275
#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
276
#define BSLS_ANNOTATION_USED __attribute__((__used__))
277
#else
278
#define BSLS_ANNOTATION_USED
279
#endif
280
281
// Note that we could conceivably migrate this to use '[[maybe_unused]]' when
282
// available, but that has more specific constraints over where it can be
283
// syntactically placed than the older vendor annotations.
284
#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
285
#define BSLS_ANNOTATION_UNUSED __attribute__((__unused__))
286
#else
287
#define BSLS_ANNOTATION_UNUSED
288
#endif
289
290
#if defined(BSLS_PLATFORM_CMP_GNU)
291
// '__error__' and '__warning__' attributes are not supported by clang as
292
// of version 7.0.
293
#define BSLS_ANNOTATION_ERROR(x) __attribute__((__error__(x)))
294
#define BSLS_ANNOTATION_WARNING(x) __attribute__((__warning__(x)))
295
#else
296
#define BSLS_ANNOTATION_ERROR(x)
297
#define BSLS_ANNOTATION_WARNING(x)
298
#endif
299
300
#if (defined(BSLS_PLATFORM_CMP_GNU) && \
301
BSLS_PLATFORM_CMP_VER_MAJOR >= 40300) || \
302
defined(BSLS_PLATFORM_CMP_CLANG)
303
#define BSLS_ANNOTATION_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
304
#define BSLS_ANNOTATION_ALLOC_SIZE_MUL(x, y) \
305
__attribute__((__alloc_size__(x, y)))
306
#else
307
#define BSLS_ANNOTATION_ALLOC_SIZE(x)
308
#define BSLS_ANNOTATION_ALLOC_SIZE_MUL(x, y)
309
#endif
310
311
#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
312
#define BSLS_ANNOTATION_ARG_NON_NULL(...) \
313
__attribute__((__nonnull__(__VA_ARGS__)))
314
#define BSLS_ANNOTATION_ARGS_NON_NULL \
315
__attribute__((__nonnull__))
316
#else
317
#define BSLS_ANNOTATION_ARG_NON_NULL(...)
318
#define BSLS_ANNOTATION_ARGS_NON_NULL
319
#endif
320
321
#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
322
#define BSLS_ANNOTATION_DEPRECATED __attribute__((__deprecated__))
323
#else
324
#define BSLS_ANNOTATION_DEPRECATED
325
#endif
326
327
#if defined(BSLS_PLATFORM_CMP_GNU) || \
328
defined(BSLS_PLATFORM_CMP_CLANG) || \
329
defined(BSLS_PLATFORM_CMP_IBM)
330
#define BSLS_ANNOTATION_FORMAT(arg) __attribute__((format_arg(arg)))
331
#else
332
#define BSLS_ANNOTATION_FORMAT(arg)
333
#endif
334
335
#if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
336
#define BSLS_ANNOTATION_NULL_TERMINATED __attribute__((__sentinel__))
337
#define BSLS_ANNOTATION_NULL_TERMINATED_AT(x) \
338
__attribute__((__sentinel__(x)))
339
#else
340
#define BSLS_ANNOTATION_NULL_TERMINATED
341
#define BSLS_ANNOTATION_NULL_TERMINATED_AT(x)
342
#endif
343
344
#if defined(BSLS_PLATFORM_CMP_GNU) || \
345
defined(BSLS_PLATFORM_CMP_CLANG) || \
346
defined(BSLS_PLATFORM_CMP_HP) || \
347
defined(BSLS_PLATFORM_CMP_IBM)
348
#define BSLS_ANNOTATION_PRINTF(fmt, arg) \
349
__attribute__((format(printf, fmt, arg)))
350
#define BSLS_ANNOTATION_SCANF(fmt, arg) \
351
__attribute__((format(scanf, fmt, arg)))
352
#else
353
#define BSLS_ANNOTATION_PRINTF(fmt, arg)
354
#define BSLS_ANNOTATION_SCANF(fmt, arg)
355
#endif
356
357
#if !BSLS_DEPRECATE_IS_ACTIVE(BDE, 3, 18)
358
#if defined(BSLS_COMPILERFEATURES_SUPPORT_ATTRIBUTE_NODISCARD)
359
#define BSLS_ANNOTATION_WARN_UNUSED_RESULT [[ nodiscard ]]
360
#elif defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
361
#define BSLS_ANNOTATION_WARN_UNUSED_RESULT \
362
__attribute__((warn_unused_result))
363
#else
364
#define BSLS_ANNOTATION_WARN_UNUSED_RESULT
365
#endif
366
#endif
367
368
#if defined(BSLS_COMPILERFEATURES_SUPPORT_ATTRIBUTE_NODISCARD)
369
#define BSLS_ANNOTATION_NODISCARD [[ nodiscard ]]
370
#elif defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
371
#define BSLS_ANNOTATION_NODISCARD __attribute__((warn_unused_result))
372
#else
373
#define BSLS_ANNOTATION_NODISCARD
374
#endif
375
376
#if defined(BSLS_COMPILERFEATURES_SUPPORT_ATTRIBUTE_NORETURN)
377
#define BSLS_ANNOTATION_NORETURN [[ noreturn ]]
378
#elif defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
379
#define BSLS_ANNOTATION_NORETURN __attribute__((noreturn))
380
#elif defined(BSLS_PLATFORM_CMP_MSVC)
381
#define BSLS_ANNOTATION_NORETURN __declspec(noreturn)
382
#else
383
#define BSLS_ANNOTATION_NORETURN
384
#endif
385
386
#if defined(BSLS_PLATFORM_CMP_CLANG)
387
#if __has_feature(attribute_analyzer_noreturn)
388
#define BSLS_ANNOTATION_ANALYZER_NORETURN \
389
__attribute__((analyzer_noreturn))
390
#endif
391
#endif
392
#if !defined(BSLS_ANNOTATION_ANALYZER_NORETURN)
393
#define BSLS_ANNOTATION_ANALYZER_NORETURN
394
#endif
395
396
397
#if defined(BSLS_COMPILERFEATURES_SUPPORT_ATTRIBUTE_FALLTHROUGH)
398
#define BSLS_ANNOTATION_FALLTHROUGH [[ fallthrough ]]
399
#elif defined(BSLS_PLATFORM_CMP_GNU)
400
#if BSLS_PLATFORM_CMP_VERSION >= 70000
401
#define BSLS_ANNOTATION_FALLTHROUGH __attribute__((fallthrough))
402
#endif
403
#elif defined(BSLS_PLATFORM_CMP_CLANG)
404
#if __cplusplus >= 201103L && defined(__has_warning)
405
#if __has_feature(cxx_attributes) && \
406
__has_warning("-Wimplicit-fallthrough")
407
#define BSLS_ANNOTATION_FALLTHROUGH [[clang::fallthrough]]
408
#endif
409
#endif
410
#endif
411
#ifndef BSLS_ANNOTATION_FALLTHROUGH
412
#define BSLS_ANNOTATION_FALLTHROUGH
413
#endif
414
415
#endif
416
417
// ----------------------------------------------------------------------------
418
// Copyright 2013 Bloomberg Finance L.P.
419
//
420
// Licensed under the Apache License, Version 2.0 (the "License");
421
// you may not use this file except in compliance with the License.
422
// You may obtain a copy of the License at
423
//
424
// http://www.apache.org/licenses/LICENSE-2.0
425
//
426
// Unless required by applicable law or agreed to in writing, software
427
// distributed under the License is distributed on an "AS IS" BASIS,
428
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
429
// See the License for the specific language governing permissions and
430
// limitations under the License.
431
// ----------------------------- END-OF-FILE ----------------------------------
432
433
/** @} */
434
/** @} */
435
/** @} */
bsls_deprecate.h
bsls_ident.h
bsls_platform.h
BSLS_IDENT
#define BSLS_IDENT(str)
Definition
bsls_ident.h:195
doxygen_input
bde
groups
bsl
bsls
bsls_annotation.h
Generated by
1.9.8