[PATCH] score: Avoid cyclic header file dependencies

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Apr 24 13:00:33 UTC 2023


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



More information about the devel mailing list