https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113160
Bug ID: 113160 Summary: Const valarray (g)slice and indirect_array fail to match valarray in template functions Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: yihuajack at gmail dot com Target Milestone: --- Created attachment 56957 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56957&action=edit Output GCC version: 13.2.0, etc. System type: MinGW-w64 3.4.10.x86_64, etc. Options: -std=c++23, etc. Command line: g++ -std=c++23 -save-temps test2.cpp Outputs are attached. Reproducer: #include <iostream> #include <valarray> template<typename T> void foo(const std::valarray<T> &va) { std::cout << va[0] << '\n'; } int main() { const std::valarray<bool> vmask = {1, 0, 0, 1}; const std::valarray<std::size_t> vind = {1, 3}; const std::valarray<double> va = {1, 2, 3, 4}; foo(va[std::slice(1, 2, 1)]); foo(va[std::gslice(0, {1, 1}, {1, 1})]); foo(va[vmask]); foo(va[vind]); } The code can be successfully compiled by MSVC v19.38.33130 and v19.latest for x86/x64 but failed to be compiled by GCC 13.2.0 or trunk. If function foo() is not a template function, i.e., void foo(const std::valarray<double> &va) { std::cout << va[0] << '\n'; } Then the code compiles. If the valarray is not const, then it returns a std::valarray, std::gslice_array, std::mask_array, or std::indirect_array, which makes no dissent - the compiler refuses to match std::valarray with it. However, this is not the case for a const valarray. According to the Working Draft, Standard for Programming Language C++ (N4950): Any function returning a valarray is permitted to return an object of another type, provided all the const member functions of valarray are also applicable to this type. This return type shall not add more than two levels of template nesting over the most deeply nested argument type. 4 Implementations introducing such replacement types shall provide additional functions and operators as follows: (4.1) — for every function taking a const valarray& other than begin and end (28.6.10), identical functions taking the replacement types shall be added; (4.2) — for every function taking two const valarray& arguments, identical functions taking every combi- nation of const valarray& and replacement types shall be added. For libstdc++, the replacement types (mask_array is an exception - the operator function directly returns a valarray, so it compiles) are _Expr<_SClos<_ValArray, _Tp>, _Tp> _Expr<_GClos<_ValArray, _Tp>, _Tp> _Expr<_IClos<_ValArray, _Tp>, _Tp> which refuse to match const std::valarray<T> &, which might be a violation of the C++ standard.