[MCJIT] Fix an iterator invalidation bug in MCJIT::finalizeObject.
authorLang Hames <lhames@gmail.com>
Fri, 5 Sep 2014 23:38:35 +0000 (23:38 +0000)
committerLang Hames <lhames@gmail.com>
Fri, 5 Sep 2014 23:38:35 +0000 (23:38 +0000)
The finalizeObject method calls generateCodeForModule on each of the currently
'added' objects, but generateCodeForModule moves objects out of the 'added'
set as it's called. To avoid iterator invalidation issues, the added set is
copied out before any calls to generateCodeForModule.

This should fix http://llvm.org/PR20851 .

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217291 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/MCJIT/MCJIT.cpp
lib/ExecutionEngine/MCJIT/MCJIT.h

index 3dd205751d1be9b60124d895f7a448a0e4a80edb..8ff41ffd7d677f51af72dca49822c7ae5043f91a 100644 (file)
@@ -225,12 +225,14 @@ void MCJIT::finalizeLoadedModules() {
 void MCJIT::finalizeObject() {
   MutexGuard locked(lock);
 
-  for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
-                              E = OwnedModules.end_added();
-       I != E; ++I) {
-    Module *M = *I;
+  // Generate code for module is going to move objects out of the 'added' list,
+  // so we need to copy that out before using it:
+  SmallVector<Module*, 16> ModsToAdd;
+  for (auto M : OwnedModules.added())
+    ModsToAdd.push_back(M);
+
+  for (auto M : ModsToAdd)
     generateCodeForModule(M);
-  }
 
   finalizeLoadedModules();
 }
index 9a4e53f27f2f604e17c0a0549edc71d588849a41..624a4317a3b7e284347d4c6753d02a9087139393 100644 (file)
@@ -118,6 +118,9 @@ class MCJIT : public ExecutionEngine {
 
     ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
     ModulePtrSet::iterator end_added() { return AddedModules.end(); }
+    iterator_range<ModulePtrSet::iterator> added() {
+      return iterator_range<ModulePtrSet::iterator>(begin_added(), end_added());
+    }
 
     ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
     ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }