<div dir="ltr"><div dir="ltr">On Thu, 10 Dec 2020 at 06:46, Nuno Lopes via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
I've been trying to fix a bunch of LLVM headers so they are compatible with<br>
C++20. (so I can include those from Alive2 source code)<br>
<br>
I'm currently stuck with -Wambiguous-reversed-operator. I've fixed a couple,<br>
but this one (a few similar) left me wondering if the warning is correct or<br>
not:<br>
<br>
In file included from llvm/include/llvm/Passes/PassBuilder.h:19:<br>
In file included from llvm/include/llvm/Analysis/CGSCCPassManager.h:98:<br>
llvm/include/llvm/Analysis/LazyCallGraph.h:1117:22: error: ISO C++20<br>
considers use of overloaded operator '!=' (with operand types<br>
'llvm::User::value_op_iterator' and 'llvm::User::value_op_iterator') to be<br>
ambiguous despite there being a unique best viable function<br>
[-Werror,-Wambiguous-reversed-operator]<br>
for (Value *Op : C->operand_values())<br>
^<br>
llvm/include/llvm/ADT/iterator.h:263:8: note: ambiguity is between a regular<br>
call to this operator and a call with the argument order reversed<br>
bool operator==(const DerivedT &RHS) const { return I == RHS.I; }<br>
^<br>
<br>
Note that it's complaining about comparing 'llvm::User::value_op_iterator'<br>
and 'llvm::User::value_op_iterator' (i.e., same type). Since both arguments<br>
are of the same type and the comparison function has const on both LHS/RHS,<br>
reversing them shouldn't have any impact, right?<br>
Unless there's some type conversion going on that the error message is<br>
hiding.<br>
<br>
Could someone please confirm if the warning is correct and/or the code needs<br>
fixing?<br></blockquote><div><br></div><div>The warning is correct. In C++20 there are four ways to perform this != comparison:</div><div><br></div><div>Using iterator_adaptor_base::operator==:</div><div><br></div><div>1: !((iterator_adaptor_base&)a == b) [synthesized != from operator==]</div><div>2: !((iterator_adaptor_base&)b == a) [synthesized != from operator==, reversed]</div><div><br></div><div>Using iterator_facade_base::operator!=:</div><div><br></div><div>3: (iterator_facade_base&)a != b [regular operator!=]</div><div>4: (iterator_facade_base&)b != a [regular operator!=, reversed]</div><div><br></div><div>Of these: 1 beats 3 (better conversion for a), 2 beats 4 (better conversion for b), and they're otherwise unordered, so the result is an ambiguity.</div><div><br></div><div>Probably the cleanest solution would be to replace:</div><div><br></div><div>bool operator==(const DerivedT &RHS) const { return I == RHS.I; }<br></div><div><br></div><div>with:</div><div><br></div><div>friend bool operator==(const DerivedT &LHS, const DerivedT &RHS) const { return LHS.I == RHS.I; }<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Thanks,<br>
Nuno<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>