[lld] r312570 - Do not use invalid iterators to fix Windows build.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 13:17:37 PDT 2017


Author: ruiu
Date: Tue Sep  5 13:17:37 2017
New Revision: 312570

URL: http://llvm.org/viewvc/llvm-project?rev=312570&view=rev
Log:
Do not use invalid iterators to fix Windows build.

std::vector::insert invalidates all iterators, so it was not safe to do

  Script->Opt.Commands.insert(++I, Make(ElfSym::End1));
  Script->Opt.Commands.insert(++I, Make(ElfSym::End2));

because after the first line, `I` is no longer valid.

This patch rewrites fixes the issue. I belive the new code without
higher-order functions is a bit more readable than before.

Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=312570&r1=312569&r2=312570&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Sep  5 13:17:37 2017
@@ -936,6 +936,7 @@ template <class ELFT> void Writer<ELFT>:
   PhdrEntry *Last = nullptr;
   PhdrEntry *LastRO = nullptr;
   PhdrEntry *LastRW = nullptr;
+
   for (PhdrEntry *P : Phdrs) {
     if (P->p_type != PT_LOAD)
       continue;
@@ -953,50 +954,50 @@ template <class ELFT> void Writer<ELFT>:
     return Cmd;
   };
 
-  auto IsSection = [](OutputSection *Sec) {
-    return [=](BaseCommand *Base) { return Base == Sec; };
-  };
-
-  auto IsNoBits = [](BaseCommand *Base) {
-    if (auto *Sec = dyn_cast<OutputSection>(Base))
-      return Sec->Type == SHT_NOBITS;
-    return false;
-  };
+  std::vector<BaseCommand *> &V = Script->Opt.Commands;
 
+  // _end is the first location after the uninitialized data region.
   if (Last) {
-    // _end is the first location after the uninitialized data region.
-    auto E = Script->Opt.Commands.end();
-    auto I = Script->Opt.Commands.begin();
-    I = std::find_if(I, E, IsSection(Last->Last));
-    if (I != E) {
-      if (ElfSym::End1)
-        Script->Opt.Commands.insert(++I, Make(ElfSym::End1));
+    for (size_t I = 0; I < V.size(); ++I) {
+      if (V[I] != Last->Last)
+        continue;
       if (ElfSym::End2)
-        Script->Opt.Commands.insert(++I, Make(ElfSym::End2));
+        V.insert(V.begin() + I + 1, Make(ElfSym::End2));
+      if (ElfSym::End1)
+        V.insert(V.begin() + I + 1, Make(ElfSym::End1));
+      break;
     }
   }
+
+  // _etext is the first location after the last read-only loadable segment.
   if (LastRO) {
-    // _etext is the first location after the last read-only loadable segment.
-    auto E = Script->Opt.Commands.end();
-    auto I = Script->Opt.Commands.begin();
-    I = std::find_if(I, E, IsSection(LastRO->Last));
-    if (I != E) {
-      if (ElfSym::Etext1)
-        Script->Opt.Commands.insert(++I, Make(ElfSym::Etext1));
+    for (size_t I = 0; I < V.size(); ++I) {
+      if (V[I] != LastRO->Last)
+        continue;
       if (ElfSym::Etext2)
-        Script->Opt.Commands.insert(++I, Make(ElfSym::Etext2));
+        V.insert(V.begin() + I + 1, Make(ElfSym::Etext2));
+      if (ElfSym::Etext1)
+        V.insert(V.begin() + I + 1, Make(ElfSym::Etext1));
+      break;
     }
   }
+
+  // _edata points to the end of the last non SHT_NOBITS section.
   if (LastRW) {
-    // _edata points to the end of the last non SHT_NOBITS section.
-    auto E = Script->Opt.Commands.end();
-    auto I = Script->Opt.Commands.begin();
-    I = std::find_if(std::find_if(I, E, IsSection(LastRW->First)), E, IsNoBits);
-    if (I != E) {
+    size_t I = 0;
+    for (; I < V.size(); ++I)
+      if (V[I] == LastRW->First)
+        break;
+
+    for (; I < V.size(); ++I) {
+      auto *Sec = dyn_cast<OutputSection>(V[I]);
+      if (!Sec || Sec->Type != SHT_NOBITS)
+        continue;
       if (ElfSym::Edata2)
-        I = Script->Opt.Commands.insert(I, Make(ElfSym::Edata2));
+        V.insert(V.begin() + I, Make(ElfSym::Edata2));
       if (ElfSym::Edata1)
-        I = Script->Opt.Commands.insert(I, Make(ElfSym::Edata1));
+        V.insert(V.begin() + I, Make(ElfSym::Edata1));
+      break;
     }
   }
 }




More information about the llvm-commits mailing list