GCC Code Coverage Report


Directory: Fw/Types/
File: Assert.hpp
Date: 2026-09-03 21:15:04
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 2 2 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 #ifndef FW_ASSERT_HPP
2 #define FW_ASSERT_HPP
3
4 #include <Fw/FPrimeBasicTypes.hpp>
5
6 // Return only the first argument passed to the macro.
7 #define FW_ASSERT_FIRST_ARG(ARG_0, ...) ARG_0
8 // Return all the arguments of the macro, but the first one
9 #define FW_ASSERT_NO_FIRST_ARG(ARG_0, ...) __VA_ARGS__
10
11 #if FW_ASSERT_LEVEL == FW_NO_ASSERT
12 // Users may override the NO_ASSERT case should they choose
13 #ifndef FW_ASSERT
14 #define FW_ASSERT(...) ((void)(FW_ASSERT_FIRST_ARG(__VA_ARGS__)))
15 #endif
16 #define FILE_NAME_ARG const CHAR*
17 #else // ASSERT is defined
18
19 // Passing the __LINE__ argument at the end of the function ensures that
20 // the FW_ASSERT_NO_FIRST_ARG macro will never have an empty variadic variable
21 #if FW_ASSERT_LEVEL == FW_FILEID_ASSERT && defined ASSERT_FILE_ID
22 #define FILE_NAME_ARG U32
23 #define FW_ASSERT(...) \
24 ((FW_ASSERT_FIRST_ARG(__VA_ARGS__, 0)) \
25 ? ((void)0) \
26 : (Fw::SwAssert(ASSERT_FILE_ID, FW_ASSERT_NO_FIRST_ARG(__VA_ARGS__, __LINE__))))
27 #elif FW_ASSERT_LEVEL == FW_FILEID_ASSERT && !defined ASSERT_FILE_ID
28 #define FILE_NAME_ARG U32
29 #define FW_ASSERT(...) \
30 ((FW_ASSERT_FIRST_ARG(__VA_ARGS__, 0)) \
31 ? ((void)0) \
32 : (Fw::SwAssert(static_cast<U32>(0), FW_ASSERT_NO_FIRST_ARG(__VA_ARGS__, __LINE__))))
33 #elif FW_ASSERT_LEVEL == FW_RELATIVE_PATH_ASSERT && defined ASSERT_RELATIVE_PATH
34 #define FILE_NAME_ARG const CHAR*
35 #define FW_ASSERT(...) \
36 ((FW_ASSERT_FIRST_ARG(__VA_ARGS__, 0)) \
37 ? ((void)0) \
38 : (Fw::SwAssert(ASSERT_RELATIVE_PATH, FW_ASSERT_NO_FIRST_ARG(__VA_ARGS__, __LINE__))))
39 #else
40 #define FILE_NAME_ARG const CHAR*
41 #define FW_ASSERT(...) \
42 ((FW_ASSERT_FIRST_ARG(__VA_ARGS__, 0)) ? ((void)0) \
43 : (Fw::SwAssert(__FILE__, FW_ASSERT_NO_FIRST_ARG(__VA_ARGS__, __LINE__))))
44 #endif
45 #endif // if ASSERT is defined
46
47 // Helper macro asserting that a value fits into a type without overflow. Helpful for checking before static casts
48 #define FW_ASSERT_NO_OVERFLOW(value, T) \
49 FW_ASSERT((value) <= std::numeric_limits<T>::max(), static_cast<FwAssertArgType>(value))
50
51 #if FW_ASSERTIONS_ALWAYS_ABORT
52 #define FW_ASSERT_NORETURN __attribute__((noreturn))
53 #endif
54
55 // F' Assertion functions can technically return even though the intention is for the assertion to terminate the
56 // program. This breaks static analysis depending on assertions, since the analyzer has to assume the assertion will
57 // return. When supported, annotate assertion functions as noreturn when statically analyzing.
58 #ifndef FW_ASSERT_NORETURN
59 #ifndef __has_feature
60 #define __has_feature(x) 0 // Compatibility with non-clang compilers.
61 #endif
62 #if __has_feature(attribute_analyzer_noreturn)
63 #define FW_ASSERT_NORETURN __attribute__((analyzer_noreturn))
64 #else
65 #define FW_ASSERT_NORETURN
66 #endif
67 #endif
68
69 // Define NOINLINE as __attribute__((noinline)) if that attribute is available.
70 // Marking assertion functions as NOINLINE can reduce code size without sacrificing performance
71 // in the common case that the function is not called.
72 #ifndef NOINLINE
73 #ifndef __has_attribute
74 #define __has_attribute(x) 0
75 #endif
76 #if __has_attribute(noinline)
77 #define NOINLINE __attribute__((noinline))
78 #else
79 #define NOINLINE
80 #endif
81 #endif
82
83 namespace Fw {
84 //! Assert with no arguments
85 void SwAssert(FILE_NAME_ARG file, FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
86
87 //! Assert with one argument
88 void SwAssert(FILE_NAME_ARG file, FwAssertArgType arg1, FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
89
90 //! Assert with two arguments
91 void SwAssert(FILE_NAME_ARG file,
92 FwAssertArgType arg1,
93 FwAssertArgType arg2,
94 FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
95
96 //! Assert with three arguments
97 void SwAssert(FILE_NAME_ARG file,
98 FwAssertArgType arg1,
99 FwAssertArgType arg2,
100 FwAssertArgType arg3,
101 FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
102
103 //! Assert with four arguments
104 void SwAssert(FILE_NAME_ARG file,
105 FwAssertArgType arg1,
106 FwAssertArgType arg2,
107 FwAssertArgType arg3,
108 FwAssertArgType arg4,
109 FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
110
111 //! Assert with five arguments
112 void SwAssert(FILE_NAME_ARG file,
113 FwAssertArgType arg1,
114 FwAssertArgType arg2,
115 FwAssertArgType arg3,
116 FwAssertArgType arg4,
117 FwAssertArgType arg5,
118 FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
119
120 //! Assert with six arguments
121 void SwAssert(FILE_NAME_ARG file,
122 FwAssertArgType arg1,
123 FwAssertArgType arg2,
124 FwAssertArgType arg3,
125 FwAssertArgType arg4,
126 FwAssertArgType arg5,
127 FwAssertArgType arg6,
128 FwSizeType lineNo) NOINLINE FW_ASSERT_NORETURN;
129 } // namespace Fw
130
131 // Base class for declaring an assert hook
132 // Each of the base class functions can be overridden
133 // or used by derived classes.
134
135 namespace Fw {
136 // Base class for declaring an assert hook
137 class AssertHook {
138 public:
139 5 AssertHook() : previousHook(nullptr) {}; //!< constructor
140 10 virtual ~AssertHook() {}; //!< destructor
141 // override this function to intercept asserts
142 virtual void reportAssert(FILE_NAME_ARG file,
143 FwSizeType lineNo,
144 FwSizeType numArgs,
145 FwAssertArgType arg1,
146 FwAssertArgType arg2,
147 FwAssertArgType arg3,
148 FwAssertArgType arg4,
149 FwAssertArgType arg5,
150 FwAssertArgType arg6);
151 // default reportAssert() will call this when the message is built
152 // override it to do another kind of print. printf by default
153 virtual void printAssert(const CHAR* msg);
154 // do assert action. By default, calls assert.
155 // Called after reportAssert()
156 virtual void doAssert();
157 // register the hook
158 void registerHook();
159 // deregister the hook
160 void deregisterHook();
161 // get a pointer to the registered hook
162 static AssertHook* getRegisteredHook();
163
164 protected:
165 private:
166 // the currently registered assert hook
167 static AssertHook* s_assertHook;
168 // the previous assert hook
169 AssertHook* previousHook;
170 };
171 } // namespace Fw
172
173 #endif // FW_ASSERT_HPP
174