[libcxx-dev] Potential bug in use of auto in comparator lambda for std::upper_bound when debug build is enabled

Wesley Yue via libcxx-dev libcxx-dev at lists.llvm.org
Tue Apr 23 12:23:41 PDT 2019


I'm working on some code that compares two different types with std::upper_bound and does so with a custom lambda, which takes both parameters as type "auto". When building normally, this compiles fine. When building with -D_LIBCPP_DEBUG=1, this fails and somewhere in the template magic, libc++ seems to confuse the two types and pass them into the lambda backwards.

Here is some minimal code to reproduce, and the corresponding compilation error:

#include <algorithm>
#include <vector>

struct T1 {
  int i;
};

int main(int argc, char const* argv[]) {
  std::vector<T1> t1_vec = {{.i = 1}, {.i = 3}};

  std::upper_bound(t1_vec.begin(), t1_vec.end(), 2,
                   [](const auto& a, const auto& b) { return a < b.i; });
  return 0;
}


experimental/upper_bound.cpp:14:67: error: member reference base type
 'const int' is not a structure or union
                   [](const auto& a, const auto& b) { return a < b.i; });
                                                                 ~^~
external/llvm_toolchain/bin/../include/c++/v1/algorithm:777:20: note: in instantiation of function template specialization 'main(int, const char **)::(anonymous class)::operator()<T1, int>' requested here
    decltype((void)_VSTD::declval<_Compare&>()(
                   ^
external/llvm_toolchain/bin/../include/c++/v1/__config:473:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
              ^
external/llvm_toolchain/bin/../include/c++/v1/algorithm:771:13: note: while substituting deduced template arguments into function template '__do_compare_assert' [with _LHS = T1, _RHS = int]
            __do_compare_assert(0, __y, __x);
            ^
external/llvm_toolchain/bin/../include/c++/v1/algorithm:4249:13: note: in instantiation of function template specialization 'std::__1::__debug_less<(lambda at experimental/upper_bound.cpp:14:20)>::operator()<int, T1>' requested here
        if (__comp(__value_, *__m))
            ^
external/llvm_toolchain/bin/../include/c++/v1/algorithm:4268:12: note: in instantiation of function template specialization 'std::__1::__upper_bound<std::__1::__debug_less<(lambda at experimental/upper_bound.cpp:14:20)> &, std::__1::__wrap_iter<T1 *>, int>' requested here
    return __upper_bound<_Comp_ref>(__first, __last, __value_, __c);
           ^
experimental/upper_bound.cpp:13:8: note: in instantiation of function template specialization 'std::__1::upper_bound<std::__1::__wrap_iter<T1 *>, int, (lambda at experimental/upper_bound.cpp:14:20)>' requested here
  std::upper_bound(t1_vec.begin(), t1_vec.end(), 2,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/libcxx-dev/attachments/20190423/cf986e09/attachment.html>


More information about the libcxx-dev mailing list