[cfe-dev] -Wambiguous-reversed-operator with equal types (original) (raw)
Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Thu Dec 10 13:39:24 PST 2020
- Previous message: [cfe-dev] -Wambiguous-reversed-operator with equal types
- Next message: [cfe-dev] -Wambiguous-reversed-operator with equal types
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, 10 Dec 2020 at 06:46, Nuno Lopes via cfe-dev <cfe-dev at lists.llvm.org> wrote:
Hi,
I've been trying to fix a bunch of LLVM headers so they are compatible with C++20. (so I can include those from Alive2 source code) I'm currently stuck with -Wambiguous-reversed-operator. I've fixed a couple, but this one (a few similar) left me wondering if the warning is correct or not: In file included from llvm/include/llvm/Passes/PassBuilder.h:19: In file included from llvm/include/llvm/Analysis/CGSCCPassManager.h:98: llvm/include/llvm/Analysis/LazyCallGraph.h:1117:22: error: ISO C++20 considers use of overloaded operator '!=' (with operand types 'llvm::User::valueopiterator' and 'llvm::User::valueopiterator') to be ambiguous despite there being a unique best viable function [-Werror,-Wambiguous-reversed-operator] for (Value *Op : C->operandvalues()) ^ llvm/include/llvm/ADT/iterator.h:263:8: note: ambiguity is between a regular call to this operator and a call with the argument order reversed bool operator==(const DerivedT &RHS) const { return I == RHS.I; } ^ Note that it's complaining about comparing 'llvm::User::valueopiterator' and 'llvm::User::valueopiterator' (i.e., same type). Since both arguments are of the same type and the comparison function has const on both LHS/RHS, reversing them shouldn't have any impact, right? Unless there's some type conversion going on that the error message is hiding. Could someone please confirm if the warning is correct and/or the code needs fixing?
The warning is correct. In C++20 there are four ways to perform this != comparison:
Using iterator_adaptor_base::operator==:
1: !((iterator_adaptor_base&)a == b) [synthesized != from operator==] 2: !((iterator_adaptor_base&)b == a) [synthesized != from operator==, reversed]
Using iterator_facade_base::operator!=:
3: (iterator_facade_base&)a != b [regular operator!=] 4: (iterator_facade_base&)b != a [regular operator!=, reversed]
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.
Probably the cleanest solution would be to replace:
bool operator==(const DerivedT &RHS) const { return I == RHS.I; }
with:
friend bool operator==(const DerivedT &LHS, const DerivedT &RHS) const { return LHS.I == RHS.I; }
Thanks, Nuno
cfe-dev mailing list cfe-dev at lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20201210/fd85b1cb/attachment.html>
- Previous message: [cfe-dev] -Wambiguous-reversed-operator with equal types
- Next message: [cfe-dev] -Wambiguous-reversed-operator with equal types
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]