]> granicus.if.org Git - graphviz/commitdiff
add a macro for optimizing unreachable code
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 20 Jun 2021 21:09:41 +0000 (14:09 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 26 Jun 2021 16:42:17 +0000 (09:42 -0700)
lib/cgraph/CMakeLists.txt
lib/cgraph/Makefile.am
lib/cgraph/cgraph.vcxproj
lib/cgraph/cgraph.vcxproj.filters
lib/cgraph/unreachable.h [new file with mode: 0644]

index f52e93d9a68381c4478525a47631c58ffadd404e..b1466d2d7e8015723c73d4787698e49d47874501 100644 (file)
@@ -12,6 +12,7 @@ add_library(cgraph SHARED
     itos.h
     sprint.h
     strcasecmp.h
+    unreachable.h
 
     # Source files
     agerror.c
index 9d520452577937fcaa6f50ffbc003831a42c02fe..04317540b99cab16c8485fe3d6ff639d8239a11c 100644 (file)
@@ -8,7 +8,7 @@ pkgconfigdir = $(libdir)/pkgconfig
 AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)/lib/cdt
 
 pkginclude_HEADERS = cgraph.h
-noinst_HEADERS = agxbuf.h cghdr.h itos.h sprint.h strcasecmp.h
+noinst_HEADERS = agxbuf.h cghdr.h itos.h sprint.h strcasecmp.h unreachable.h
 noinst_LTLIBRARIES = libcgraph_C.la
 lib_LTLIBRARIES = libcgraph.la
 pkgconfig_DATA = libcgraph.pc
index 7fa787f35df31a1624b9eec5a7a080b3f680c8d7..03f0d3d3aca643ec9cf833cc85d20c01b4c8b945 100644 (file)
@@ -104,6 +104,7 @@ win_flex -oscan.c scan.l</Command>
     <ClInclude Include="itos.h" />
     <ClInclude Include="sprint.h" />
     <ClInclude Include="strcasecmp.h" />
+    <ClInclude Include="unreachable.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="agerror.c" />
index f6d120770c043bf7606a17278dbc6a41f4ac989d..7d59114125ae01465c7c401ab59004cfb9a6023b 100644 (file)
@@ -33,6 +33,9 @@
     <ClInclude Include="strcasecmp.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="unreachable.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="agerror.c">
diff --git a/lib/cgraph/unreachable.h b/lib/cgraph/unreachable.h
new file mode 100644 (file)
index 0000000..f3d69b7
--- /dev/null
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <assert.h>
+#include <stdlib.h>
+
+/** Marker for a point in code which execution can never reach.
+ *
+ * As a C11 function, this could be thought of as:
+ *
+ *   _Noreturn void UNREACHABLE(void);
+ *
+ * Calling this teaches the compiler that the call site can never be executed,
+ * and it can optimize with this assumption in mind. This can be used to explain
+ * that a switch is exhaustive:
+ *
+ *   switch (…) {
+ *   default: UNREACHABLE();
+ *   …remaining cases that cover all possibilities…
+ *   }
+ *
+ * or that a function coda can be omitted:
+ *
+ *   int foo(void) {
+ *     while (always_true()) {
+ *     }
+ *     UNREACHABLE();
+ *   }
+ */
+#ifdef __GNUC__
+#define UNREACHABLE()                                                          \
+  do {                                                                         \
+    assert(0 && "unreachable");                                                \
+    __builtin_unreachable();                                                   \
+  } while (0)
+#elif defined(_MSC_VER)
+#define UNREACHABLE()                                                          \
+  do {                                                                         \
+    assert(0 && "unreachable");                                                \
+    __assume(0);                                                               \
+  } while (0)
+#else
+#define UNREACHABLE()                                                          \
+  do {                                                                         \
+    assert(0 && "unreachable");                                                \
+    abort();                                                                   \
+  } while (0)
+#endif