[libc-commits] [libc] [libc] Make math-macros.h C++-friendly (PR #86206)

Roland McGrath via libc-commits libc-commits at lists.llvm.org
Thu Mar 21 15:01:15 PDT 2024


https://github.com/frobtech created https://github.com/llvm/llvm-project/pull/86206

The isfinite, isnan, and isinf "functions" are specified by C99..C23 to be macros that act as type-generic functions. Defining them as their __builtin_* counterparts works fine for this.  However, in C++ the identifiers need to be usable in different contexts, such as being declared inside a C++ namespace.  So define inline constexpr template functions for them under `#ifdef __cplusplus`.

>From a6cf9cabe747c43d2da4be8c6e4febe9d21335f0 Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr at google.com>
Date: Thu, 21 Mar 2024 14:37:08 -0700
Subject: [PATCH] [libc] Make math-macros.h C++-friendly

The isfinite, isnan, and isinf "functions" are specified by
C99..C23 to be macros that act as type-generic functions.
Defining them as their __builtin_* counterparts works fine for
this.  However, in C++ the identifiers need to be usable in
different contexts, such as being declared inside a C++
namespace.  So define inline constexpr template functions
for them under `#ifdef __cplusplus`.
---
 libc/include/llvm-libc-macros/math-macros.h | 32 ++++++++++++++++++---
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index db8a4ea65bd69a..2605535b927d76 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -30,10 +30,6 @@
 #define FP_LLOGB0 (-LONG_MAX - 1)
 #define FP_LLOGBNAN LONG_MAX
 
-#define isfinite(x) __builtin_isfinite(x)
-#define isinf(x) __builtin_isinf(x)
-#define isnan(x) __builtin_isnan(x)
-
 #ifdef __FAST_MATH__
 #define math_errhandling 0
 #elif defined(__NO_MATH_ERRNO__)
@@ -44,4 +40,32 @@
 #define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
 #endif
 
+// These must be type-generic functions.  The C standard specifies them as
+// being macros rather than functions, in fact.  However, in C++ it's important
+// that there be function declarations that don't interfere with other uses of
+// the identifier, even in places with parentheses where a function-like macro
+// will be expanded (such as a function declaration in a C++ namespace).
+
+#ifdef __cplusplus
+
+template <typename T> inline constexpr bool isfinite(T x) {
+  return __builtin_isfinite(x);
+}
+
+template <typename T> inline constexpr bool isinf(T x) {
+  return __builtin_isinf(x);
+}
+
+template <typename T> inline constexpr bool isnan(T x) {
+  return __builtin_isnan(x);
+}
+
+#else
+
+#define isfinite(x) __builtin_isfinite(x)
+#define isinf(x) __builtin_isinf(x)
+#define isnan(x) __builtin_isnan(x)
+
+#endif
+
 #endif // LLVM_LIBC_MACROS_MATH_MACROS_H



More information about the libc-commits mailing list