[PATCH] score: Avoid cyclic header file dependencies
Chris Johns
chrisj at rtems.org
Mon Apr 24 21:31:45 UTC 2023
Looks good and thanks for sorting this out.
Chris
On 24/4/2023 11:00 pm, Sebastian Huber wrote:
> 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"
> + )
> + );
> }
>
> /**
More information about the devel
mailing list