[PATCH] Cleanup compiler diagnostics

François Dumont frs.dumont@gmail.com
Mon Sep 16 17:24:41 GMT 2024


On 16/09/2024 09:06, Jonathan Wakely wrote:
>
>
> On Mon, 16 Sept 2024, 07:07 François Dumont, <frs.dumont@gmail.com> wrote:
>
>     Hi
>
>     Before I extend those changes to the whole library I'd like to
>     know if
>     there is any interest in this effort.
>
>
> Unfortunately this change breaks standard conformance. Changing those 
> operators to "hidden friends" changes overload resolution, which is 
> why the diagnostics change, but that can also break value programs.
>
> Consider:
>
> struct S {
>   operator std::vector<int>() const;
> } s
> auto b = s==s;
>
>
>     Thanks to this patch build of the new test cases simply gives:
>
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc: In
>     function 'int main()':
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:17:
>     error: no match for 'operator==' in 's1 == s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:18:
>     error: no match for 'operator<' in 's1 < s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:19:
>     error: no match for 'operator!=' in 's1 != s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:20:
>     error: no match for 'operator>' in 's1 > s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:21:
>     error: no match for 'operator<=' in 's1 <= s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:22:
>     error: no match for 'operator>=' in 's1 >= s2' (operand types are
>     'NoOperators' and 'NoOperators')
>     ~/libstdc++-v3/testsuite/std/operators/clean_diagnostics20_neg.cc:23:
>     error: no match for 'operator<=>' in 's1 <=> s2' (operand types are
>     'NoOperators' and 'NoOperators')
>
>     and not 2 or more screens of potential candidates that does not match
>     because of template deduction issues.
>
>
> I think this needs to be fixed in the compiler, not by changing the 
> library behaviour.

Too bad, I hoped it would also improve compilation time limiting the 
number of operators to consider.


>
> For example, do not show all candidates by default, with an option to 
> show them. Showing candidates that don't match either argument isn't 
> often useful, so we could limit the output to cases where one argument 
> is viable. That wouldn't help for operator<< though, as the left 
> operand is usually an ostream even if no usable operator<< is found 
> for the right operator.
>
>
>
>     Of course if I include stdc++.h it is more 5 screens.
>
>     If there is interest some questions before I submit this patch
>     properly:
>
>     Where to put the new tests ?
>
>     Anyone to help making those test FAIL rather than XFAIL if there
>     is for
>     example any 'note: candidate' in the output ?
>
>
> You probably want to use dg-bogus for that.
>
> https://gcc.gnu.org/onlinedocs/gccint/Directives.html
>
>
>
>     I also tried to deal with spaceship operator in this patch. But it
>     has
>     side effect because __synth3way_t is not SFINAE friendly.
>
>
> It is SFINAE friendly though. The problem is that you tried to use it 
> in a context where T is not deduced, so does not give a substitution 
> failure, because it's not substituted during template argument deduction.
>
> That is a problem with your change, not a problem with synth3way.

Yes, my bad, I shouldn't have said that it was not SFINAE friendly. In 
the patch you can see that I tried to move it as friend like this:

       template<typename _Up>
     [[nodiscard]] _GLIBCXX20_CONSTEXPR
     friend inline enable_if_t<is_same_v<_Tp, _Up> &&
                   three_way_comparable<_Up>,
                   __detail::__synth3way_t<_Up>>
     operator<=>(const vector<_Up, _Alloc>& __x,
             const vector<_Up, _Alloc>& __y)
     {
       return std::lexicographical_compare_three_way(__x.begin(), __x.end(),
                             __y.begin(), __y.end(),
                             __detail::__synth3way);
     }

so still requiring substitution.

>
>
>     There is this
>     problem in 23_containers/vector/cmp_c++20.cc:
>
>     Excess errors:
>     ~/gcc/git/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc:126:
>
>     error: static assertion failed
>     ~/gcc/git/libstdc++-v3/testsuite/23_containers/vector/cmp_c++20.cc:129:
>
>     error: no match for 'operator<=>' in 'c <=> c' (operand types are
>     'std::vector<test04()::L>' and 'std::vector<test04()::L>')
>
>     It's due to three_way_comparable<> not doing the same job as
>     _Synth3way
>     for type having only a '<' operator. Should it ?
>

So, even if it is purely theoretical now for my original purpose, 
shouldn't the public three_way_comparable concept return true as soon as 
the type has an operator < ?

The _Synth3way would need of course the current concept as an internal.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20240916/c96f4311/attachment-0001.htm>


More information about the Libstdc++ mailing list