diff --git a/libcxx/include/complex b/libcxx/include/complex --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -881,6 +881,45 @@ __d = scalbn(__d, -__ilogbw); } } + if (__libcpp_is_constant_evaluated()) { + bool __z_zero = __a == _Tp(0) && __b == _Tp(0); + bool __w_zero = __c == _Tp(0) && __d == _Tp(0); + bool __z_inf = __libcpp_isinf_or_builtin(__a) || __libcpp_isinf_or_builtin(__b); + bool __w_inf = __libcpp_isinf_or_builtin(__c) || __libcpp_isinf_or_builtin(__d); + bool __z_nan = !__z_inf && ( + (__libcpp_isnan_or_builtin(__a) && __libcpp_isnan_or_builtin(__b)) + || (__libcpp_isnan_or_builtin(__a) && __b == _Tp(0)) + || (__a == _Tp(0) && __libcpp_isnan_or_builtin(__b)) + ); + bool __w_nan = !__w_inf && ( + (__libcpp_isnan_or_builtin(__c) && __libcpp_isnan_or_builtin(__d)) + || (__libcpp_isnan_or_builtin(__c) && __d == _Tp(0)) + || (__c == _Tp(0) && __libcpp_isnan_or_builtin(__d)) + ); + if ((__z_nan || __w_nan) || (__z_inf && __w_inf)) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + bool __z_nonzero_nan = !__z_inf && !__z_nan && (__libcpp_isnan_or_builtin(__a) || __libcpp_isnan_or_builtin(__b)); + bool __w_nonzero_nan = !__w_inf && !__w_nan && (__libcpp_isnan_or_builtin(__c) || __libcpp_isnan_or_builtin(__d)); + if (__z_nonzero_nan || __w_nonzero_nan) { + if (__w_zero) { + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + if (__w_inf) { + return complex<_Tp>(_Tp(0), _Tp(0)); + } + if (__z_inf) { + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + if (__w_zero) { + if (__z_zero) { + return complex<_Tp>(_Tp(NAN), _Tp(0)); + } + return complex<_Tp>(_Tp(INFINITY), _Tp(INFINITY)); + } + } _Tp __denom = __c * __c + __d * __d; _Tp __x{}; _Tp __y{};