Issue 76393
Summary [C++20] Problem parsing pipe syntax as valarray's operator|
Labels new issue
Assignees
Reporter yihuajack
    Reproducer:
```c++
#include <iostream>
#include <ranges>
#include <valarray>

int main() {
        std::valarray<double> va1 = {1, 2};
 std::valarray<double> va2 = {3, 4};
        for (const auto& elem : va1 * va2 | std::views::transform([](double x) {return x + 1;})) {
 std::cout << "- " << elem << '\n';
        }
}
```
This code can be successfully compiled by x64 Microsoft C/C++ compiler 19.38.33130 by `cl /EHsc /std:c++20 test.cpp`, but failed to be compiled by `clang++ -std=c++20 -stdlib=libc++ test.cpp`.
If writing `std::valarray<double> vprod = va1 * va2;` and
```c++
for (const auto& elem : vprod | std::views::transform([](double x) {return x + 1;}))
```
The code can also be successfully compiled by clang with libc++.
clang version 17.0.6 to trunk--20231226 produce this.
>[<source>:10:70: error: invalid operands to binary _expression_ ('__val_expr<_BinaryOp<multiplies<typename valarray<double>::value_type>, valarray<double>, valarray<double>>>' (aka '__val_expr<_BinaryOp<multiplies<double>, std::valarray<double>, std::valarray<double>>>') and '__range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at <source>:10:94)>>>' (aka 'std::__range_adaptor_closure_t<std::__bind_back_t<std::ranges::views::__transform::__fn, std::tuple<(lambda at <source>:10:94)>>>'))](error: invalid operands to binary _expression_ ('__val_expr<_BinaryOp<multiplies<typename valarray<double>::value_type>, valarray<double>, valarray<double>>>' (aka '__val_expr<_BinaryOp<multiplies<double>, std::valarray<double>, std::valarray<double>>>') and '__range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at <source>:8:67)>>>' (aka 'std::__range_adaptor_closure_t<std::__bind_back_t<std::ranges::views::__transform::__fn, std::tuple<(lambda at <source>:8:67)>>>')))

According to [operator+,-,*,/,%,&,|,^,<<,>>,&&,|| (std::valarray)](https://en.cppreference.com/w/cpp/numeric/valarray/operator_arith3):
```c++
template< class T >
std::valarray<T> operator* ( const std::valarray<T>& lhs, const std::valarray<T>& rhs );
template< class T >
std::valarray<T> operator| ( const std::valarray<T>& lhs, const std::valarray<T>& rhs );
```
It seems that it is reasonable to parse the "|" as pipe syntax rather than valarray's operator|., evaluating `va1 * va2` as a `std::valarray`.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to