-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Closed
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationAnything related to constant evaluation
Description
For example:
static_assert(__imag(5.0j / 0) == __builtin_inf());
https://godbolt.org/z/59fqKv4Kc
This works without any diagnostics in Clang, but errors out in gcc.
There are actually a few tests in tests/SemaCXX/complex-folding.cpp
that rely on this behavior, although they aren't as obvious as the example above:
llvm-project/clang/test/SemaCXX/complex-folding.cpp
Lines 60 to 99 in d02d8df
// Test that infinities are preserved, don't turn into NaNs, and do form zeros | |
// when the divisor. | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * 1.0)) == 1); | |
static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + __builtin_inf() * 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == -1); | |
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) * (1.0 + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); | |
static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + __builtin_inf() * 1.0j) * (1.0 + __builtin_inf() * 1.0j))) == -1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + __builtin_inf() * 1.0j) * (__builtin_inf() + __builtin_inf() * 1.0j))) == -1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (1.0 + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (1.0 + 1.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 1.0)) == 1); | |
static_assert(__builtin_isinf_sign(__imag__(1.0 + (__builtin_inf() * 1.0j) / 1.0)) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 1.0)) == 1); | |
static_assert(((1.0 + 1.0j) / (__builtin_inf() + 1.0j)) == (0.0 + 0.0j)); | |
static_assert(((1.0 + 1.0j) / (1.0 + __builtin_inf() * 1.0j)) == (0.0 + 0.0j)); | |
static_assert(((1.0 + 1.0j) / (__builtin_inf() + __builtin_inf() * 1.0j)) == (0.0 + 0.0j)); | |
static_assert(((1.0 + 1.0j) / __builtin_inf()) == (0.0 + 0.0j)); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (0.0 + 0.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / (0.0 + 0.0j))) == 1); | |
static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / 0.0)) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((1.0 + __builtin_inf() * 1.0j) / 0.0)) == 1); | |
static_assert(__builtin_isinf_sign(__imag__((__builtin_inf() + __builtin_inf() * 1.0j) / 0.0)) == 1); |
In this example:
constexpr _Complex double D1 = {0.0, 0.0};
constexpr double D2 = __real(__builtin_inf() * D1);
static_assert(D2 == 1);
constexpr double D3 = __builtin_inf() * 0.0;
https://godbolt.org/z/dPME9To8d
(which is adapted and simplified from the test above), multiplying inf
with 0
produces a nan
, which is properly diagnosed when evaluating the initializer for D3
, but not at al when evaluating D2
. The static_assert
proves that D2 is indeed nan
.
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationAnything related to constant evaluation