Skip to content

[libc] Make math-macros.h C++-friendly #86206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2024
Merged

Conversation

frobtech
Copy link
Contributor

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.

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`.
@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2024

@llvm/pr-subscribers-libc

Author: Roland McGrath (frobtech)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/86206.diff

1 Files Affected:

  • (modified) libc/include/llvm-libc-macros/math-macros.h (+28-4)
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

@lntue lntue merged commit c56211b into llvm:main Mar 21, 2024
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
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`.
@philnik777
Copy link
Contributor

This patch is actually really problematic for interoperability with C++ standard libraries and the implementation is non-conforming in C++, because it doesn't satisfy http://eel.is/c++draft/c.math#cmath.syn-3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants