Skip to content

[flang] Fix POSIX.1/XPG checks in intrinsics-library.cpp - #201072

Merged
rorth merged 4 commits into
llvm:mainfrom
rorth:flang-_posix-xopen_version
Jul 30, 2026
Merged

[flang] Fix POSIX.1/XPG checks in intrinsics-library.cpp#201072
rorth merged 4 commits into
llvm:mainfrom
rorth:flang-_posix-xopen_version

Conversation

@rorth

@rorth rorth commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

PR #201063 breaks the flang build on Solaris:

flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '__float128 (__float128)'
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '_Complex __float128 (_Complex __float128)'

There are two problems here:

  • The __float128 support in intrinsics-library.cpp is guarded by the POSIX.1 >= 2001/XPG >= 6 check, but only depends on HAVE_QUADMATHLIB.
  • That check is done incorrectly: it tests for _POSIX_C_SOURCE >= 200112L or _XOPEN_SOURCE >= 600, which are no longer defined on Solaris after the PR above. This check is due a misunderstanding of those feature test macros: as detailed in The Open Group Base Specifications Issue 8, 2.2.1 POSIX.1 Symbols, those macros are expected to be defined by the user to ensure that the features introduced by a particular version of POSIX.1 or XPG are enabled, and only be checked by system headers. To test if they actually are supported, the values of _POSIX_VERSION or _XOPEN_VERSION need to be checked instead, as explained in 2.1.3.1 POSIX System Interfaces. The feature test macros being defined by the system headers is a non-portable glibc/AIX extension, it seems.
    If the XPG6 features required for flang are present by default in a compilation environment, _POSIX_VERSION or _XOPEN_VERSION will be defined to the required values even without defining _POSIX_C_SOURCE or _XOPEN_SOURCE.

Tested on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu.

PR llvm#201063 breaks the `flang` build on Solaris:

```
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '__float128 (__float128)'
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '_Complex __float128 (_Complex __float128)'

```

The problem is that the `__float128` support in `intrinsics-library.cpp` is
guarded incorrectly: it tests for `_POSIX_C_SOURCE >= 200112L` or
`_XOPEN_SOURCE >= 600`, which are no longer defined on Solaris after the PR
above.  This check is due a misunderstanding of those feature test macros:
as detailed in [The Open Group Base Specifications Issue 8, 2.2.1 POSIX.1
Symbols](https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html),
those macros are expected to be **defined** by the user to ensure that the
features introduced by a particular version of POSIX.1 or XPG are enabled.
To test if they actually are supported, the values of `_POSIX_VERSION` or
`_XOPEN_VERSION` need to be checked instead, as explained in [2.1.3.1 POSIX
System
Interfaces](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap02.html).

If the XPG6 features required for `flang` are present by default in a
compilation environment, `_POSIX_VERSION` or `_XOPEN_VERSION` will be
defined to the required values even without defining `_POSIX_C_SOURCE` or
`_XOPEN_SOURCE`.

Tested on `amd64-pc-solaris2.11`, `sparcv9-sun-solaris2.11`, and
`x86_64-pc-linux-gnu`.
@llvmorg-github-actions llvmorg-github-actions Bot added flang Flang issues not falling into any other category flang:semantics labels Jun 2, 2026
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-flang-semantics

Author: Rainer Orth (rorth)

Changes

PR #201063 breaks the flang build on Solaris:

flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '__float128 (__float128)'
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '_Complex __float128 (_Complex __float128)'

The problem is that the __float128 support in intrinsics-library.cpp is guarded incorrectly: it tests for _POSIX_C_SOURCE >= 200112L or _XOPEN_SOURCE >= 600, which are no longer defined on Solaris after the PR above. This check is due a misunderstanding of those feature test macros: as detailed in The Open Group Base Specifications Issue 8, 2.2.1 POSIX.1 Symbols, those macros are expected to be defined by the user to ensure that the features introduced by a particular version of POSIX.1 or XPG are enabled. To test if they actually are supported, the values of _POSIX_VERSION or _XOPEN_VERSION need to be checked instead, as explained in 2.1.3.1 POSIX System
Interfaces
.

If the XPG6 features required for flang are present by default in a compilation environment, _POSIX_VERSION or _XOPEN_VERSION will be defined to the required values even without defining _POSIX_C_SOURCE or _XOPEN_SOURCE.

Tested on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu.


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

1 Files Affected:

  • (modified) flang/lib/Evaluate/intrinsics-library.cpp (+2-2)
diff --git a/flang/lib/Evaluate/intrinsics-library.cpp b/flang/lib/Evaluate/intrinsics-library.cpp
index 54726ac539d60..68d47d2c248b3 100644
--- a/flang/lib/Evaluate/intrinsics-library.cpp
+++ b/flang/lib/Evaluate/intrinsics-library.cpp
@@ -440,7 +440,7 @@ struct HostRuntimeLibrary<std::complex<double>, LibraryVersion::Libm> {
 //    clang libc++ (ok in GNU libstdc++). Instead, the Posix libm
 //    extensions are used when available below.
 
-#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
+#if _POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600
 /// Define libm extensions
 /// Bessel functions are defined in POSIX.1-2001.
 
@@ -557,7 +557,7 @@ struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
   static_assert(map.Verify(), "map must be sorted");
 };
 #endif // HAS_FLOAT80 || HAS_LDBL128
-#endif //_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
+#endif //_POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600
 
 #ifdef _WIN32
 template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 5011 tests passed
  • 135 tests skipped

✅ The build succeeded and all tests passed.

@eugeneepshteyn

Copy link
Copy Markdown
Contributor

@rorth , I assume you are looking at the CI failure, because it shows the exact problem the original code was trying to guard against...

@rorth

rorth commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@rorth , I assume you are looking at the CI failure, because it shows the exact problem the original code was trying to guard against...

Sure. However, I didn't see them when testing on x86_64-pc-linux-gnu (Ubuntu 24.04). I suspect this is exactly as I described: to be certain to access POSIX.1/XPG6 features, you need to define _POSIX_C_SOURCE/_XOPEN_SOURCE before including the affected headers.

Alternatively, one could simply move the part guarded by HAS_QUADMATHLIB out of the current _POSIX_C_SOURCE/_XOPEN_SOURCE guard: AFAICS the two are unrelated.

However, to really investigate I need to know how exactly that CI build is run. Otherwise, it would be impossible to reproduce.

@rorth

rorth commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

At least checking both the *_SOURCE and *_VERSION macros makes the CI happy...

@kkwli

kkwli commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Build successfully on AIX. Thanks

@rorth

rorth commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

This is still an issue and breaks building LLVM 23.1.0 rc1. What about the revised version?

@dyung dyung moved this from Needs Triage to Needs Fix in LLVM Release Status Jul 18, 2026
@tru

tru commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

@MaskRay @jeanPerier @vdonaldson This still seems to be an issue for @rorth, with no review activity in about 7 weeks. Could one of you take a look?

// extensions are used when available below.

#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
#if _POSIX_C_SOURCE >= 200112L || _POSIX_VERSION >= 200112L || \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file doesn't include unistd.h, _POSIX_VERSION and _XOPEN_VERSION feel dead to me.

@rorth

rorth commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

You're right about the <unistd.h> part. However, let's take two steps back: I think I now seen what's wrong. Assume for the moment that the guards above are meant to check if POSIX.1 >= 2001.1 or XPG >= 6 are available. Just take the guards and the instances of HostRuntimeLibrary within, indented to see the structure:

#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
  #if !defined(_AIX) && !defined(__APPLE__)
  template <> struct HostRuntimeLibrary<float, LibraryVersion::LibmExtensions> {
  #endif
  #if HAS_QUADMATHLIB
  template <> struct HostRuntimeLibrary<__float128, LibraryVersion::Libm> {
  template <> struct HostRuntimeLibrary<__complex128, LibraryVersion::Libm> {
  #endif
  template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
  #if defined(__GLIBC__) && (HAS_FLOAT80 || HAS_LDBL128)
  struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
  #endif // HAS_FLOAT80 || HAS_LDBL128
#endif //_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
#ifdef _WIN32
template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
#endif

There's a mixture of HostRuntimeLibrary<..., LibraryVersion::LibmExtensions> and HostRuntimeLibrary<..., LibraryVersion::Libm> inside the POSIX.1/XPG guard. However, the LibraryVersion::Libm ones are completely unrelated to POSIX.1/XPG, but always present if HAS_QUADMATHLIB.

If you change the structure to

#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
  #if !defined(_AIX) && !defined(__APPLE__)
  template <> struct HostRuntimeLibrary<float, LibraryVersion::LibmExtensions> {
  #endif
  template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
  #if defined(__GLIBC__) && (HAS_FLOAT80 || HAS_LDBL128)
  struct HostRuntimeLibrary<long double, LibraryVersion::LibmExtensions> {
  #endif // HAS_FLOAT80 || HAS_LDBL128
#endif //_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
#ifdef _WIN32
template <> struct HostRuntimeLibrary<double, LibraryVersion::LibmExtensions> {
#endif
#if HAS_QUADMATHLIB
template <> struct HostRuntimeLibrary<__float128, LibraryVersion::Libm> {
template <> struct HostRuntimeLibrary<__complex128, LibraryVersion::Libm> {
#endif

the compile failures observed when POSIX.1-2001/XPG6 is (incorrectly) assumed to be missing are gone.

Let's get to the actual POSIX.1/XPG guards now. Consider a (modified) version of the ftm.c example from Linux feature_test_macros(7), stripped down to only include POSIX.1/XPG macros, but including _POSIX_VERSION and _XOPEN_VERSION:

/* ftm.c */

#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
#ifdef _POSIX_SOURCE
    printf("_POSIX_SOURCE defined\n");
#endif

#ifdef _POSIX_C_SOURCE
    printf("_POSIX_C_SOURCE defined: %jdL\n",
            (intmax_t) _POSIX_C_SOURCE);
#endif

#ifdef _POSIX_VERSION
    printf("_POSIX_VERSION defined: %jdL\n",
            (intmax_t) _POSIX_VERSION);
#endif

#ifdef _XOPEN_SOURCE
    printf("_XOPEN_SOURCE defined: %d\n", _XOPEN_SOURCE);
#endif

#ifdef _XOPEN_VERSION
    printf("_XOPEN_VERSION defined: %d\n", _XOPEN_VERSION);
#endif

    exit(EXIT_SUCCESS);
}

If you build this with gcc -o ftm ftm.c on various targets, you get:

  • Linux (Ubuntu 24.04):
 _POSIX_SOURCE defined
 _POSIX_C_SOURCE defined: 200809L
 _POSIX_VERSION defined: 200809L
 _XOPEN_VERSION defined: 700
  • Solaris 11.4:
_POSIX_VERSION defined: 200809L
_XOPEN_VERSION defined: 700
  • FreeBSD 15.1:
_POSIX_VERSION defined: 200809L
  • NetBSD 10.1:
_POSIX_VERSION defined: 200112L
  • macOS 26:
_POSIX_VERSION defined: 200112L
_XOPEN_VERSION defined: 600
  • AIX 7.3:
_POSIX_SOURCE defined
_POSIX_C_SOURCE defined: 200809L
_POSIX_VERSION defined: 200809L
_XOPEN_SOURCE defined: 700
_XOPEN_VERSION defined: 700

As you can see, the system headers predefining the feature test macros themselves rather than their _*_VERSION counterparts is primarily a glibc (and AIX) extension. I suspect this doesn't violate POSIX.1/XPG, but certainly isn't the intended use. Therefore including <unistd.h> and switching the guard to _POSIX_VERSION >= 200112L || _XOPEN_VERSION >= 600 should work as intended everywhere.

I've got a patch doing just this, so far only lightly tested on Solaris and Linux. If we can agree this is the direction to take, I'll test it some more on both Darwin and AIX, unless someone else who has development environments on those readily available beats me to it.

I could go on about properly guarding the various versions of the bessel functions, some of them in XPG6, others mere extensions on all sorts of platforms, but for the moment I'm primarily concerned about fixing the Solaris compile failure.

rorth added 2 commits July 30, 2026 09:30
Move quadmathlib code out of POSIX.1/XPG guard.
@rorth
rorth merged commit 3d94aeb into llvm:main Jul 30, 2026
12 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Fix to Done in LLVM Release Status Jul 30, 2026
@rorth

rorth commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

/cherry-pick 3d94aeb

@llvmbot

llvmbot commented Jul 30, 2026

Copy link
Copy Markdown
Member

/pull-request #213109

jgreenbaum pushed a commit to jgreenbaum/llvm-project that referenced this pull request Aug 3, 2026
PR llvm#201063 breaks the `flang` build on Solaris:

```
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '__float128 (__float128)'
flang/lib/Evaluate/intrinsics-library.cpp:225:26: error: address of overloaded function 'acos' does not match required type '_Complex __float128 (_Complex __float128)'

```

There are two problems here:
- The `__float128` support in `intrinsics-library.cpp` is guarded by the
POSIX.1 >= 2001/XPG >= 6 check, but only depends on `HAVE_QUADMATHLIB`.
- That check is done incorrectly: it tests for `_POSIX_C_SOURCE >=
200112L` or `_XOPEN_SOURCE >= 600`, which are no longer defined on
Solaris after the PR above. This check is due a misunderstanding of
those feature test macros: as detailed in [The Open Group Base
Specifications Issue 8, 2.2.1 POSIX.1
Symbols](https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html),
those macros are expected to be **defined** by the user to ensure that
the features introduced by a particular version of POSIX.1 or XPG are
enabled, and only be checked by system headers. To test if they actually
are supported, the values of `_POSIX_VERSION` or `_XOPEN_VERSION` need
to be checked instead, as explained in [2.1.3.1 POSIX System
Interfaces](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap02.html).
The feature test macros being defined by the system headers is a
non-portable glibc/AIX extension, it seems.
If the XPG6 features required for `flang` are present by default in a
compilation environment, `_POSIX_VERSION` or `_XOPEN_VERSION` will be
defined to the required values even without defining `_POSIX_C_SOURCE`
or `_XOPEN_SOURCE`.

Tested on `amd64-pc-solaris2.11`, `sparcv9-sun-solaris2.11`, and
`x86_64-pc-linux-gnu`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:codegen flang:semantics flang Flang issues not falling into any other category platform:solaris

Projects

Development

Successfully merging this pull request may close these issues.

7 participants