blob: e70451822b4dd1d0040db572fd9c7dc0ee9e397b [file] [log] [blame]
Andrew Jeffery66c77232024-04-24 11:42:02 +09301/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2#ifndef PLDM_COMPILER_H
3#define PLDM_COMPILER_H
4
Andrew Jeffery860a43d2024-08-23 01:21:58 +00005#ifndef __has_attribute
6#error The libpldm implementation requires __has_attribute
7#endif
8
9#include <assert.h>
10
11static struct {
12 static_assert(__has_attribute(unused),
13 "`unused` attribute is required");
14 int compliance;
15} pldm_required_attributes __attribute__((unused));
16
17#define LIBPLDM_CC_UNUSED __attribute__((unused))
18
Andrew Jeffery66c77232024-04-24 11:42:02 +093019// NOLINTBEGIN(bugprone-macro-parentheses)
20/**
21 * Require that the given object is of the specified type.
22 *
23 * If the object is not of the required type then a diagnostic will be emitted.
24 *
25 * If you are reading this documentation due to hitting a compilation error
26 * passing through the macro, then you have a type error in your code that must
27 * be fixed. Despite the compiler output, the error is _not_ that some array
28 * is negatively sized, the array is negatively sized _because_ you have a type
29 * error.
30 *
31 * How this works:
32 *
33 * If the type of @p obj is not equivalent to the provided type @p type then
34 * we force the compiler to evaluate sizeof on a negatively-sized array. The
35 * C standard requires that the integer constant expression that specifies
36 * the array length must be greater than zero. Failure to meet this constraint
37 * generally terminates compilation of the translation unit as any other result
38 * cannot be handled in a sensible way. The array size is derived to an integer
39 * constant expression from a type eqivalence evaluated using _Generic()
40 * allowing us to stay within the language standard. The default generic
41 * association, representing a type mismatch, yields -1.
42 *
43 * pldm_require_obj_type() was introduced into the libpldm implementation to
44 * enable use of the pldm_msgbuf_extract*() APIs for objects that may or may not
45 * reside in a packed struct. See src/msgbuf.h for more details.
46 *
47 * @param obj The name of the object to evaluate
48 * @param type The required type of @p obj
49 *
50 * @return The expression either yields 1, or compilation is terminated
51 */
52#define pldm_require_obj_type(obj, type) \
53 ((void)(sizeof( \
54 struct { char buf[_Generic((obj), type: 1, default: -1)]; })))
55// NOLINTEND(bugprone-macro-parentheses)
56
57#endif