From 4501d391e5febacaabe293d6433640551baf589d Mon Sep 17 00:00:00 2001
From: Thorsten Hater <24411438+thorstenhater@users.noreply.github.com>
Date: Thu, 4 Aug 2022 10:40:42 +0200
Subject: [PATCH] modcc: Allow redundant, but correct READ declaration. (#1936)

---
 modcc/module.cpp                          | 17 ++++++++++++-----
 test/unit-modcc/mod_files/test-rw-ion.mod |  8 ++++++++
 test/unit-modcc/test_module.cpp           |  9 +++++++++
 3 files changed, 29 insertions(+), 5 deletions(-)
 create mode 100644 test/unit-modcc/mod_files/test-rw-ion.mod

diff --git a/modcc/module.cpp b/modcc/module.cpp
index c167b053..6d6a56a0 100644
--- a/modcc/module.cpp
+++ b/modcc/module.cpp
@@ -723,11 +723,8 @@ void Module::add_variables_to_symbols() {
     }
 
     std::set<std::string> cond;
-    for(auto const& ion : neuron_block_.ions) {
-        for(auto const& var : ion.read) {
-            update_ion_symbols(var, accessKind::read, ion.name);
-        }
-        for(auto const& var : ion.write) {
+    for(auto const& ion: neuron_block_.ions) {
+        for(auto const& var: ion.write) {
             update_ion_symbols(var, accessKind::write, ion.name);
             auto name = "conductivity_" + ion.name + "_";
             if (cond.find(name) == cond.end()) {
@@ -736,6 +733,16 @@ void Module::add_variables_to_symbols() {
             }
         }
 
+        for(auto const& var: ion.read) {
+            // Skip vars we have already processed as WRITE, since those can be read as well.
+            if (std::count_if(ion.write.begin(),
+                              ion.write.end(),
+                              [&var](const auto& it) { return var.spelling == it.spelling; })) {
+                continue;
+            }
+            update_ion_symbols(var, accessKind::read, ion.name);
+        }
+
         if(ion.uses_valence()) {
             Token valence_var = ion.valence_var;
             create_indexed_variable(valence_var.spelling, sourceKind::ion_valence,
diff --git a/test/unit-modcc/mod_files/test-rw-ion.mod b/test/unit-modcc/mod_files/test-rw-ion.mod
new file mode 100644
index 00000000..ea2800db
--- /dev/null
+++ b/test/unit-modcc/mod_files/test-rw-ion.mod
@@ -0,0 +1,8 @@
+NEURON {
+    SUFFIX hh
+    USEION na READ ena, ina WRITE ina
+}
+
+BREAKPOINT { ina = 5*(v - ena) }
+
+INITIAL {}
diff --git a/test/unit-modcc/test_module.cpp b/test/unit-modcc/test_module.cpp
index f708fc91..34ff5b4d 100644
--- a/test/unit-modcc/test_module.cpp
+++ b/test/unit-modcc/test_module.cpp
@@ -113,3 +113,12 @@ TEST(Module, breakpoint) {
 
     EXPECT_TRUE(m.semantic());
 }
+
+TEST(Module, read_write_ion) {
+    Module m(io::read_all(DATADIR "/mod_files/test-rw-ion.mod"), "test-rw-ion.mod");
+    EXPECT_NE(m.buffer().size(), 0);
+
+    Parser p(m, false);
+    EXPECT_TRUE(p.parse());
+    EXPECT_TRUE(m.semantic());
+}
-- 
GitLab