Page MenuHomeFreeBSD

D58983.id184350.diff
No OneTemporary

D58983.id184350.diff

diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -369,16 +369,83 @@
#define __rangeof(type, start, end) \
(__offsetof(type, end) - __offsetof(type, start))
+/*
+ * Clang's -fbounds-safety annotations
+ * (https://clang.llvm.org/docs/BoundsSafety.html). Each ties a pointer to the
+ * expression that bounds it and keeps plain-C pointer ABI. Every macro expands
+ * to nothing without the extension, so the tree still builds with GCC and
+ * stock Clang.
+ */
+#if __has_feature(bounds_attributes) || __has_feature(bounds_safety_attributes)
+#define __has_ptrcheck 1
+/* Pointer to exactly one object: arithmetic on it is a compile-time error. */
+#define __single __attribute__((__single__))
+/* Ordinary unchecked C pointer; conversion to checked forms is explicit. */
+#define __unsafe_indexable __attribute__((__unsafe_indexable__))
+/* Pointer to N elements; N is a sibling parameter, field or constant. */
+#define __counted_by(N) __attribute__((__counted_by__(N)))
+#define __counted_by_or_null(N) __attribute__((__counted_by_or_null__(N)))
+/* As __counted_by, but N counts bytes rather than elements. */
+#define __sized_by(N) __attribute__((__sized_by__(N)))
+#define __sized_by_or_null(N) __attribute__((__sized_by_or_null__(N)))
+/* Pointer bounded by the sibling pointer E (one past the end). */
+#define __ended_by(E) __attribute__((__ended_by__(E)))
+/* Escape hatches: produce a checked pointer from an address (and size). */
+#define __unsafe_forge_single(T, P) \
+ ((T __single)__builtin_unsafe_forge_single((P)))
+#define __unsafe_forge_bidi_indexable(T, P, S) \
+ ((T __bidi_indexable)__builtin_unsafe_forge_bidi_indexable((P), (S)))
+/* Set the default ABI for subsequent unannotated pointers in this file. */
+#define __ptrcheck_abi_assume_single() \
+ _Pragma("clang abi_ptr_attr set(single)")
+#define __ptrcheck_abi_assume_unsafe_indexable() \
+ _Pragma("clang abi_ptr_attr set(unsafe_indexable)")
+/*
+ * Wide (fat) pointers carrying their bounds at run time. These change the
+ * pointer's layout and so are only for function locals, never for
+ * ABI-visible declarations (parameters, struct fields, globals).
+ */
+#if __has_feature(bounds_attributes)
+#define __bidi_indexable __attribute__((__bidi_indexable__))
+#define __indexable __attribute__((__indexable__))
+#endif
+#else
+#define __has_ptrcheck 0
+#define __single
+#define __unsafe_indexable
+#define __counted_by(N)
+#define __counted_by_or_null(N)
+#define __sized_by(N)
+#define __sized_by_or_null(N)
+#define __ended_by(E)
+#define __unsafe_forge_single(T, P) ((T)(P))
+#define __unsafe_forge_bidi_indexable(T, P, S) ((void)(S), (T)(P))
+#define __ptrcheck_abi_assume_single()
+#define __ptrcheck_abi_assume_unsafe_indexable()
+/*
+ * __bidi_indexable and __indexable are left undefined here: a build error
+ * beats a silent ABI break if they reach an unsupporting compiler.
+ */
+#endif
+
/*
* Given the pointer x to the member m of the struct s, return
* a pointer to the containing structure. When using GCC, we first
* assign pointer x to a local variable, to check that its type is
* compatible with member m.
*/
+#if __has_ptrcheck
+#define __containerof(x, s, m) ({ \
+ const volatile __typeof(((s *)0)->m) *__x = (x); \
+ __unsafe_forge_single(s *, \
+ (__uintptr_t)__x - __offsetof(s, m)); \
+})
+#else
#define __containerof(x, s, m) ({ \
const volatile __typeof(((s *)0)->m) *__x = (x); \
__DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
})
+#endif
/*
* Compiler-dependent macros to declare that functions take printf-like

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 5:06 PM (5 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36991660
Default Alt Text
D58983.id184350.diff (3 KB)

Event Timeline