| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // std::sort |
| |
| #include <algorithm> |
| #include <iterator> |
| #include <type_traits> |
| #include <utility> |
| |
| struct BadIter { |
| struct Value { |
| friend bool operator==(const Value& x, const Value& y); |
| friend bool operator!=(const Value& x, const Value& y); |
| friend bool operator< (const Value& x, const Value& y); |
| friend bool operator<=(const Value& x, const Value& y); |
| friend bool operator> (const Value& x, const Value& y); |
| friend bool operator>=(const Value& x, const Value& y); |
| friend void swap(Value, Value); |
| }; |
| |
| using iterator_category = std::random_access_iterator_tag; |
| using value_type = Value; |
| using reference = Value&; |
| using difference_type = long; |
| using pointer = Value*; |
| |
| Value operator*() const; // Not `Value&`. |
| reference operator[](difference_type n) const; |
| |
| BadIter& operator++(); |
| BadIter& operator--(); |
| BadIter operator++(int); |
| BadIter operator--(int); |
| |
| BadIter& operator+=(difference_type n); |
| BadIter& operator-=(difference_type n); |
| friend BadIter operator+(BadIter x, difference_type n); |
| friend BadIter operator+(difference_type n, BadIter x); |
| friend BadIter operator-(BadIter x, difference_type n); |
| friend difference_type operator-(BadIter x, BadIter y); |
| |
| friend bool operator==(const BadIter& x, const BadIter& y); |
| friend bool operator!=(const BadIter& x, const BadIter& y); |
| friend bool operator< (const BadIter& x, const BadIter& y); |
| friend bool operator<=(const BadIter& x, const BadIter& y); |
| friend bool operator> (const BadIter& x, const BadIter& y); |
| friend bool operator>=(const BadIter& x, const BadIter& y); |
| }; |
| |
| // Verify that iterators with incorrect `iterator_traits` are rejected. This protects against potential undefined |
| // behavior when these iterators are passed to standard algorithms. |
| void test() { |
| std::sort(BadIter(), BadIter()); |
| //expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of dereferencing the iterator}} |
| } |