Fix invalid reads in valgrind during unused basic block collections
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 13 Dec 2012 14:52:07 +0000 (15:52 +0100)
committerLars Knoll <lars.knoll@digia.com>
Thu, 13 Dec 2012 19:29:23 +0000 (20:29 +0100)
When clearing cross-references to unused basic blocks blocks, don't
delete the block right afterwards because another block might also
still reference it. Instead keep track of the ones to be deleted
and delete them afterwards in one shot.

Also replaces the existance check for the blocks from a linear
vector search to a hash set lookup which we already have around.

Change-Id: I3bd72359259065ba26bf2116bf849575e4601f32
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
qv4codegen.cpp

index 1cbdc84..17b96fe 100644 (file)
@@ -1520,18 +1520,21 @@ void Codegen::linearize(IR::Function *function)
 
     I::trace(function->basicBlocks.first(), &V, &trace);
 
+    V.insert(exitBlock);
     exitBlock->index = trace.size();
     trace.append(exitBlock);
 
+    QVarLengthArray<IR::BasicBlock*> blocksToDelete;
     foreach (IR::BasicBlock *b, function->basicBlocks)
-        if (!trace.contains(b)) {
-            foreach (IR::BasicBlock *out, b->out) {
-                int idx = out->in.indexOf(b);
-                if (idx >= 0)
-                    out->in.remove(idx);
+        if (!V.contains(b)) {
+                foreach (IR::BasicBlock *out, b->out) {
+                    int idx = out->in.indexOf(b);
+                    if (idx >= 0)
+                        out->in.remove(idx);
+                }
+                blocksToDelete.append(b);
             }
-            delete b;
-        }
+    qDeleteAll(blocksToDelete);
     function->basicBlocks = trace;
 
 #ifndef QV4_NO_LIVENESS