From e5a2d17b5dffc69c9994d48c2c12288865b80156 Mon Sep 17 00:00:00 2001
From: Alberto Gonzalez <boqwxp@airmail.cc>
Date: Wed, 17 Jun 2020 22:32:34 +0000
Subject: [PATCH 1/2] hashlib, rtlil: Add `operator+=()` to `dict<>::iterator`
 and `dict<>::const_iterator` and add `operator+()` and `operator+=()` to
 `ObjIterator`.

---
 kernel/hashlib.h |  2 ++
 kernel/rtlil.h   | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index 5c87b55f5..52dfd1280 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -363,6 +363,7 @@ public:
 	public:
 		const_iterator() { }
 		const_iterator operator++() { index--; return *this; }
+		const_iterator operator+=(int amt) { index -= amt; if(index < 0) index = -1; return *this; }
 		bool operator<(const const_iterator &other) const { return index > other.index; }
 		bool operator==(const const_iterator &other) const { return index == other.index; }
 		bool operator!=(const const_iterator &other) const { return index != other.index; }
@@ -380,6 +381,7 @@ public:
 	public:
 		iterator() { }
 		iterator operator++() { index--; return *this; }
+		iterator operator+=(int amt) { index -= amt; if(index < 0) index = -1; return *this; }
 		bool operator<(const iterator &other) const { return index > other.index; }
 		bool operator==(const iterator &other) const { return index == other.index; }
 		bool operator!=(const iterator &other) const { return index != other.index; }
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index f3dc3af68..147ec8a5b 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -554,6 +554,29 @@ namespace RTLIL
 			return *this;
 		}
 
+		inline ObjIterator<T>& operator+=(int amt) {
+			log_assert(list_p != nullptr);
+			it += amt;
+			if (it == list_p->end()) {
+				(*refcount_p)--;
+				list_p = nullptr;
+				refcount_p = nullptr;
+			}
+			return *this;
+		}
+
+		inline ObjIterator<T> operator+(int amt) {
+			log_assert(list_p != nullptr);
+			ObjIterator<T> new_obj(*this);
+			new_obj.it += amt;
+			if (new_obj.it == list_p->end()) {
+				(*(new_obj.refcount_p))--;
+				new_obj.list_p = nullptr;
+				new_obj.refcount_p = nullptr;
+			}
+			return new_obj;
+		}
+
 		inline const ObjIterator<T> operator++(int) {
 			ObjIterator<T> result(*this);
 			++(*this);

From d71a9badda20d48bcd4031f030d2d0901f837261 Mon Sep 17 00:00:00 2001
From: Alberto Gonzalez <boqwxp@airmail.cc>
Date: Fri, 19 Jun 2020 20:57:27 +0000
Subject: [PATCH 2/2] dict: Remove guard for past-the-end iterators that might
 mask problems in static analysis.

Co-Authored-By: whitequark <whitequark@whitequark.org>
---
 kernel/hashlib.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index 52dfd1280..a523afadd 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -363,7 +363,7 @@ public:
 	public:
 		const_iterator() { }
 		const_iterator operator++() { index--; return *this; }
-		const_iterator operator+=(int amt) { index -= amt; if(index < 0) index = -1; return *this; }
+		const_iterator operator+=(int amt) { index -= amt; return *this; }
 		bool operator<(const const_iterator &other) const { return index > other.index; }
 		bool operator==(const const_iterator &other) const { return index == other.index; }
 		bool operator!=(const const_iterator &other) const { return index != other.index; }
@@ -381,7 +381,7 @@ public:
 	public:
 		iterator() { }
 		iterator operator++() { index--; return *this; }
-		iterator operator+=(int amt) { index -= amt; if(index < 0) index = -1; return *this; }
+		iterator operator+=(int amt) { index -= amt; return *this; }
 		bool operator<(const iterator &other) const { return index > other.index; }
 		bool operator==(const iterator &other) const { return index == other.index; }
 		bool operator!=(const iterator &other) const { return index != other.index; }