Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 09 Jun 2026 11:27:55 +0000
From:      ShengYi Hung <aokblast@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 9c0489508695 - main - libc: Use slow path in fenv in C++
Message-ID:  <6a27f8bb.3257d.36b63bf9@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by aokblast:

URL: https://cgit.FreeBSD.org/src/commit/?id=9c0489508695fde3bdd742edfd1b4b681aab4d19

commit 9c0489508695fde3bdd742edfd1b4b681aab4d19
Author:     ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-06-04 08:58:28 +0000
Commit:     ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-06-09 11:25:30 +0000

    libc: Use slow path in fenv in C++
    
    C++ exposes cfenv functions via using ::func. Our name-mangling
    mechanism rewrites all function calls causing symbols such as
    std::feclearexcept to be transformed into std::__feclearexcept_int.
    Since no such function exists, compilation fails.
    
    The using ::feclearexpect declarations themselves are unaffected because
    they are not function calls, which further exposes the mismatch
    
    As a result, enable the fast path only for C and fall back to the slow
    path in C++.
    
    Reviewed by:    kib
    Fixes:          5bc64b7d417d
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D57450
---
 lib/msun/aarch64/fenv.h | 10 ++++++++++
 lib/msun/arm/fenv.h     | 10 ++++++++++
 lib/msun/powerpc/fenv.h | 12 ++++++++++++
 lib/msun/riscv/fenv.h   | 12 ++++++++++++
 lib/msun/x86/fenv.h     | 10 ++++++++++
 5 files changed, 54 insertions(+)

diff --git a/lib/msun/aarch64/fenv.h b/lib/msun/aarch64/fenv.h
index 5d47940cf9eb..aebcd99909ce 100644
--- a/lib/msun/aarch64/fenv.h
+++ b/lib/msun/aarch64/fenv.h
@@ -96,6 +96,15 @@ int feenableexcept(int);
 int fedisableexcept(int);
 int fegetexcept(void);
 
+/*
+ * C permits a standard library function to also be exposed as a function-like
+ * macro (C23 7.1.4), and msun uses that here to inline the fast path.  C++
+ * forbids it: <cfenv> imports these names into namespace std (using
+ * ::feclearexcept; etc.), so std::feclearexcept() and friends must denote the
+ * actual functions.  Expose the inlining macros to C only; C++ uses the real
+ * extern functions (defined in the matching lib/msun/<arch>/fenv.c).
+ */
+#ifndef __cplusplus
 #define	feclearexcept(a)	__feclearexcept_int(a)
 #define	fegetexceptflag(e, a)	__fegetexceptflag_int(e, a)
 #define	fesetexceptflag(e, a)	__fesetexceptflag_int(e, a)
@@ -110,6 +119,7 @@ int fegetexcept(void);
 #define	feenableexcept(a)	__feenableexcept_int(a)
 #define	fedisableexcept(a)	__fedisableexcept_int(a)
 #define	fegetexcept()		__fegetexcept_int()
+#endif /* !__cplusplus */
 
 __fenv_static inline int
 __feclearexcept_int(int __excepts)
diff --git a/lib/msun/arm/fenv.h b/lib/msun/arm/fenv.h
index 78ca9ef0f589..6febbf95008d 100644
--- a/lib/msun/arm/fenv.h
+++ b/lib/msun/arm/fenv.h
@@ -129,6 +129,15 @@ int fedisableexcept(int);
 int fegetexcept(void);
 #endif
 
+/*
+ * C permits a standard library function to also be exposed as a function-like
+ * macro (C23 7.1.4), and msun uses that here to inline the fast path.  C++
+ * forbids it: <cfenv> imports these names into namespace std (using
+ * ::feclearexcept; etc.), so std::feclearexcept() and friends must denote the
+ * actual functions.  Expose the inlining macros to C only; C++ uses the real
+ * extern functions (defined in the matching lib/msun/<arch>/fenv.c).
+ */
+#ifndef __cplusplus
 #define	feclearexcept(a)	__feclearexcept_int(a)
 #define	fegetexceptflag(e, a)	__fegetexceptflag_int(e, a)
 #define	fesetexceptflag(e, a)	__fesetexceptflag_int(e, a)
@@ -145,6 +154,7 @@ int fegetexcept(void);
 #define	fedisableexcept(a)	__fedisableexcept_int(a)
 #define	fegetexcept()		__fegetexcept_int()
 #endif
+#endif /* !__cplusplus */
 
 __fenv_static inline int
 __feclearexcept_int(int __excepts)
diff --git a/lib/msun/powerpc/fenv.h b/lib/msun/powerpc/fenv.h
index f6fb354470c7..8752be09994c 100644
--- a/lib/msun/powerpc/fenv.h
+++ b/lib/msun/powerpc/fenv.h
@@ -123,6 +123,15 @@ int feholdexcept(fenv_t *);
 int fesetenv(const fenv_t *);
 int feupdateenv(const fenv_t *);
 
+/*
+ * C permits a standard library function to also be exposed as a function-like
+ * macro (C23 7.1.4), and msun uses that here to inline the fast path.  C++
+ * forbids it: <cfenv> imports these names into namespace std (using
+ * ::feclearexcept; etc.), so std::feclearexcept() and friends must denote the
+ * actual functions.  Expose the inlining macros to C only; C++ uses the real
+ * extern functions (defined in the matching lib/msun/<arch>/fenv.c).
+ */
+#ifndef __cplusplus
 #define	feclearexcept(a)	__feclearexcept_int(a)
 #define	fegetexceptflag(e, a)	__fegetexceptflag_int(e, a)
 #define	fesetexceptflag(e, a)	__fesetexceptflag_int(e, a)
@@ -134,6 +143,7 @@ int feupdateenv(const fenv_t *);
 #define	feholdexcept(e)		__feholdexcept_int(e)
 #define	fesetenv(e)		__fesetenv_int(e)
 #define	feupdateenv(e)		__feupdateenv_int(e)
+#endif /* !__cplusplus */
 
 __fenv_static inline int
 __feclearexcept_int(int __excepts)
@@ -266,8 +276,10 @@ __feupdateenv_int(const fenv_t *__envp)
 int feenableexcept(int);
 int fedisableexcept(int);
 
+#ifndef __cplusplus	/* see the note above; C++ uses the real functions */
 #define	feenableexcept(a)	__feenableexcept_int(a)
 #define	fedisableexcept(a)	__fedisableexcept_int(a)
+#endif
 
 __fenv_static inline int
 __feenableexcept_int(int __mask)
diff --git a/lib/msun/riscv/fenv.h b/lib/msun/riscv/fenv.h
index 1059744941f3..199ca1806684 100644
--- a/lib/msun/riscv/fenv.h
+++ b/lib/msun/riscv/fenv.h
@@ -91,6 +91,15 @@ int feholdexcept(fenv_t *);
 int fesetenv(const fenv_t *);
 int feupdateenv(const fenv_t *);
 
+/*
+ * C permits a standard library function to also be exposed as a function-like
+ * macro (C23 7.1.4), and msun uses that here to inline the fast path.  C++
+ * forbids it: <cfenv> imports these names into namespace std (using
+ * ::feclearexcept; etc.), so std::feclearexcept() and friends must denote the
+ * actual functions.  Expose the inlining macros to C only; C++ uses the real
+ * extern functions (defined in the matching lib/msun/<arch>/fenv.c).
+ */
+#ifndef __cplusplus
 #define	feclearexcept(a)	__feclearexcept_int(a)
 #define	fegetexceptflag(e, a)	__fegetexceptflag_int(e, a)
 #define	fesetexceptflag(e, a)	__fesetexceptflag_int(e, a)
@@ -102,6 +111,7 @@ int feupdateenv(const fenv_t *);
 #define	feholdexcept(e)		__feholdexcept_int(e)
 #define	fesetenv(e)		__fesetenv_int(e)
 #define	feupdateenv(e)		__feupdateenv_int(e)
+#endif /* !__cplusplus */
 
 __fenv_static inline int
 __feclearexcept_int(int __excepts)
@@ -224,8 +234,10 @@ __feupdateenv_int(const fenv_t *__envp)
 int feenableexcept(int);
 int fedisableexcept(int);
 
+#ifndef __cplusplus	/* see the note above; C++ uses the real functions */
 #define	feenableexcept(a)	__feenableexcept_int(a)
 #define	fedisableexcept(a)	__fedisableexcept_int(a)
+#endif
 
 __fenv_static inline int
 __feenableexcept_int(int __mask __unused)
diff --git a/lib/msun/x86/fenv.h b/lib/msun/x86/fenv.h
index b5da37902083..cb44624a858a 100644
--- a/lib/msun/x86/fenv.h
+++ b/lib/msun/x86/fenv.h
@@ -150,12 +150,22 @@ int fesetround(int);
 int fegetround(void);
 int fesetenv(const fenv_t *);
 
+/*
+ * C permits a standard library function to also be exposed as a function-like
+ * macro (C23 7.1.4), and msun uses that here to inline the fast path.  C++
+ * forbids it: <cfenv> imports these names into namespace std (using
+ * ::feclearexcept; etc.), so std::feclearexcept() and friends must denote the
+ * actual functions.  Expose the inlining macros to C only; C++ uses the real
+ * extern functions (defined in the matching lib/msun/<arch>/fenv.c).
+ */
+#ifndef __cplusplus
 #define	feclearexcept(a)	__feclearexcept_int(a)
 #define	fegetexceptflag(e, a)	__fegetexceptflag_int(e, a)
 #define	fetestexcept(a)		__fetestexcept_int(a)
 #define	fesetround(a)		__fesetround_int(a)
 #define	fegetround()		__fegetround_int()
 #define	fesetenv(a)		__fesetenv_int(a)
+#endif /* !__cplusplus */
 
 #ifdef __i386__
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a27f8bb.3257d.36b63bf9>