oveRTOS C API
Embedded RTOS framework — build system, configuration, and portable C API
Loading...
Searching...
No Matches
heap_assert.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 *
6 * This file is part of oveRTOS.
7 */
8
34#ifndef OVE_HEAP_ASSERT_H
35#define OVE_HEAP_ASSERT_H
36
37#include "ove_config.h"
38
39/* bindgen (libclang) rejects the `__attribute__((error(...)))`
40 * redeclarations below as "attribute does not appear on the first
41 * declaration" against the libc decls. GCC accepts that pattern; the
42 * Rust crate's build.rs passes -D__BINDGEN__, so skip the redecls there
43 * — bindgen never emits libc allocator symbols anyway.
44 *
45 * Emscripten/clang has the same strict behaviour as bindgen's libclang:
46 * the `error` attribute can only appear on the first declaration of a
47 * function, not a redeclaration. Skip the trap there too — the WASM
48 * sim build doesn't have a kernel heap to protect anyway, and the
49 * runtime trap in ove_heap_lock.c remains in place for any backend
50 * that does.
51 *
52 * Cross-compile clang-tidy (config/ove-cli/ove/lint.py:_clang_tidy_backends)
53 * shares clang's strictness: it parses with --target=arm-none-eabi and
54 * trips on the same redeclaration pattern. The lint script defines
55 * `__OVE_LINT__` so we can opt out — lint never produces a binary, so
56 * the compile-time guard isn't doing anything useful in that pass. */
57#if defined(CONFIG_OVE_ZERO_HEAP) && !defined(__BINDGEN__) && !defined(__ZIG_CIMPORT__) && \
58 !defined(__EMSCRIPTEN__) && !defined(__OVE_LINT__)
59
60#include <stddef.h>
61
62#define _OVE_HEAP_FORBIDDEN(name) \
63 __attribute__((error("oveRTOS zero-heap mode forbids libc " name "(); use " \
64 "OVE_*_DEFINE_STATIC / ove_*_init() with caller-supplied " \
65 "storage, or build with CONFIG_OVE_ZERO_HEAP=n if dynamic " \
66 "allocation is required.")))
67
68/* C++ libc declarations carry `noexcept`; redeclaring without it is
69 * a hard error. C has no exception specifiers, so the macro expands
70 * to nothing there. */
71#ifdef __cplusplus
72#define _OVE_HEAP_NOTHROW noexcept
73#else
74#define _OVE_HEAP_NOTHROW
75#endif
76
77/*
78 * Redeclare libc allocators with the `error` attribute. GCC + Clang
79 * accept redeclarations that add attributes; any subsequent call site
80 * that sees this declaration fails compilation with the message
81 * above.
82 */
83#ifdef __cplusplus
84extern "C" {
85#endif
86
87extern void *malloc(size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("malloc");
88extern void *calloc(size_t, size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("calloc");
89extern void *realloc(void *, size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("realloc");
90extern void *zalloc(size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("zalloc");
91extern void *memalign(size_t, size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("memalign");
92extern void *aligned_alloc(size_t, size_t) _OVE_HEAP_NOTHROW _OVE_HEAP_FORBIDDEN("aligned_alloc");
93
94#ifdef __cplusplus
95}
96#endif
97
98#undef _OVE_HEAP_NOTHROW
99#undef _OVE_HEAP_FORBIDDEN
100
101#endif /* CONFIG_OVE_ZERO_HEAP */
102
103#endif /* OVE_HEAP_ASSERT_H */