Issue 179139
Summary [ADT] SmallSet is unusable in make_filter_range due to improper iterator facade usage
Labels new issue
Assignees
Reporter Theodor
    On a rather simple testcase attempt to iterate through "filtered" SmallSet fails on iterator dereference.
It tries to bind non-const reference to const value.

```
] cat test.cc
#include <llvm/ADT/SmallSet.h>
#include <llvm/ADT/STLExtras.h>
void test() {
  llvm::SmallSet<int, 12> NewSet;
  auto PredTrue = [](int A) { return true; };
  auto Filtered = llvm::make_filter_range(NewSet, PredTrue);
  for (const auto &Val : Filtered) {
    (void)Val;
  }
}
] gcc test.cc -I../llvm/include -I./include -std=c++17  
In file included from ../llvm/include/llvm/ADT/SmallSet.h:21,
                 from test.cc:1:
../llvm/include/llvm/ADT/iterator.h: In instantiation of ‘ReferenceT llvm::iterator_adaptor_base<DerivedT, WrappedIteratorT, IteratorCategoryT, T, DifferenceTypeT, PointerT, ReferenceT>::operator*() const [with DerivedT = llvm::filter_iterator_base<llvm::SmallSetIterator<int, 12, std::less<int> >, test()::<lambda(int)>, std::forward_iterator_tag>; WrappedIteratorT = llvm::SmallSetIterator<int, 12, std::less<int> >; IteratorCategoryT = std::forward_iterator_tag; T = int; DifferenceTypeT = long int; PointerT = int*; ReferenceT = int&]’:
../llvm/include/llvm/ADT/STLExtras.h:471:28:   required from ‘decltype(auto) llvm::filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>::operator*() const [with WrappedIteratorT = llvm::SmallSetIterator<int, 12, std::less<int> >; PredicateT = test()::<lambda(int)>; IterTag = std::forward_iterator_tag]’
  471 |     return BaseT::operator*();
      |            ~~~~~~~~~~~~~~~~^~
test.cc:7:26:   required from here
    7 |   for (const auto &Val : Filtered) {
      |                          ^~~~~~~~
../llvm/include/llvm/ADT/iterator.h:305:42: error: binding reference of type ‘int&’ to ‘const int’ discards qualifiers
  305 |   ReferenceT operator*() const { return *I; }
      |                                          ^
```

This happens because SmallSetIterator fails to define its reference type as "const".
SmallSet does have const iterator by design, so SmallSetIterator should set ReferenceT parameter of its base class iterator_facade_base to "const T&".

I dont see an easy way to work around this issue.


_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to