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: 5bc64b7d41
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57450
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
Reference in New Issue
Block a user