From bff3682e9ede6c317bbfb666e64a7d4927ba9055 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Mon, 6 Mar 2023 14:13:07 +0000 Subject: [PATCH] Fix SafeIntIterator reference type We explicitly state that the `reference` type for Sequence iterator is a `value_type`. Since the iterator is a lazy generator, it cannot point to any memory and so it cannot have a reference type. Fixes https://github.com/llvm/llvm-project/issues/61122 Differential Revision: https://reviews.llvm.org/D145373 --- llvm/include/llvm/ADT/Sequence.h | 6 +++--- llvm/unittests/ADT/SequenceTest.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/ADT/Sequence.h b/llvm/include/llvm/ADT/Sequence.h index 1153352..ddda9a9 100644 --- a/llvm/include/llvm/ADT/Sequence.h +++ b/llvm/include/llvm/ADT/Sequence.h @@ -190,7 +190,7 @@ template struct SafeIntIterator { using value_type = T; using difference_type = intmax_t; using pointer = T *; - using reference = T &; + using reference = value_type; // The iterator does not reference memory. // Construct from T. explicit SafeIntIterator(T Value) : SI(CheckedInt::from(Value)) {} @@ -198,9 +198,9 @@ template struct SafeIntIterator { SafeIntIterator(const SafeIntIterator &O) : SI(O.SI) {} // Dereference - value_type operator*() const { return SI.to(); } + reference operator*() const { return SI.to(); } // Indexing - value_type operator[](intmax_t Offset) const { return *(*this + Offset); } + reference operator[](intmax_t Offset) const { return *(*this + Offset); } // Can be compared for equivalence using the equality/inequality operators. bool operator==(const SafeIntIterator &O) const { return SI == O.SI; } diff --git a/llvm/unittests/ADT/SequenceTest.cpp b/llvm/unittests/ADT/SequenceTest.cpp index aec1ea4..acc15bf 100644 --- a/llvm/unittests/ADT/SequenceTest.cpp +++ b/llvm/unittests/ADT/SequenceTest.cpp @@ -296,4 +296,13 @@ TEST(SequenceTest, NonIterableEnums) { ElementsAre(UntypedEnum::A)); } +// Reproducer for https://github.com/llvm/llvm-project/issues/61122 +TEST(SequenceTest, CorrectReferenceType) { + std::vector vals = {1, 2, 3}; + detail::SafeIntIterator begin(4); + detail::SafeIntIterator end(6); + vals.insert(vals.end(), begin, end); + EXPECT_THAT(vals, ElementsAre(1, 2, 3, 4, 5)); +} + } // namespace -- 2.7.4