[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