Also, minimize whitespace differences from glibc,
to simplify comparison.
* lib/cdefs.h: Do not issue header warning if C++.
(__COLD, __attribute_overloadable__, __REDIRECT_FORTIFY)
(__REDIRECT_FORTIFY_NTH, __glibc_const_generic)
(__attribute_struct_may_alias__): New macros.
Several other new macros are defined if !__GNULIB_CDEFS.
(__glibc_safe_or_unknown_len): Check that __osz is a constant.
(__REDIRECT_LDBL): Optimize error redirects for ieeelongdouble.
(__fortified_attr_access): Drop access attribute for _FORTIFY_SOURCE=3.
---
 ChangeLog   |  14 +++
 lib/cdefs.h | 247 ++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 233 insertions(+), 28 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7681ab4c5d..35f761a0d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2026-02-21  Paul Eggert  <[email protected]>
+
+       cdefs: merge from glibc
+       Also, minimize whitespace differences from glibc,
+       to simplify comparison.
+       * lib/cdefs.h: Do not issue header warning if C++.
+       (__COLD, __attribute_overloadable__, __REDIRECT_FORTIFY)
+       (__REDIRECT_FORTIFY_NTH, __glibc_const_generic)
+       (__attribute_struct_may_alias__): New macros.
+       Several other new macros are defined if !__GNULIB_CDEFS.
+       (__glibc_safe_or_unknown_len): Check that __osz is a constant.
+       (__REDIRECT_LDBL): Optimize error redirects for ieeelongdouble.
+       (__fortified_attr_access): Drop access attribute for _FORTIFY_SOURCE=3.
+
 2026-02-21  Bruno Haible  <[email protected]>
 
        strnul: Add tests.
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 696e65424b..4e82167c26 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -27,8 +27,8 @@
 /* The GNU libc does not support any K&R compilers or the traditional mode
    of ISO C compilers anymore.  Check for some of the combinations not
    supported anymore.  */
-#if defined __GNUC__ && !defined __STDC__
-# error "You need a ISO C conforming compiler to use the glibc headers"
+#if defined __GNUC__ && !defined __STDC__ && !defined __cplusplus
+# error "You need a ISO C or C++ conforming compiler to use the glibc headers"
 #endif
 
 /* Some user header file might have defined this before.  */
@@ -100,6 +100,12 @@
 #  endif
 # endif
 
+# if __GNUC_PREREQ (4, 3) || __glibc_has_attribute (__cold__)
+#  define __COLD       __attribute__ ((__cold__))
+# else
+#  define __COLD
+# endif
+
 #else  /* Not GCC or clang.  */
 
 # if (defined __cplusplus                                              \
@@ -112,6 +118,7 @@
 # define __THROW
 # define __THROWNL
 # define __NTH(fct)    fct
+# define __COLD
 
 #endif /* GCC || clang.  */
 
@@ -140,38 +147,47 @@
 #endif
 
 
+/* The overloadable attribute was added on clang 2.6. */
+#if defined __clang_major__ \
+    && (__clang_major__ + (__clang_minor__ >= 6) > 2)
+# define __attribute_overloadable__ __attribute__((__overloadable__))
+#else
+# define __attribute_overloadable__
+#endif
+
 /* Gnulib avoids these definitions, as they don't work on non-glibc platforms.
    In particular, __bos and __bos0 are defined differently in the Android libc.
  */
 #ifndef __GNULIB_CDEFS
 
 /* Fortify support.  */
-# define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
-# define __bos0(ptr) __builtin_object_size (ptr, 0)
+#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
 
 /* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available.  */
-# if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0)                \
-                                 || __GNUC_PREREQ (12, 0))
-#  define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
-#  define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
-# else
-#  define __glibc_objsize0(__o) __bos0 (__o)
-#  define __glibc_objsize(__o) __bos (__o)
-# endif
+#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0)                 \
+                                || __GNUC_PREREQ (12, 0))
+# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
+# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
+#else
+# define __glibc_objsize0(__o) __bos0 (__o)
+# define __glibc_objsize(__o) __bos (__o)
+#endif
 
+#if __USE_FORTIFY_LEVEL > 0
 /* Compile time conditions to choose between the regular, _chk and _chk_warn
    variants.  These conditions should get evaluated to constant and optimized
    away.  */
 
-# define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s))
-# define __glibc_unsigned_or_positive(__l) \
+#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s))
+#define __glibc_unsigned_or_positive(__l) \
   ((__typeof (__l)) 0 < (__typeof (__l)) -1                                  \
    || (__builtin_constant_p (__l) && (__l) > 0))
 
 /* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
    condition can be folded to a constant and if it is true, or unknown (-1) */
-# define __glibc_safe_or_unknown_len(__l, __s, __osz) \
-  ((__osz) == (__SIZE_TYPE__) -1                                             \
+#define __glibc_safe_or_unknown_len(__l, __s, __osz) \
+  ((__builtin_constant_p (__osz) && (__osz) == (__SIZE_TYPE__) -1)           \
    || (__glibc_unsigned_or_positive (__l)                                    \
        && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
                                                       (__s), (__osz)))       \
@@ -180,34 +196,179 @@
 /* Conversely, we know at compile time that the length is unsafe if the
    __L * __S <= __OBJSZ condition can be folded to a constant and if it is
    false.  */
-# define __glibc_unsafe_len(__l, __s, __osz) \
+#define __glibc_unsafe_len(__l, __s, __osz) \
   (__glibc_unsigned_or_positive (__l)                                        \
    && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l),     \
                                                   __s, __osz))               \
    && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
 
+/* To correctly instrument the fortify wrapper clang requires the
+   pass_object_size attribute, and the attribute has the restriction that the
+   argument needs to be 'const'.  Furthermore, to make it usable with C
+   interfaces, clang provides the overload attribute, which provides a C++
+   like function overload support.  The overloaded fortify wrapper with the
+   pass_object_size attribute has precedence over the default symbol.
+
+   Also, clang does not support __va_arg_pack, so variadic functions are
+   expanded to issue va_arg implementations. The error function must not have
+   bodies (address takes are expanded to nonfortified calls), and with
+   __fortify_function compiler might still create a body with the C++
+   mangling name (due to the overload attribute).  In this case, the function
+   is defined with __fortify_function_error_function macro instead.
+
+   The argument size check is also done with a clang-only attribute,
+   __attribute__ ((__diagnose_if__ (...))), different than gcc which calls
+   symbol_chk_warn alias with uses __warnattr attribute.
+
+   The pass_object_size was added on clang 4.0, __diagnose_if__ on 5.0,
+   and pass_dynamic_object_size on 9.0.  */
+#if defined __clang_major__ && __clang_major__ >= 5
+# define __fortify_use_clang 1
+
+# define __fortify_function_error_function static __attribute__((__unused__))
+
+# define __fortify_clang_pass_object_size_n(n) \
+  __attribute__ ((__pass_object_size__ (n)))
+# define __fortify_clang_pass_object_size0 \
+  __fortify_clang_pass_object_size_n (0)
+# define __fortify_clang_pass_object_size \
+  __fortify_clang_pass_object_size_n (__USE_FORTIFY_LEVEL > 1)
+
+# if __clang_major__ >= 9
+#  define __fortify_clang_pass_dynamic_object_size_n(n) \
+  __attribute__ ((__pass_dynamic_object_size__ (n)))
+#  define __fortify_clang_pass_dynamic_object_size0 \
+  __fortify_clang_pass_dynamic_object_size_n (0)
+#  define __fortify_clang_pass_dynamic_object_size \
+  __fortify_clang_pass_dynamic_object_size_n (1)
+# else
+#  define __fortify_clang_pass_dynamic_object_size_n(n)
+#  define __fortify_clang_pass_dynamic_object_size0
+#  define __fortify_clang_pass_dynamic_object_size
+# endif
+
+# define __fortify_clang_bos_static_lt_impl(bos_val, n, s) \
+  ((bos_val) != -1ULL && (n) > (bos_val) / (s))
+# define __fortify_clang_bos_static_lt2(__n, __e, __s) \
+  __fortify_clang_bos_static_lt_impl (__bos (__e), __n, __s)
+# define __fortify_clang_bos_static_lt(__n, __e) \
+  __fortify_clang_bos_static_lt2 (__n, __e, 1)
+# define __fortify_clang_bos0_static_lt2(__n, __e, __s) \
+  __fortify_clang_bos_static_lt_impl (__bos0 (__e), __n, __s)
+# define __fortify_clang_bos0_static_lt(__n, __e) \
+  __fortify_clang_bos0_static_lt2 (__n, __e, 1)
+
+# define __fortify_clang_bosn_args(bos_fn, n, buf, div, complaint) \
+  (__fortify_clang_bos_static_lt_impl (bos_fn (buf), n, div)), (complaint), \
+  "warning"
+
+# define __fortify_clang_warning(__c, __msg) \
+  __attribute__ ((__diagnose_if__ ((__c), (__msg), "warning")))
+#  define __fortify_clang_error(__c, __msg) \
+  __attribute__ ((__diagnose_if__ ((__c), (__msg), "error")))
+#  define __fortify_clang_warning_only_if_bos0_lt(n, buf, complaint) \
+  __attribute__ ((__diagnose_if__ \
+                 (__fortify_clang_bosn_args (__bos0, n, buf, 1, complaint))))
+# define __fortify_clang_warning_only_if_bos0_lt2(n, buf, div, complaint) \
+  __attribute__ ((__diagnose_if__ \
+                 (__fortify_clang_bosn_args (__bos0, n, buf, div, complaint))))
+# define __fortify_clang_warning_only_if_bos_lt(n, buf, complaint) \
+  __attribute__ ((__diagnose_if__ \
+                 (__fortify_clang_bosn_args (__bos, n, buf, 1, complaint))))
+# define __fortify_clang_warning_only_if_bos_lt2(n, buf, div, complaint) \
+  __attribute__ ((__diagnose_if__ \
+                 (__fortify_clang_bosn_args (__bos, n, buf, div, complaint))))
+
+#  define __fortify_clang_prefer_this_overload \
+  __attribute__ ((enable_if (1, "")))
+#  define __fortify_clang_unavailable(__msg) \
+  __attribute__ ((unavailable(__msg)))
+
+# if __USE_FORTIFY_LEVEL == 3
+#  define __fortify_clang_overload_arg(__type, __attr, __name) \
+  __type __attr const __fortify_clang_pass_dynamic_object_size __name
+#  define __fortify_clang_overload_arg0(__type, __attr, __name) \
+  __type __attr const __fortify_clang_pass_dynamic_object_size0 __name
+# else
+#  define __fortify_clang_overload_arg(__type, __attr, __name) \
+  __type __attr const __fortify_clang_pass_object_size __name
+#  define __fortify_clang_overload_arg0(__type, __attr, __name) \
+  __type __attr const __fortify_clang_pass_object_size0 __name
+# endif
+
+# define __fortify_clang_mul_may_overflow(size, n) \
+  ((size | n) >= (((size_t)1) << (8 * sizeof (size_t) / 2)))
+
+# define __fortify_clang_size_too_small(__bos, __dest, __len) \
+  (__bos (__dest) != (size_t) -1 && __bos (__dest) < __len)
+# define __fortify_clang_warn_if_src_too_large(__dest, __src) \
+  __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \
+                                                          __dest, \
+                                                          __builtin_strlen 
(__src) + 1), \
+                          "destination buffer will always be overflown by 
source")
+# define __fortify_clang_warn_if_dest_too_small(__dest, __len) \
+  __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize, \
+                                                           __dest, \
+                                                           __len), \
+                           "function called with bigger length than the 
destination buffer")
+# define __fortify_clang_warn_if_dest_too_small0(__dest, __len) \
+  __fortify_clang_warning (__fortify_clang_size_too_small (__glibc_objsize0, \
+                                                           __dest, \
+                                                           __len), \
+                           "function called with bigger length than the 
destination buffer")
+#else
+# define __fortify_use_clang 0
+# define __fortify_clang_warning(__c, __msg)
+# define __fortify_clang_warning_only_if_bos0_lt(__n, __buf, __complaint)
+# define __fortify_clang_warning_only_if_bos0_lt2(__n, __buf, __div, complaint)
+# define __fortify_clang_warning_only_if_bos_lt(__n, __buf, __complaint)
+# define __fortify_clang_warning_only_if_bos_lt2(__n, __buf, div, __complaint)
+# define __fortify_clang_overload_arg(__type, __attr, __name) \
+ __type __attr __name
+# define __fortify_clang_overload_arg0(__type, __attr, __name) \
+  __fortify_clang_overload_arg (__type, __attr, __name)
+# define __fortify_clang_warn_if_src_too_large(__dest, __src)
+# define __fortify_clang_warn_if_dest_too_small(__dest, __len)
+# define __fortify_clang_warn_if_dest_too_small0(__dest, __len)
+#endif
+
+
 /* Fortify function f.  __f_alias, __f_chk and __f_chk_warn must be
    declared.  */
 
+#if !__fortify_use_clang
 # define __glibc_fortify(f, __l, __s, __osz, ...) \
   (__glibc_safe_or_unknown_len (__l, __s, __osz)                             \
    ? __ ## f ## _alias (__VA_ARGS__)                                         \
    : (__glibc_unsafe_len (__l, __s, __osz)                                   \
       ? __ ## f ## _chk_warn (__VA_ARGS__, __osz)                            \
-      : __ ## f ## _chk (__VA_ARGS__, __osz)))                       \
+      : __ ## f ## _chk (__VA_ARGS__, __osz)))
+#else
+# define __glibc_fortify(f, __l, __s, __osz, ...) \
+  (__osz == (__SIZE_TYPE__) -1)                                                
      \
+   ? __ ## f ## _alias (__VA_ARGS__)                                         \
+   : __ ## f ## _chk (__VA_ARGS__, __osz)
+#endif
 
 /* Fortify function f, where object size argument passed to f is the number of
    elements and not total size.  */
 
+#if !__fortify_use_clang
 # define __glibc_fortify_n(f, __l, __s, __osz, ...) \
   (__glibc_safe_or_unknown_len (__l, __s, __osz)                             \
    ? __ ## f ## _alias (__VA_ARGS__)                                         \
    : (__glibc_unsafe_len (__l, __s, __osz)                                   \
       ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s))                  \
-      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))                     \
-
+      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
+# else
+# define __glibc_fortify_n(f, __l, __s, __osz, ...) \
+  (__osz == (__SIZE_TYPE__) -1)                                                
      \
+   ? __ ## f ## _alias (__VA_ARGS__)                                         \
+   : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))
 #endif
 
+#endif /* __USE_FORTIFY_LEVEL > 0 */
+#endif /* !__GNULIB_CDEFS */
 
 #if __GNUC_PREREQ (4,3)
 # define __warnattr(msg) __attribute__((__warning__ (msg)))
@@ -269,6 +430,14 @@
 # define __ASMNAME(cname)  __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
 # define __ASMNAME2(prefix, cname) __STRING (prefix) cname
 
+#ifndef __REDIRECT_FORTIFY
+#define __REDIRECT_FORTIFY __REDIRECT
+#endif
+
+#ifndef __REDIRECT_FORTIFY_NTH
+#define __REDIRECT_FORTIFY_NTH __REDIRECT_NTH
+#endif
+
 /*
 #elif __SOME_OTHER_COMPILER__
 
@@ -445,14 +614,14 @@
 # define __attribute_artificial__ /* Ignore */
 #endif
 
-/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
-   inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__
-   or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
+/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 inline
+   semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__ or
+   __GNUC_GNU_INLINE__ is not a good enough check for gcc because gcc versions
    older than 4.3 may define these macros and still not guarantee GNU inlining
    semantics.
 
    clang++ identifies itself as gcc-4.2, but has support for GNU inlining
-   semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and
+   semantics, that can be checked for by using the __GNUC_STDC_INLINE__ and
    __GNUC_GNU_INLINE__ macro definitions.  */
 #if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
      || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
@@ -577,6 +746,8 @@
 #  define __LDBL_REDIR(name, proto) ... unused__ldbl_redir
 #  define __LDBL_REDIR_DECL(name) \
   extern __typeof (name) name __asm (__ASMNAME ("__" #name "ieee128"));
+#  define __REDIRECT_LDBL(name, proto, alias) \
+  name proto __asm (__ASMNAME ("__" #alias "ieee128"))
 
 /* Alias name defined automatically, with leading underscores.  */
 #  define __LDBL_REDIR2_DECL(name) \
@@ -594,7 +765,6 @@
   __LDBL_REDIR1_NTH (name, proto, __##alias##ieee128)
 
 /* Unused.  */
-#  define __REDIRECT_LDBL(name, proto, alias) ... unused__redirect_ldbl
 #  define __LDBL_REDIR_NTH(name, proto) ... unused__ldbl_redir_nth
 
 # else
@@ -666,6 +836,18 @@ _Static_assert (0, "IEEE 128-bits long double requires 
redirection on this platf
 # define __HAVE_GENERIC_SELECTION 0
 #endif
 
+#if __HAVE_GENERIC_SELECTION
+/* If PTR is a pointer to const, return CALL cast to type CTYPE,
+   otherwise return CALL.  Pointers to types with non-const qualifiers
+   are not valid.  This should not be defined for C++, as macros are
+   not an appropriate way of implementing such qualifier-generic
+   operations for C++.  */
+# define __glibc_const_generic(PTR, CTYPE, CALL)       \
+  _Generic (0 ? (PTR) : (void *) 1,                    \
+           const void *: (CTYPE) (CALL),               \
+           default: CALL)
+#endif
+
 #if __GNUC_PREREQ (10, 0)
 /* Designates a 1-based positional argument ref-index of pointer type
    that can be used to access size-index elements of the pointed-to
@@ -675,10 +857,10 @@ _Static_assert (0, "IEEE 128-bits long double requires 
redirection on this platf
 #  define __attr_access(x) __attribute__ ((__access__ x))
 /* For _FORTIFY_SOURCE == 3 we use __builtin_dynamic_object_size, which may
    use the access attribute to get object sizes from function definition
-   arguments, so we can't use them on functions we fortify.  Drop the object
-   size hints for such functions.  */
+   arguments, so we can't use them on functions we fortify.  Drop the access
+   attribute for such functions.  */
 #  if __USE_FORTIFY_LEVEL == 3
-#    define __fortified_attr_access(a, o, s) __attribute__ ((__access__ (a, 
o)))
+#    define __fortified_attr_access(a, o, s)
 #  else
 #    define __fortified_attr_access(a, o, s) __attr_access ((a, o, s))
 #  endif
@@ -712,4 +894,13 @@ _Static_assert (0, "IEEE 128-bits long double requires 
redirection on this platf
 # define __attribute_returns_twice__ /* Ignore.  */
 #endif
 
+/* Mark struct types as aliasable.  Restricted to compilers that
+   support forward declarations of structs in the presence of the
+   attribute.  */
+#if __GNUC_PREREQ (7, 1) || defined __clang__
+# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__))
+#else
+# define __attribute_struct_may_alias__
+#endif
+
 #endif  /* sys/cdefs.h */
-- 
2.51.0


Reply via email to