From dd62fb6eeb9a5bc9a870430a93c6de1aca4be1d6 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Sun, 3 Oct 2021 14:03:25 +0200 Subject: [PATCH 01/21] avutil/avassert: Add av_unreachable and av_assume() macros Useful to let the compiler and static analyzers know that something is unreachable without adding an av_assert (which would be either dead for the compiler or add runtime overhead) for this. The implementation used here enforces the use of a message to provide a reason why a particular code is supposed to be unreachable. Signed-off-by: Andreas Rheinhardt --- doc/APIchanges | 3 +++ libavutil/avassert.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index 75d66f87f3..78dcaa8009 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28 API changes, most recent first: +2025-05-06 - xxxxxxxxxx - lavu 60.xx.100 - avassert.h + Add av_unreachable() and av_assume() macros. + 2025-04-21 - xxxxxxxxxx - lavu 60.2.100 - log.h Add AV_CLASS_CATEGORY_HWDEVICE. diff --git a/libavutil/avassert.h b/libavutil/avassert.h index 1895fb7551..d0d5aa0c7e 100644 --- a/libavutil/avassert.h +++ b/libavutil/avassert.h @@ -31,6 +31,7 @@ #ifdef HAVE_AV_CONFIG_H # include "config.h" #endif +#include "attributes.h" #include "log.h" #include "macros.h" @@ -75,4 +76,45 @@ */ void av_assert0_fpu(void); +/** + * Asserts that are used as compiler optimization hints depending + * upon ASSERT_LEVEL and NBDEBUG. + * + * Undefined behaviour occurs if execution reaches a point marked + * with av_unreachable() or if a condition used with av_assume() + * is false. + * + * The condition used with av_assume() should not have side-effects + * and should be visible to the compiler. + */ +#if defined(ASSERT_LEVEL) ? ASSERT_LEVEL > 0 : !defined(HAVE_AV_CONFIG_H) && !defined(NDEBUG) +#define av_unreachable(msg) \ +do { \ + av_log(NULL, AV_LOG_PANIC, \ + "Code at %s:%d that was supposedly unreachable due to '%s' reached\n", \ + __FILE__, __LINE__, msg); \ + abort(); \ +} while (0) +#define av_assume(cond) av_assert0(cond) +#else +#if AV_GCC_VERSION_AT_LEAST(4, 5) || AV_HAS_BUILTIN(__builtin_unreachable) +#define av_unreachable(msg) __builtin_unreachable() +#elif defined(_MSC_VER) +#define av_unreachable(msg) __assume(0) +#define av_assume(cond) __assume(cond) +#elif __STDC_VERSION__ >= 202311L +#include +#define av_unreachable(msg) unreachable() +#else +#define av_unreachable(msg) ((void)0) +#endif + +#ifndef av_assume +#define av_assume(cond) do { \ + if (!(cond)) \ + av_unreachable(); \ +} while (0) +#endif +#endif + #endif /* AVUTIL_AVASSERT_H */ -- 2.45.2