blob: 75b746ad41e68b55418a24a42ff8d0bec77881ea [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 Jeffery3a2c6582024-11-07 16:30:36 +10305#include <libpldm/compiler.h>
6
Andrew Jeffery860a43d2024-08-23 01:21:58 +00007#ifndef __has_attribute
8#error The libpldm implementation requires __has_attribute
9#endif
10
11#include <assert.h>
12
13static struct {
Andrew Jefferycb569bc2024-09-01 09:38:09 +030014 static_assert(__has_attribute(always_inline),
15 "`always_inline` attribute is required");
Andrew Jeffery00d12f82025-09-29 10:40:45 +093016 static_assert(__has_attribute(cleanup),
17 "`cleanup` attribute is required");
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +030018 static_assert(__has_attribute(nonnull),
19 "`nonnull` attribute is required");
Andrew Jeffery860a43d2024-08-23 01:21:58 +000020 static_assert(__has_attribute(unused),
21 "`unused` attribute is required");
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000022 static_assert(__has_attribute(warn_unused_result),
23 "`warn_unused_result` attribute is required");
Amithash Prasade78634b2025-09-26 14:10:13 -070024 static_assert(__has_attribute(weak), "`weak` attribute is required");
Andrew Jeffery860a43d2024-08-23 01:21:58 +000025 int compliance;
26} pldm_required_attributes __attribute__((unused));
27
Andrew Jeffery3a2c6582024-11-07 16:30:36 +103028#ifndef LIBPLDM_CC_ALWAYS_INLINE
29#error Missing definition for LIBPLDM_ALWAYS_INLINE
30#endif
31
32#ifndef LIBPLDM_CC_NONNULL
33#error Missing definition for LIBPLDM_CC_NONNULL
34#endif
35
Andrew Jefferya1896962025-03-03 21:41:25 +103036#define LIBPLDM_CC_CLEANUP(fn) __attribute__((cleanup(fn)))
Andrew Jeffery90bbe6c2024-09-01 13:02:02 +030037#define LIBPLDM_CC_NONNULL_ARGS(...) __attribute__((nonnull(__VA_ARGS__)))
Andrew Jeffery0a1be3c2024-08-11 08:34:10 +000038#define LIBPLDM_CC_UNUSED __attribute__((unused))
39#define LIBPLDM_CC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
Amithash Prasade78634b2025-09-26 14:10:13 -070040#define LIBPLDM_CC_WEAK __attribute__((weak))
Andrew Jeffery860a43d2024-08-23 01:21:58 +000041
Andrew Jeffery66c77232024-04-24 11:42:02 +093042// NOLINTBEGIN(bugprone-macro-parentheses)
43/**
44 * Require that the given object is of the specified type.
45 *
46 * If the object is not of the required type then a diagnostic will be emitted.
47 *
48 * If you are reading this documentation due to hitting a compilation error
49 * passing through the macro, then you have a type error in your code that must
50 * be fixed. Despite the compiler output, the error is _not_ that some array
51 * is negatively sized, the array is negatively sized _because_ you have a type
52 * error.
53 *
54 * How this works:
55 *
56 * If the type of @p obj is not equivalent to the provided type @p type then
57 * we force the compiler to evaluate sizeof on a negatively-sized array. The
58 * C standard requires that the integer constant expression that specifies
59 * the array length must be greater than zero. Failure to meet this constraint
60 * generally terminates compilation of the translation unit as any other result
61 * cannot be handled in a sensible way. The array size is derived to an integer
62 * constant expression from a type eqivalence evaluated using _Generic()
63 * allowing us to stay within the language standard. The default generic
64 * association, representing a type mismatch, yields -1.
65 *
66 * pldm_require_obj_type() was introduced into the libpldm implementation to
67 * enable use of the pldm_msgbuf_extract*() APIs for objects that may or may not
68 * reside in a packed struct. See src/msgbuf.h for more details.
69 *
70 * @param obj The name of the object to evaluate
71 * @param type The required type of @p obj
72 *
73 * @return The expression either yields 1, or compilation is terminated
74 */
75#define pldm_require_obj_type(obj, type) \
76 ((void)(sizeof( \
77 struct { char buf[_Generic((obj), type: 1, default: -1)]; })))
78// NOLINTEND(bugprone-macro-parentheses)
79
80#endif