Description
Testing the Stan math library against clang 19.0.1 we found that one of libc++'s complex pow signatures is overriding one of our signatures. stan-dev/math#3106
We can fix this by making the exponent's type const&
, or by users calling stan::math::pow
fully instead of bringing pow
into the local scope. But I wanted to suggest a fix here that I think will stop this issue from coming up for other users.
In the pow
signatures for a complex base and arithmetic exponent, such as the one below from complex, if a user has a custom type in complex
this signature will be chosen by the compiler but then fail while calling __promote
template <class _Tp, class _Up, __enable_if_t<is_arithmetic<_Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) {
typedef complex<typename __promote<_Tp, _Up>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
This signature only checks that Up_
is arithmetic while the compiler is looking for candidates, but then after that signature has been chosen it also requires that _Tp
is arithmetic since __promote<_Tp, _Up>
will throw a compiler error from it's static assert if both types are not arithmetic (code). It looks like the signature should be checking that __promote<_Tp, _Up>
is arithmetic so that users with custom types can add their own pow
functions with custom complex types.
This could be fixed by adding another NTTP to these functions that checks if the result of __promote
is valid.
template <class _Tp, class _Up,
__enable_if_t<is_arithmetic<_Up>::value, int> = 0,
__enable_if_t<is_arithmetic_promotable<_Tp, _Up>::value, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI complex<typename __promote<_Tp, _Up>::type> pow(const complex<_Tp>& __x, const _Up& __y) {
typedef complex<typename __promote<_Tp, _Up>::type> result_type;
return std::pow(result_type(__x), result_type(__y));
}
The example of the fix and issue can be found in the godbolt below. You can toggle the SHOW_ERROR
macro on and off to see the current error and suggested fix