https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109732

--- Comment #9 from Martin Liška <marxin at gcc dot gnu.org> ---
I've got a C++ reduced test-case:

$ cat x.ii
template <typename> struct is_same;
template <bool, typename _Tp> using enable_if_t = _Tp;
template <typename _Iterator> struct reverse_iterator {
  _Iterator current;
  typedef _Iterator iterator_type;
  reverse_iterator(iterator_type __x) : current(__x) {}
  iterator_type base() { return current; }
};
template <typename _Iterator>
bool operator==(reverse_iterator<_Iterator> __x,
                reverse_iterator<_Iterator> __y) {
  return __x.base() == __y.base();
}
struct __normal_iterator {
  int _M_current;
};
template <typename> struct __new_allocator;
template <typename> struct allocator_traits;
template <typename _Tp> struct allocator_traits<__new_allocator<_Tp>> {
  using const_pointer = _Tp *;
};
template <typename> struct vector {
  typedef __normal_iterator iterator;
};
namespace {
enum value_t { null, object, array, string };
template <template <typename, typename...> class = vector,
          template <typename> class = __new_allocator>
class basic_json;
struct external_constructor {
  template <
      typename BasicJsonType, typename CompatibleStringType,
      enable_if_t<is_same<typename BasicJsonType::string_t>::value, int> = 0>
  static void construct(BasicJsonType &j, CompatibleStringType) {
    j.m_type = string;
  }
} to_json_s;
void to_json(basic_json<> &j) { external_constructor::construct(j, to_json_s);
}
long begin_value;
long end_value = 1;
struct primitive_iterator_t {
  long m_it;
  void set_begin() { m_it = begin_value; }
  void set_end() { m_it = end_value; }
  friend bool operator==(primitive_iterator_t, primitive_iterator_t rhs) {
    return rhs.m_it;
  }
};
template <typename BasicJsonType> struct internal_iterator {
  typename BasicJsonType::array_t::iterator array_iterator;
  primitive_iterator_t primitive_iterator;
};
template <typename BasicJsonType> struct iter_impl {
  using array_t = typename BasicJsonType::array_t;
  typedef typename BasicJsonType::const_pointer pointer;
  iter_impl(pointer object) : m_object(object) {
    switch (m_object->m_type)
    case ::object:
    case array:
      m_it.array_iterator = typename array_t::iterator();
  }
  void set_begin() {
    switch (m_object->m_type) {
    case object:
    case array:
      break;
    case null:
      m_it.primitive_iterator.set_end();
      break;
    default:
      m_it.primitive_iterator.set_begin();
    }
  }
  template <typename IterImpl> bool operator==(IterImpl other) {
    return m_it.primitive_iterator == other.m_it.primitive_iterator;
  }
  pointer m_object;
  internal_iterator<BasicJsonType> m_it;
};
template <typename Base> struct json_reverse_iterator : reverse_iterator<Base>
{
  json_reverse_iterator(Base it) : reverse_iterator<Base>(it) {}
};
template <template <typename, typename...> class ArrayType,
          template <typename> class AllocatorType>
struct basic_json {
  using const_pointer =
      typename allocator_traits<AllocatorType<basic_json>>::const_pointer;
  using const_iterator = iter_impl<basic_json>;
  using const_reverse_iterator = json_reverse_iterator<const_iterator>;
  using array_t = ArrayType<basic_json>;
  template <typename CompatibleType> basic_json(CompatibleType) {
    to_json(*this);
  }
  const_iterator cbegin() {
    const_iterator result(this);
    result.set_begin();
    return result;
  }
  const_iterator cend() {
    const_iterator result(this);
    return result;
  }
  const_reverse_iterator crbegin() { return cend(); }
  const_reverse_iterator crend() { return cbegin(); }
  value_t m_type;
};
} // namespace
int seen_failures;
__attribute__((noinline)) void sne(basic_json<>::const_reverse_iterator lhs,
                                   basic_json<>::const_reverse_iterator rhs) {
  bool res = !(lhs == rhs);
  if (!res)
    seen_failures++;
}
basic_json main_js = "";

int
main() {
  basic_json js_const(main_js);
  basic_json<>::const_reverse_iterator sit = js_const.crbegin(),
                                       __trans_tmp_1 = js_const.crend();
  sne(sit, __trans_tmp_1);
  return seen_failures;
}

Reply via email to