There was a cyclic dependency: For RTEMS_STATIC_ANALYSIS we needed basedefs.h in assert.h. For RTEMS_UNREACHABLE() we needed _Assert() from assert.h in basedefs.h.
Fix this by introducing _Debug_Unreachable() in basedefs.h. Add RTEMS_FUNCTION_NAME to basedefs.h and use it in basedefs.h and assert.h. Close #4900. --- cpukit/include/rtems/score/assert.h | 17 +-- cpukit/include/rtems/score/basedefs.h | 109 +++++++++++-------- cpukit/score/src/debugunreachable.c | 49 +++++++++ spec/build/cpukit/librtemscpu.yml | 1 + testsuites/validation/tc-basedefs-no-debug.c | 20 ++-- 5 files changed, 129 insertions(+), 67 deletions(-) create mode 100644 cpukit/score/src/debugunreachable.c diff --git a/cpukit/include/rtems/score/assert.h b/cpukit/include/rtems/score/assert.h index 9eeccacf76..cff4801036 100644 --- a/cpukit/include/rtems/score/assert.h +++ b/cpukit/include/rtems/score/assert.h @@ -71,22 +71,7 @@ extern "C" { * @note This is based on the code in newlib's assert.h. */ #ifndef __RTEMS_ASSERT_FUNCTION - /* Use g++'s demangled names in C++. */ - #if defined __cplusplus && defined __GNUC__ - #define __RTEMS_ASSERT_FUNCTION __PRETTY_FUNCTION__ - - /* C99 requires the use of __func__. */ - #elif __STDC_VERSION__ >= 199901L - #define __RTEMS_ASSERT_FUNCTION __func__ - - /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ - #elif __GNUC__ >= 2 - #define __RTEMS_ASSERT_FUNCTION __FUNCTION__ - - /* failed to detect __func__ support. */ - #else - #define __RTEMS_ASSERT_FUNCTION ((char *) 0) - #endif + #define __RTEMS_ASSERT_FUNCTION RTEMS_FUNCTION_NAME #endif /* !__RTEMS_ASSERT_FUNCTION */ #if !defined( RTEMS_SCHEDSIM ) diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h index c182ea02ec..96b1d65e27 100644 --- a/cpukit/include/rtems/score/basedefs.h +++ b/cpukit/include/rtems/score/basedefs.h @@ -12,7 +12,7 @@ /* * Copyright (C) 2014 Paval Pisa * Copyright (C) 2011, 2013 On-Line Applications Research Corporation (OAR) - * Copyright (C) 2009, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2009, 2023 embedded brains GmbH (http://www.embedded-brains.de) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -355,6 +355,47 @@ extern "C" { */ #define RTEMS_EXPAND( _token ) _token +/* Generated from spec:/rtems/basedefs/if/function-name */ + +/** + * @ingroup RTEMSAPIBaseDefs + * + * @brief Expands to the name of the function containing the use of this + * define. + */ +#if defined(__cplusplus) && defined(__GNUC__) + #define RTEMS_FUNCTION_NAME __PRETTY_FUNCTION__ +#else + #define RTEMS_FUNCTION_NAME __func__ +#endif + +/* Generated from spec:/rtems/basedefs/if/no-return */ + +/** + * @ingroup RTEMSAPIBaseDefs + * + * @brief Tells the compiler in a function declaration that this function does + * not return. + */ +#if __cplusplus >= 201103L + #define RTEMS_NO_RETURN [[noreturn]] +#elif __STDC_VERSION__ >= 201112L + #define RTEMS_NO_RETURN _Noreturn +#elif defined(__GNUC__) + #define RTEMS_NO_RETURN __attribute__(( __noreturn__ )) +#else + #define RTEMS_NO_RETURN +#endif + +/* Generated from spec:/rtems/basedefs/if/compiler-no-return-attribute */ + +/** + * @ingroup RTEMSAPIBaseDefs + * + * @brief Provided for backward compatibility. + */ +#define RTEMS_COMPILER_NO_RETURN_ATTRIBUTE RTEMS_NO_RETURN + /* Generated from spec:/rtems/basedefs/if/section */ /** @@ -425,17 +466,25 @@ extern "C" { */ #define RTEMS_XCONCAT( _x, _y ) RTEMS_CONCAT( _x, _y ) -/* Generated from spec:/score/basedefs/if/assert-unreachable */ +#if !defined(ASM) && defined(RTEMS_DEBUG) + /* Generated from spec:/score/basedefs/if/debug-unreachable */ -/** - * @ingroup RTEMSScore - * - * @brief Asserts that this program point is unreachable. - */ -#if defined(RTEMS_DEBUG) - #define _Assert_Unreachable() _Assert( 0 ) -#else - #define _Assert_Unreachable() do { } while ( 0 ) + /** + * @ingroup RTEMSScore + * + * @brief Terminates the program with a failed assertion. + * + * @param file is the file name. + * + * @param line is the line of the file. + * + * @param func is the function name. + */ + RTEMS_NO_RETURN void _Debug_Unreachable( + const char *file, + int line, + const char *func + ); #endif #if !defined(ASM) @@ -614,33 +663,6 @@ extern "C" { #define RTEMS_NO_INLINE #endif -/* Generated from spec:/rtems/basedefs/if/no-return */ - -/** - * @ingroup RTEMSAPIBaseDefs - * - * @brief Tells the compiler in a function declaration that this function does - * not return. - */ -#if __cplusplus >= 201103L - #define RTEMS_NO_RETURN [[noreturn]] -#elif __STDC_VERSION__ >= 201112L - #define RTEMS_NO_RETURN _Noreturn -#elif defined(__GNUC__) - #define RTEMS_NO_RETURN __attribute__(( __noreturn__ )) -#else - #define RTEMS_NO_RETURN -#endif - -/* Generated from spec:/rtems/basedefs/if/compiler-no-return-attribute */ - -/** - * @ingroup RTEMSAPIBaseDefs - * - * @brief Provided for backward compatibility. - */ -#define RTEMS_COMPILER_NO_RETURN_ATTRIBUTE RTEMS_NO_RETURN - /* Generated from spec:/rtems/basedefs/if/noinit */ /** @@ -858,14 +880,13 @@ extern "C" { * * @brief Tells the compiler that this program point is unreachable. */ -#if defined(__GNUC__) +#if defined(RTEMS_DEBUG) #define RTEMS_UNREACHABLE() \ - do { \ - __builtin_unreachable(); \ - _Assert_Unreachable(); \ - } while ( 0 ) + _Debug_Unreachable( __FILE__, __LINE__, RTEMS_FUNCTION_NAME ) +#elif defined(__GNUC__) + #define RTEMS_UNREACHABLE() __builtin_unreachable() #else - #define RTEMS_UNREACHABLE() _Assert_Unreachable() + #define RTEMS_UNREACHABLE() do { } while ( 0 ) #endif /* Generated from spec:/rtems/basedefs/if/unused */ diff --git a/cpukit/score/src/debugunreachable.c b/cpukit/score/src/debugunreachable.c new file mode 100644 index 0000000000..f6c2bf67ca --- /dev/null +++ b/cpukit/score/src/debugunreachable.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSScore + * + * @brief This source file contains the implementation of _Debug_Unreachable(). + */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/score/basedefs.h> + +#include <assert.h> + +#if defined(RTEMS_DEBUG) +void _Debug_Unreachable( const char *file, int line, const char *func ) +{ + __assert_func( file, line, func, "reached unreachable code" ); +} +#endif diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 2c969aa5f6..e80be5ebf0 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1409,6 +1409,7 @@ source: - cpukit/score/src/coretodhookunregister.c - cpukit/score/src/coretodset.c - cpukit/score/src/debugisthreaddispatchingallowed.c +- cpukit/score/src/debugunreachable.c - cpukit/score/src/freechain.c - cpukit/score/src/futex.c - cpukit/score/src/gcovdumpinfobase64.c diff --git a/testsuites/validation/tc-basedefs-no-debug.c b/testsuites/validation/tc-basedefs-no-debug.c index 2566107730..479f563cdb 100644 --- a/testsuites/validation/tc-basedefs-no-debug.c +++ b/testsuites/validation/tc-basedefs-no-debug.c @@ -72,9 +72,9 @@ * * - Check that the string is equal to the expected statement. * - * - Expand and stringify _Assert_Unreachable(). + * - Expand RTEMS_FUNCTION_NAME. * - * - Check that the string is equal to the expected statement. + * - Check that the string is equal to the expected function name. * * @{ */ @@ -95,24 +95,30 @@ static void RtemsBasedefsValBasedefsNoDebug_Action_0( void ) 0, IsEqualIgnoreWhiteSpace( s, - "do{__builtin_unreachable();do{}while(0);}while(0)" + "__builtin_unreachable()" ) ); } /** - * @brief Expand and stringify _Assert_Unreachable(). + * @brief Expand RTEMS_FUNCTION_NAME. */ static void RtemsBasedefsValBasedefsNoDebug_Action_1( void ) { const char *s; - s = RTEMS_XSTRING( _Assert_Unreachable() ); + s = RTEMS_FUNCTION_NAME; /* - * Check that the string is equal to the expected statement. + * Check that the string is equal to the expected function name. */ - T_step_true( 1, IsEqualIgnoreWhiteSpace( s, "do{}while(0)" ) ); + T_step_true( + 1, + IsEqualIgnoreWhiteSpace( + s, + "RtemsBasedefsValBasedefsNoDebug_Action_1" + ) + ); } /** -- 2.35.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel