From: Matthew Fernandez Date: Sun, 20 Jun 2021 21:09:41 +0000 (-0700) Subject: add a macro for optimizing unreachable code X-Git-Tag: 2.48.0~31^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0a1324f28dc0250c75cd4ea82b5bd56d04ef68d3;p=graphviz add a macro for optimizing unreachable code --- diff --git a/lib/cgraph/CMakeLists.txt b/lib/cgraph/CMakeLists.txt index f52e93d9a..b1466d2d7 100644 --- a/lib/cgraph/CMakeLists.txt +++ b/lib/cgraph/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(cgraph SHARED itos.h sprint.h strcasecmp.h + unreachable.h # Source files agerror.c diff --git a/lib/cgraph/Makefile.am b/lib/cgraph/Makefile.am index 9d5204525..04317540b 100644 --- a/lib/cgraph/Makefile.am +++ b/lib/cgraph/Makefile.am @@ -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 diff --git a/lib/cgraph/cgraph.vcxproj b/lib/cgraph/cgraph.vcxproj index 7fa787f35..03f0d3d3a 100644 --- a/lib/cgraph/cgraph.vcxproj +++ b/lib/cgraph/cgraph.vcxproj @@ -104,6 +104,7 @@ win_flex -oscan.c scan.l + diff --git a/lib/cgraph/cgraph.vcxproj.filters b/lib/cgraph/cgraph.vcxproj.filters index f6d120770..7d5911412 100644 --- a/lib/cgraph/cgraph.vcxproj.filters +++ b/lib/cgraph/cgraph.vcxproj.filters @@ -33,6 +33,9 @@ Header Files + + Header Files + diff --git a/lib/cgraph/unreachable.h b/lib/cgraph/unreachable.h new file mode 100644 index 000000000..f3d69b730 --- /dev/null +++ b/lib/cgraph/unreachable.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +/** 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