]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg: Add NORETURN attribute and UNREACHABLE() macro.
authorMarvin H?user <Marvin.Haeuser@outlook.com>
Sun, 19 Jun 2016 01:28:51 +0000 (09:28 +0800)
committerLiming Gao <liming.gao@intel.com>
Wed, 22 Jun 2016 01:37:01 +0000 (09:37 +0800)
The NORETURN attribute informs compilers and analyzers that the flagged
function cannot return. This may improve the quality of the optimizations.

The UNREACHABLE() macro informs compilers and analyzers that its position
cannot be reached, for example eliminating implicit returns.
It is recommended to be used together with the NORETURN attribute to prevent
warnings regarding the function flagged as 'noreturn' returning.

The ANALYZER-prefixed versions have the same effects, but exclude compilers.
They may be used to surpress warnings of static analyzers, such as possible
dereferencing of a NULL pointer when dereferencing it after having checked it
via ASSERT().

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
MdePkg/Include/Base.h

index 89b2aed07229f4d6eaab8d916bf71c856aa468b1..cbd9e552d0464653354b8a5a7db5735d7a0c7675 100644 (file)
@@ -84,6 +84,116 @@ VERIFY_SIZE_OF (CHAR16, 2);
   #define GLOBAL_REMOVE_IF_UNREFERENCED\r
 #endif\r
 \r
+//\r
+// Should be used in combination with NORETURN to avoid 'noreturn' returns\r
+// warnings.\r
+//\r
+#ifndef UNREACHABLE\r
+  #ifdef __GNUC__\r
+    ///\r
+    /// Signal compilers and analyzers that this call is not reachable.  It is\r
+    /// up to the compiler to remove any code past that point.\r
+    ///\r
+    #define UNREACHABLE()  __builtin_unreachable ()\r
+  #elif defined (__has_feature)\r
+    #if __has_builtin (__builtin_unreachable)\r
+      ///\r
+      /// Signal compilers and analyzers that this call is not reachable.  It is\r
+      /// up to the compiler to remove any code past that point.\r
+      ///\r
+      #define UNREACHABLE()  __builtin_unreachable ()\r
+    #endif\r
+  #endif\r
+\r
+  #ifndef UNREACHABLE\r
+    ///\r
+    /// Signal compilers and analyzers that this call is not reachable.  It is\r
+    /// up to the compiler to remove any code past that point.\r
+    ///\r
+    #define UNREACHABLE()\r
+  #endif\r
+#endif\r
+\r
+//\r
+// Signaling compilers and analyzers that a certain function cannot return may\r
+// remove all following code and thus lead to better optimization and less\r
+// false positives.\r
+//\r
+#ifndef NORETURN\r
+  #if defined (__GNUC__) || defined (__clang__)\r
+    ///\r
+    /// Signal compilers and analyzers that the function cannot return.\r
+    /// It is up to the compiler to remove any code past a call to functions\r
+    /// flagged with this attribute.\r
+    ///\r
+    #define NORETURN  __attribute__((noreturn))\r
+  #elif defined(_MSC_EXTENSIONS) && !defined(MDE_CPU_EBC)\r
+    ///\r
+    /// Signal compilers and analyzers that the function cannot return.\r
+    /// It is up to the compiler to remove any code past a call to functions\r
+    /// flagged with this attribute.\r
+    ///\r
+    #define NORETURN  __declspec(noreturn)\r
+  #else\r
+    ///\r
+    /// Signal compilers and analyzers that the function cannot return.\r
+    /// It is up to the compiler to remove any code past a call to functions\r
+    /// flagged with this attribute.\r
+    ///\r
+    #define NORETURN\r
+  #endif\r
+#endif\r
+\r
+//\r
+// Should be used in combination with ANALYZER_NORETURN to avoid 'noreturn'\r
+// returns warnings.\r
+//\r
+#ifndef ANALYZER_UNREACHABLE\r
+  #ifdef __clang_analyzer__\r
+    #if __has_builtin (__builtin_unreachable)\r
+      ///\r
+      /// Signal the analyzer that this call is not reachable.\r
+      /// This excludes compilers.\r
+      ///\r
+      #define ANALYZER_UNREACHABLE()  __builtin_unreachable ()\r
+    #endif\r
+  #endif\r
+\r
+  #ifndef ANALYZER_UNREACHABLE\r
+    ///\r
+    /// Signal the analyzer that this call is not reachable.\r
+    /// This excludes compilers.\r
+    ///\r
+    #define ANALYZER_UNREACHABLE()\r
+  #endif\r
+#endif\r
+\r
+//\r
+// Static Analyzers may issue errors about potential NULL-dereferences when\r
+// dereferencing a pointer, that has been checked before, outside of a\r
+// NULL-check.  This may lead to false positives, such as when using ASSERT()\r
+// for verification.\r
+//\r
+#ifndef ANALYZER_NORETURN\r
+  #ifdef __has_feature\r
+    #if __has_feature (attribute_analyzer_noreturn)\r
+      ///\r
+      /// Signal analyzers that the function cannot return.\r
+      /// This excludes compilers.\r
+      ///\r
+      #define ANALYZER_NORETURN  __attribute__((analyzer_noreturn))\r
+    #endif\r
+  #endif\r
+\r
+  #ifndef ANALYZER_NORETURN\r
+    ///\r
+    /// Signal the analyzer that the function cannot return.\r
+    /// This excludes compilers.\r
+    ///\r
+    #define ANALYZER_NORETURN\r
+  #endif\r
+#endif\r
+\r
 //\r
 // For symbol name in assembly code, an extra "_" is sometimes necessary\r
 //\r