llvm-project
llvm-project copied to clipboard
Inconsistent results for `__is_trivially_relocatable` between Clang and Apple Clang
Testcase from Qt:
#include <type_traits>
template <typename T>
inline constexpr bool qIsRelocatable = (std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>)
#if defined(__has_builtin)
#if __has_builtin(__is_trivially_relocatable)
|| __is_trivially_relocatable(T)
#endif
#endif
;
struct Complex2
{
Complex2(Complex2 &&);
};
static_assert(!qIsRelocatable<Complex2>);
This works for clang 15.0.0→18.1.0, but the static_assert fails for Apple clang version 15.0.0 (clang-1500.0.40.1).
Could someone confirm that this is Apple clang's fault? A class with a user-defined special member (case in point, not even trivially copyable) and which is not marked in any way (e.g. with [[clang::trivial_abi]]) should not be detected as trivially relocatalble.
@llvm/issue-subscribers-clang-frontend
Author: Giuseppe D'Angelo (dangelog)
#include <type_traits>
template <typename T>
inline constexpr bool qIsRelocatable = (std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>)
#if defined(__has_builtin)
#if __has_builtin(__is_trivially_relocatable)
|| __is_trivially_relocatable(T)
#endif
#endif
;
struct Complex2
{
Complex2(Complex2 &&);
};
static_assert(!qIsRelocatable<Complex2>);
This works for clang 15.0.0→18.1.0, but the static_assert fails for Apple clang version 15.0.0 (clang-1500.0.40.1).
Could someone confirm that this is Apple clang's fault? A class with a user-defined special member (case in point, not even trivially copyable) and which is not marked in any way (e.g. with [[clang::trivial_abi]]) should not be detected as trivially relocatalble.
I don't see this one clang trunk or any other version: https://godbolt.org/z/EM1ododMv
CC @Bigcheese @ldionne
@dangelog Is __is_trivially_relocatable being used on your version of AppleClang? IOW are you able to reduce to something that doesn't have these ifdefs?
Sure, if you want a minimal testcase:
struct S { S(S &&); };
static_assert(__has_builtin(__is_trivially_relocatable));
static_assert(!__is_trivially_relocatable(S));
This passes on Clang 18, passes on XCode 14, but fails on XCode 15 (clang-1500.0.40.1) with:
a.cpp:3:1: error: static assertion failed due to requirement '!__is_trivially_relocatable(S)'
I tried various versions of Apple Clang. The reproducer I used was exactly this:
$ clang++ --version
$ cat <<EOF | clang++ -xc++ - -fsyntax-only -std=c++20
struct S { S(S &&); };
static_assert(__has_builtin(__is_trivially_relocatable), "");
static_assert(!__is_trivially_relocatable(S), "");
EOF
| Xcode version | AppleClang version | Has the builtin? | S is trivially relocatable? |
|---|---|---|---|
14.0.1 |
Apple clang version 14.0.0 (clang-1400.0.29.102) |
❌ | n/a |
14.3.1 |
Apple clang version 14.0.3 (clang-1403.0.22.14.1) |
❌ | n/a |
15.0.1 |
Apple clang version 15.0.0 (clang-1500.0.40.1) |
✅ | yes |
15.3 |
Apple clang version 15.0.0 (clang-1500.3.9.4) |
✅ | yes |
However, LLVM Clang seems to agree that S is not trivially relocatable in all versions: https://godbolt.org/z/csfxPvTY6
So.. this looks like an AppleClang specific issue to me. I don't know what's different in Clang and AppleClang that causes this, I looked around a bit but couldn't find anything yet. Filed rdar://125426656 internally, stay tuned.