From a48eafa75402a61e8fd2a379236f58a13739a482 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Fri, 3 Jul 2020 15:03:57 +0100
Subject: [PATCH] utils: Add fallback definitions for alignof, offsetof,
 static_assert

This assumes either a C11 compiler, or as a fallback, a tolerably new
version of gcc.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 configure.ac  |  1 +
 utils/utils.h | 44 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index bbbbf565a..00b6911b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,7 @@ WARN_CFLAGS=$(echo "$WARN_CFLAGS" | sed -Ee 's,-W(error=)?declaration-after-stat
 WARN_CFLAGS=$(echo "$WARN_CFLAGS" | sed -Ee 's,-W(error=)?pointer-arith,,')
 
 AC_CHECK_FUNCS_ONCE([secure_getenv])
+AC_CHECK_HEADERS_ONCE([stdalign.h])
 
 AM_CONDITIONAL([ENABLE_SHARED], [test "x$enable_shared" = xyes])
 
diff --git a/utils/utils.h b/utils/utils.h
index 357d1274b..89aee28f5 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -1,4 +1,4 @@
-// Copyright © 2017 Collabora Ltd
+// Copyright © 2017-2020 Collabora Ltd
 
 // This file is part of libcapsule.
 
@@ -17,6 +17,7 @@
 
 #pragma once
 
+#include <assert.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <stddef.h>
@@ -26,6 +27,10 @@
 
 #include "debug.h"
 
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+
 #define UNLIKELY(x) __builtin_expect(x, 0)
 #define LIKELY(x)   __builtin_expect(x, 1)
 
@@ -187,3 +192,40 @@ _capsule_clear( void *pp )
  * on exit from its scope.
  */
 #define _capsule_autofree _capsule_cleanup(_capsule_clear)
+
+/*
+ * alignof:
+ * @type: A type
+ *
+ * The same as in Standard C: return the minimal alignment of a type.
+ *
+ * Note that this is not the same as gcc __alignof__, which returns the
+ * type's *preferred* alignment, which is sometimes greater than the
+ * *minimal* alignment returned by this macro.
+ */
+#ifndef alignof
+# define alignof(type) (__builtin_offsetof(struct { char a; type b; }, b))
+#endif
+
+/*
+ * offsetof:
+ * @t: A `struct` type
+ * @m: A member
+ *
+ * The same as in Standard C: return the offset of @m within @t.
+ */
+#ifndef offsetof
+# define offsetof(t, m) (__builtin_offsetof(t, m))
+#endif
+
+/*
+ * static_assert:
+ * @expr: An expression to evaluate at compile-time
+ * @message: A diagnostic message used if @expr is not true
+ *
+ * The same as in Standard C: evaluate @expr as a compile-time constant
+ * expression, and fail to build if it is zero.
+ */
+#ifndef static_assert
+# define static_assert(expr, message) _Static_assert(expr, message)
+#endif
-- 
GitLab