#ifndef __LINUX_COMPILER_TYPES_H
 #define __LINUX_COMPILER_TYPES_H
 
+/*
+ * __has_builtin is supported on gcc >= 10, clang >= 3 and icc >= 21.
+ * In the meantime, to support gcc < 10, we implement __has_builtin
+ * by hand.
+ */
+#ifndef __has_builtin
+#define __has_builtin(x) (0)
+#endif
+
 #ifndef __ASSEMBLY__
 
 /*
 # define __preserve_most
 #endif
 
-/* Builtins */
-
-/*
- * __has_builtin is supported on gcc >= 10, clang >= 3 and icc >= 21.
- * In the meantime, to support gcc < 10, we implement __has_builtin
- * by hand.
- */
-#ifndef __has_builtin
-#define __has_builtin(x) (0)
-#endif
-
 /* Compiler specific macros. */
 #ifdef __clang__
 #include <linux/compiler-clang.h>
 # define __realloc_size(x, ...)
 #endif
 
+/*
+ * When the size of an allocated object is needed, use the best available
+ * mechanism to find it. (For cases where sizeof() cannot be used.)
+ */
+#if __has_builtin(__builtin_dynamic_object_size)
+#define __struct_size(p)       __builtin_dynamic_object_size(p, 0)
+#define __member_size(p)       __builtin_dynamic_object_size(p, 1)
+#else
+#define __struct_size(p)       __builtin_object_size(p, 0)
+#define __member_size(p)       __builtin_object_size(p, 1)
+#endif
+
 #ifndef asm_volatile_goto
 #define asm_volatile_goto(x...) asm goto(x)
 #endif
 
 #if __has_builtin(__builtin_dynamic_object_size)
 #define POS                    __pass_dynamic_object_size(1)
 #define POS0                   __pass_dynamic_object_size(0)
-#define __struct_size(p)       __builtin_dynamic_object_size(p, 0)
-#define __member_size(p)       __builtin_dynamic_object_size(p, 1)
 #else
 #define POS                    __pass_object_size(1)
 #define POS0                   __pass_object_size(0)
-#define __struct_size(p)       __builtin_object_size(p, 0)
-#define __member_size(p)       __builtin_object_size(p, 1)
 #endif
 
 #define __compiletime_lessthan(bounds, length) (       \
 
 #define struct_size_t(type, member, count)                                     \
        struct_size((type *)NULL, member, count)
 
+/**
+ * _DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
+ * Enables caller macro to pass (different) initializer.
+ *
+ * @type: structure type name, including "struct" keyword.
+ * @name: Name for a variable to define.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ * @initializer: initializer expression (could be empty for no init).
+ */
+#define _DEFINE_FLEX(type, name, member, count, initializer)                   \
+       _Static_assert(__builtin_constant_p(count),                             \
+                      "onstack flex array members require compile-time const count"); \
+       union {                                                                 \
+               u8 bytes[struct_size_t(type, member, count)];                   \
+               type obj;                                                       \
+       } name##_u initializer;                                                 \
+       type *name = (type *)&name##_u
+
+/**
+ * DEFINE_FLEX() - Define an on-stack instance of structure with a trailing
+ * flexible array member.
+ *
+ * @type: structure type name, including "struct" keyword.
+ * @name: Name for a variable to define.
+ * @member: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ *
+ * Define a zeroed, on-stack, instance of @type structure with a trailing
+ * flexible array member.
+ * Use __struct_size(@name) to get compile-time size of it afterwards.
+ */
+#define DEFINE_FLEX(type, name, member, count)                 \
+       _DEFINE_FLEX(type, name, member, count, = {})
+
 #endif /* __LINUX_OVERFLOW_H */