aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2011-01-26 10:08:38 +0000
committerDuncan Sands <baldrick@free.fr>2011-01-26 10:08:38 +0000
commit37f87c7aa914fba1362bb187ce5a386abfe94e39 (patch)
treeb51c37ad037c9dd56ef135199408281a8803b7b3
parentf6c63c23203ca4c4aa89efa2bff722bb479cfe3c (diff)
Fix PR9039, a use-after-free in reassociate. The issue was that the
operand being factorized (and erased) could occur several times in Ops, resulting in freed memory being used when the next occurrence in Ops was analyzed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124287 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp15
-rw-r--r--test/Transforms/Reassociate/2011-01-26-UseAfterFree.ll35
2 files changed, 46 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index 46b7f95258..396b329980 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -811,16 +811,23 @@ Value *Reassociate::OptimizeAdd(Instruction *I,
// RemoveFactorFromExpression on successive values to behave differently.
Instruction *DummyInst = BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal);
SmallVector<Value*, 4> NewMulOps;
- for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ for (unsigned i = 0; i != Ops.size(); ++i) {
// Only try to remove factors from expressions we're allowed to.
BinaryOperator *BOp = dyn_cast<BinaryOperator>(Ops[i].Op);
if (BOp == 0 || BOp->getOpcode() != Instruction::Mul || !BOp->use_empty())
continue;
if (Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) {
- NewMulOps.push_back(V);
- Ops.erase(Ops.begin()+i);
- --i; --e;
+ // The factorized operand may occur several times. Convert them all in
+ // one fell swoop.
+ for (unsigned j = Ops.size(); j != i;) {
+ --j;
+ if (Ops[j].Op == Ops[i].Op) {
+ NewMulOps.push_back(V);
+ Ops.erase(Ops.begin()+j);
+ }
+ }
+ --i;
}
}
diff --git a/test/Transforms/Reassociate/2011-01-26-UseAfterFree.ll b/test/Transforms/Reassociate/2011-01-26-UseAfterFree.ll
new file mode 100644
index 0000000000..e6c76b3444
--- /dev/null
+++ b/test/Transforms/Reassociate/2011-01-26-UseAfterFree.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -reassociate
+; PR9039
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-gnu-linux"
+
+%ada__tags__T15s = type void ()
+
+define void @exp_averages_intraday__deviation() {
+entry:
+ %0 = load i32* undef, align 4
+ %1 = shl i32 %0, 2
+ %2 = add nsw i32 undef, %1
+ %3 = add nsw i32 %2, undef
+ %4 = mul nsw i32 %0, 12
+ %5 = add nsw i32 %3, %4
+ %6 = add nsw i32 %5, %4
+ %7 = add nsw i32 %6, undef
+ br i1 false, label %"4", label %"12"
+
+"4": ; preds = %entry
+ br i1 undef, label %"5", label %"8"
+
+"5": ; preds = %"4"
+ unreachable
+
+"8": ; preds = %"4"
+ %8 = getelementptr inbounds i8* undef, i32 %6
+ br i1 undef, label %"13", label %"12"
+
+"12": ; preds = %"8", %entry
+ ret void
+
+"13": ; preds = %"8"
+ ret void
+}