I do not know if clang++ would end up with analogous issues.
I happened to have started with g++15 for seeing if I could
build the std std.compat module from the source for doing so.
gcc got support for std.compat and std builds in 15.1 .

Note that I'm using a aarch64 context here and my lang/gcc15
has the recent patch that that has been committed to
lang/gcc15-devel that allows the toolchain to be built for
aarch64. (I doubt that use of lang/gcc15-devel would be any
different.)


# g++15 -std=c++23 -O2 -fmodules -fsearch-include-path -fmodule-only -c 
bits/std.cc
/usr/local/lib/gcc15/include/c++/bits/std.cc:3351:14: error: exporting 'int 
feclearexcept(int)' that does not have external linkage
 3351 |   using std::feclearexcept;
      |              ^~~~~~~~~~~~~
In file included from /usr/local/lib/gcc15/include/c++/fenv.h:41,
                 from /usr/local/lib/gcc15/include/c++/cfenv:43,
                 from 
/usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/stdc++.h:128,
                 from /usr/local/lib/gcc15/include/c++/bits/std.cc:30:
/usr/include/fenv.h:84:1: note: 'int feclearexcept(int)' declared here with 
internal linkage
   84 | feclearexcept(int __excepts)
      | ^~~~~~~~~~~~~
/usr/local/lib/gcc15/include/c++/bits/std.cc:3352:14: error: exporting 'int 
fegetenv(fenv_t*)' that does not have external linkage
 3352 |   using std::fegetenv;
      |              ^~~~~~~~
. . .

and so on for supporting building from (for example):

/usr/local/lib/gcc15/include/c++/bits/std.cc <http://std.cc/> :

. . .
// 28.3 <cfenv>
export C_LIB_NAMESPACE
{
#ifdef _GLIBCXX_USE_C99_FENV
  using std::feclearexcept;
  using std::fegetenv;
  using std::fegetexceptflag;
  using std::fegetround;
  using std::feholdexcept;
  using std::fenv_t;
  using std::feraiseexcept;
  using std::fesetenv;
  using std::fesetexceptflag;
  using std::fesetround;
  using std::fetestexcept;
  using std::feupdateenv;
  using std::fexcept_t;
#endif
}
. . .

g++15 has:

/usr/local/lib/gcc15/include/c++/cfenv :

. . .
#include <bits/c++config.h>

#if _GLIBCXX_HAVE_FENV_H
# include <fenv.h>
#endif
. . .

/usr/local/lib/gcc15/include/c++/fenv.h :

. . .
#include <bits/c++config.h>
#if _GLIBCXX_HAVE_FENV_H
# include_next <fenv.h>
#endif
. . .

/usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/c++config.h
does have:

/* Define to 1 if you have the <fenv.h> header file. */
#define _GLIBCXX_HAVE_FENV_H 1


FreeBSD's (main) /usr/include/fenv.h is using code like:

. . .
#ifndef __fenv_static
#define __fenv_static   static
#endif
. . .
__fenv_static __inline int
feclearexcept(int __excepts)
{
        fexcept_t __r;

        __mrs_fpsr(__r);
        __r &= ~__excepts;
        __msr_fpsr(__r);
        return (0);
}
. . .

that disallows setting up the exports in C++ modules.

FreeBSD has /usr/include/sys/cdefs.h :

. . .
#if defined(__STDC__) || defined(__cplusplus)
. . .
#if defined(__cplusplus)
#define __inline        inline          /* convert to C++ keyword */
#else
#if !(defined(__CC_SUPPORTS___INLINE))
#define __inline                        /* delete GCC keyword */
#endif /* ! __CC_SUPPORTS___INLINE */
#endif /* !__cplusplus */

#else   /* !(__STDC__ || __cplusplus) */
. . .


And FreeBSD has /usr/include/_ctype.h :

. . .
#include <sys/cdefs.h>
. . .
/*
 * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
 * to generate code for extern versions of all our inline functions.
 */
#ifdef _EXTERNALIZE_CTYPE_INLINES_
#define _USE_CTYPE_INLINE_
#define static
#define __inline
#endif
. . .


There is also:

/usr/include/arm/fenv.h :

. . .
#ifndef __fenv_static
#define __fenv_static   static
#endif
. . .
#ifndef __ARM_PCS_VFP

int feclearexcept(int __excepts);
. . .
#endif

#else   /* __ARM_PCS_VFP */

#define vmrs_fpscr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r))
#define vmsr_fpscr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r))

#define _FPU_MASK_SHIFT 8

__fenv_static inline int
feclearexcept(int __excepts)
{
        fexcept_t __fpsr;

        vmrs_fpscr(__fpsr);
        __fpsr &= ~__excepts;
        vmsr_fpscr(__fpsr);
        return (0);
}
. . .

Without __ARM_PCS_VFP involved, this would again end
up blocking the C++ exports in std and in std.compat .
It also does not use __inline but just inline.

===
Mark Millard
marklmi at yahoo.com


Reply via email to