[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