ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.06k stars 437 forks source link

`clang++` with MSVC's toolchain fails to compile Range-V3 `v0.12.0` test `test.action.adjacent_remove_if` #1721

Open Klaim opened 1 year ago

Klaim commented 1 year ago

Context

This was found while making the build2 package of range-V3 v0.12.0.

By default, if you try to build with clang++ or clang on Windows, build2 will use the clang++ driver, not the clang-cl driver with the toolchain provided by the most up-to-date version of Visual Studio installed. The rational for this is explained in details in the build-system manual.

Therefore this setup is not currently tested by the CI of range-V3, but we can see it when using build2 with clang and range-v3.

This issue doesnt prevent us to publish the package (which is already available and can be updated if necessary) as we don't enable this specific context to be checked by the CI, as a workaround.

Clang version I used:

$ clang --version
clang version 14.0.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

cl toolchain version I used:

> cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.33.31517 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

Cannot reproduce with clang on linux or macos.

I'm using git-bash on Windows which is why the following looks like bash.

How To Reproduce

I only tried with build2 for now, but I suspect the issue is independent.

  1. Use clang++ with the toolchain (linker etc.) from a recent Visual Studio installation.
  2. Use -std=c++2a
  3. Compile the tests, in particular test.action.adjacent_remove_if.

Here is the command line (from build2) that reproduces the issue (note that build2 first generates the pre-processed files before proceeding to the actual compilation, which is why there is more than one compiler invocation):

clang++ -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -std=c++2a -finput-charset=UTF-8 -D_MT -D_DLL -w -x c++ -MQ ^ -MD -E -frewrite-includes -MF - -o E:\projects\build2-packaging\range-v3\build-clang\range-v3\upstream\test\action\adjacent_remove_if.exe.obj.ii E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp
clang++ -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -std=c++2a -finput-charset=UTF-8 -D_MT -D_DLL -E -x c++ E:\projects\build2-packaging\range-v3\build-clang\range-v3\upstream\test\action\adjacent_remove_if.exe.obj.ii
clang++ -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include/std -IE:\projects\build2-packaging\range-v3\range-v3/upstream/include -IE:\projects\build2-packaging\range-v3\build-clang\range-v3/upstream/include -std=c++2a -finput-charset=UTF-8 -Xclang -fexternc-nounwind -D_MT -D_DLL -o ..\build-clang\range-v3\upstream\test\action\adjacent_remove_if.exe.obj -c -x c++ E:\projects\build2-packaging\range-v3\build-clang\range-v3\upstream\test\action\adjacent_remove_if.exe.obj.ii

(here I removed all the warnings as they are not impacting the issue, the complete report below does use the warnings, without change in output)

Observed

In file included from E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp:14:
E:\projects\build2-packaging\range-v3\range-v3/upstream/include\range/v3/action/adjacent_remove_if.hpp:55:17: error: no matching      
      function for call to object of type 'const adl_erase_detail::erase_fn'
                erase(rng, std::move(i), end(rng));
                ^~~~~
E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp:26:44: note: in instantiation of function  
      template specialization 'ranges::actions::adjacent_remove_if_fn::operator()<std::vector<int> &, (lambda at
      E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp:26:48), ranges::identity>' requested 
      here
    auto & v2 = actions::adjacent_remove_if(v, [](int x, int y){ return (x + y) % 3 == 0; });
                                           ^
E:\projects\build2-packaging\range-v3\range-v3/upstream/include\range/v3/action/erase.hpp:44:18: note: candidate template ignored:    
      substitution failure [with Rng = std::vector<int> &, I = std::vector<int>, S =
      std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>]: no matching function for call to 'erase'
            auto operator()(Rng && rng, I first, S last) const
                 ^
In file included from E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp:14:
E:\projects\build2-packaging\range-v3\range-v3/upstream/include\range/v3/action/adjacent_remove_if.hpp:55:17: error: no matching      
      function for call to object of type 'const adl_erase_detail::erase_fn'
                erase(rng, std::move(i), end(rng));
                ^~~~~
E:\projects\build2-packaging\range-v3\range-v3/upstream/include\range/v3/functional/invoke.hpp:142:20: note: in instantiation of      
      function template specialization 'ranges::actions::adjacent_remove_if_fn::operator()<std::vector<int> &, (lambda at
      E:\projects\build2-packaging\range-v3\range-v3\upstream\test\action\adjacent_remove_if.cpp:30:38), ranges::identity>' requested 
      here
            return ((F&&) f)((Args&&) args...);
                   ^
E:\projects\build2-packaging\range-v3\range-v3/upstream/include\range/v3/action/erase.hpp:44:18: note: candidate template ignored:    
      substitution failure [with Rng = std::vector<int> &, I = std::vector<int>, S =
      std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>]: no matching function for call to 'erase'
            auto operator()(Rng && rng, I first, S last) const
                 ^
2 errors generated.

Additional Info

Here is the complete verbose output from build2's buildsystem when attempting to build that specific test: https://gist.github.com/Klaim/bdc942fa0d8128bca5cb2b8b22bd1b63

This is on my personal machine.

Note that in an attempt to provided a fix I looked at why erase was not found but I failed to understand. It should be available in that context, but I probably misunderstoo something.