diff --git a/src/Configuration.cc b/src/Configuration.cc
index 247dbd5c25168a77241c13962f371e85f2c000fd..36502d11697d1c5eadda7a5c53d5c3c98a5d4807 100644
--- a/src/Configuration.cc
+++ b/src/Configuration.cc
@@ -681,7 +681,7 @@ vector<filesystem::path>
 Configuration::getIncludePaths() const
 {
   vector<filesystem::path> include_paths;
-  for (auto path : paths)
+  for (const auto& path : paths)
     for (const auto& mapit : path.get_paths())
       for (const auto& vecit : mapit.second)
         include_paths.emplace_back(vecit);
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 6d8ae9a9baec9210bb4b4d62de5a1d92805e92ff..885ee71742f3f3bce34c0fb6ee07ffdae87df78e 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1927,6 +1927,12 @@ ModelTree::initializeMEXCompilationWorkers(int numworkers, const filesystem::pat
   cout << "Spawning " << numworkers << " threads for compiling MEX files." << endl;
 
   for (int i {0}; i < numworkers; i++)
+    /* Passing the stop_token by const reference is ok (and makes clang-tidy happier),
+       since the std::jthread constructor calls the lambda with the return argument of the
+       get_stop_token() method, which returns a stop_token by value; hence there is no lifetime
+       issue. See:
+       https://stackoverflow.com/questions/72990607/const-stdstop-token-or-just-stdstop-token-as-parameter-for-thread-funct
+     */
     mex_compilation_workers.emplace_back([](const stop_token& stoken) {
       unique_lock<mutex> lk {mex_compilation_mut};
       filesystem::path output;
diff --git a/src/SubModel.cc b/src/SubModel.cc
index 87844043ca6f28f1f7cfb088028feef4624c5dd7..38b729baccf4e94cccd5fffc0618649be94950d4 100644
--- a/src/SubModel.cc
+++ b/src/SubModel.cc
@@ -315,13 +315,13 @@ TrendComponentModelTable::writeOutput(const string& basename, ostream& output) c
 
       vector<string> target_eqtags_vec = target_eqtags.at(name);
       output << "M_.trend_component." << name << ".target_eqtags = {";
-      for (auto it : target_eqtags_vec)
+      for (const auto& it : target_eqtags_vec)
         output << "'" << it << "';";
       output << "};" << endl;
 
       vector<string> eqtags_vec = eqtags.at(name);
       output << "M_.trend_component." << name << ".target_eqn = [";
-      for (auto it : target_eqtags_vec)
+      for (const auto& it : target_eqtags_vec)
         output << distance(eqtags_vec.begin(), find(eqtags_vec.begin(), eqtags_vec.end(), it)) + 1
                << " ";
       output << "];" << endl;
@@ -595,7 +595,7 @@ void
 VarModelTable::setLhs(map<string, vector<int>> lhs_arg)
 {
   lhs = move(lhs_arg);
-  for (auto it : lhs)
+  for (const auto& it : lhs)
     {
       vector<int> lhsvec;
       for (auto ids : it.second)
diff --git a/src/macro/Expressions.cc b/src/macro/Expressions.cc
index 0085526376c6293c0e63f4de2aa9ddd1c8896562..cfc6704bb3caaffd4dc3349075d44297d2accb60 100644
--- a/src/macro/Expressions.cc
+++ b/src/macro/Expressions.cc
@@ -1282,7 +1282,7 @@ void
 Array::print(ostream& output, bool matlab_output) const noexcept
 {
   output << (matlab_output ? "{" : "[");
-  for (bool printed_something {false}; auto e : arr)
+  for (bool printed_something {false}; const auto& e : arr)
     {
       if (exchange(printed_something, true))
         output << ", ";
@@ -1295,7 +1295,7 @@ void
 Tuple::print(ostream& output, bool matlab_output) const noexcept
 {
   output << (matlab_output ? "{" : "(");
-  for (bool printed_something {false}; auto e : tup)
+  for (bool printed_something {false}; const auto& e : tup)
     {
       if (exchange(printed_something, true))
         output << ", ";
@@ -1308,7 +1308,7 @@ void
 Function::printArgs(ostream& output) const noexcept
 {
   output << "(";
-  for (bool printed_something {false}; auto e : args)
+  for (bool printed_something {false}; const auto& e : args)
     {
       if (exchange(printed_something, true))
         output << ", ";