Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<filesystem>: path's comparison operators are IF-NDR #2358

Closed
statementreply opened this issue Nov 24, 2021 · 3 comments · Fixed by #2457
Closed

<filesystem>: path's comparison operators are IF-NDR #2358

statementreply opened this issue Nov 24, 2021 · 3 comments · Fixed by #2457
Labels
bug Something isn't working fixed Something works now, yay!

Comments

@statementreply
Copy link
Contributor

statementreply commented Nov 24, 2021

Describe the bug

After #2000, path's comparison operators are IF-NDR (ill-formed, no diagnostic required). See @Quuxplusone's blogpost and @jwakely's comment for a detailed analysis of similar issues in libc++ and libstdc++.

Command-line test case

Copied from Arthur O’Dwyer's blogpost.

D:\Temp>type repro.cpp
#include <filesystem>
#include <ranges>

static_assert(std::ranges::range<std::filesystem::path>);
static_assert(std::ranges::range<const std::filesystem::path>);
D:\Temp>clang-cl /c /EHsc /W4 /std:c++latest /D_HAS_CXX23=1 repro.cpp
repro.cpp(5,1): error: static_assert failed
static_assert(std::ranges::range<const std::filesystem::path>);
^                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
repro.cpp(5,28): note: because 'const std::filesystem::path' does not satisfy 'range'
static_assert(std::ranges::range<const std::filesystem::path>);
                           ^
D:\repos\STL\out\\build\x64\out\inc\xutility(2233,9): note: because '::std::ranges::begin(__r)' would be invalid: no
      matching function for call to object of type 'const _Begin::_Cpo'
        _RANGES begin(__r);
        ^
D:\repos\STL\out\\build\x64\out\inc\yvals_core.h(1411,20): note: expanded from macro '_RANGES'
#define _RANGES    ::std::ranges::
                   ^
1 error generated.

STL version

3c2fd04

@statementreply statementreply changed the title <filesystem>: path's comparison operators invoke IF-NDR <filesystem>: path's comparison operators are IF-NDR Nov 24, 2021
@cpplearner
Copy link
Contributor

cpplearner commented Nov 24, 2021

In addition to path's comparison operators (both operator== and operator<=>), the following lines also cause clang-cl to attempt implicit conversion from const path& to wstring_view, and thus affect the result of range<const path>:

return operator+=(_Replacement);

STL/stl/inc/filesystem

Lines 1739 to 1740 in 3c2fd04

} else if (_Elem == _Dot) { // skip filename elements that are dot, N4810 29.11.7.4.11 [fs.path.gen]/4.2
} else if (_Elem == _Dot_dot) {

There are similar uses in templates, but uses in uninstantiated templates are probably fine.

@StephanTLavavej StephanTLavavej added the bug Something isn't working label Dec 1, 2021
@StephanTLavavej
Copy link
Member

@CaseyCarter agrees that this is definitely a bug, and that we need to ensure that path::iterator is defined before its semantics affect the behavior of the program (by defining path::iterator earlier, or the dependent stuff later).

@fsb4000
Copy link
Contributor

fsb4000 commented Jan 4, 2022

There are similar uses in templates, but uses in uninstantiated templates are probably fine.

@cpplearner thank you for your analytics. Templates influenced this too. I had to do inline templated operator+= for the static_asserts to be successful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants