ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
671 stars 273 forks source link

Added support for noreturn mocked function #441

Open informatimago opened 1 year ago

informatimago commented 1 year ago
Hi!

Here's a (somewhat big) patch to support and mock **noreturn** functions.

Functions may be declared as noreturn with various syntaxes (_Noreturn, noreturn, __attribute__((noreturn)), [[noreturn]] etc).
When that's the case, trying to return from them is undefined, and some compilers such as clang will warn or error about these mocked functions.

Therefore, the proposed patches has three parts:
- added to **Unity** a set of macros:  TEST_PROTECT_NORETURN(), TEST_DO_NOT_RETURN(), and TEST_NOT_RETURNING(call) to test for non-returning functions. (cf. https://github.com/ThrowTheSwitch/Unity/pull/674 )
- `cmock_generator.rb` checks for the `function[:noreturn]` flag, and when set, generates calls to the new `TEST_DO_NOT_RETURN()` macro.
- `cmock_header_parser.rb` now perform some level of parsing to analyse the noreturn attributes.

There's a C lexer (`CLexer`) that is used to transform source text into Arrays of Symbols, which are then parsed to get the parenthesis structure correctly (parentheses, brackets, braces and angle brackets for C++ templates).  This "structured" Array of Symbol is the processed to parse the function signature, along with any attribute surrounding it, or in the parameters. (namespaces in C++ [[ ... ]] attributes are supported too).  Most attributes are thrown away, but noreturn attributes are used to set the resulting function[:noreturn] flag used by the generator.

All the old unit and integration tests pass (mostly unchanged, a few results are different, eg. __attribute__ are not removed early, or int const* --> const int* because the text are unparsed from internal representations).

New unit tests for new noreturn code is added, as well as a noreturn.h for integration test (system). I've not found any "test driver" for them so I assumed that the test only processed them automatically,without actually running a mock test (but it would be nice to add one, since we may want to test the TEST_PROTECT_NORETURN() and  TEST_NOT_RETURNING(myexec1("test")) macros.