F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Assert.hpp
Go to the documentation of this file.
1 #ifndef FW_ASSERT_HPP
2 #define FW_ASSERT_HPP
3 
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 {
86 
89 
91 void SwAssert(FILE_NAME_ARG file,
92  FwAssertArgType arg1,
93  FwAssertArgType arg2,
95 
97 void SwAssert(FILE_NAME_ARG file,
98  FwAssertArgType arg1,
99  FwAssertArgType arg2,
100  FwAssertArgType arg3,
102 
104 void SwAssert(FILE_NAME_ARG file,
105  FwAssertArgType arg1,
106  FwAssertArgType arg2,
107  FwAssertArgType arg3,
108  FwAssertArgType arg4,
110 
112 void SwAssert(FILE_NAME_ARG file,
113  FwAssertArgType arg1,
114  FwAssertArgType arg2,
115  FwAssertArgType arg3,
116  FwAssertArgType arg4,
117  FwAssertArgType arg5,
119 
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,
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  AssertHook() : previousHook(nullptr) {};
140  virtual ~AssertHook() {};
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
PlatformSizeType FwSizeType
char CHAR
Definition: BasicTypes.h:59
#define FILE_NAME_ARG
Definition: Assert.hpp:16
static AssertHook * getRegisteredHook()
Definition: Assert.cpp:108
void SwAssert(FILE_NAME_ARG file, FwSizeType lineNo)
Assert with no arguments.
Definition: Assert.cpp:138
void deregisterHook()
Definition: Assert.cpp:104
virtual void doAssert()
Definition: Assert.cpp:93
virtual void reportAssert(FILE_NAME_ARG file, FwSizeType lineNo, FwSizeType numArgs, FwAssertArgType arg1, FwAssertArgType arg2, FwAssertArgType arg3, FwAssertArgType arg4, FwAssertArgType arg5, FwAssertArgType arg6)
destructor
Definition: Assert.cpp:77
virtual ~AssertHook()
constructor
Definition: Assert.hpp:140
void registerHook()
Definition: Assert.cpp:99
virtual void printAssert(const CHAR *msg)
Definition: Assert.cpp:73
#define NOINLINE
Definition: Assert.hpp:79
Implementation of malloc based allocator.
#define FW_ASSERT_NORETURN
Definition: Assert.hpp:65
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.