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>
12BSLS_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/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195