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
This commit is contained in:
Duncan Sands 2011-01-26 10:08:38 +00:00
parent f6c63c2320
commit 37f87c7aa9
2 changed files with 46 additions and 4 deletions

View File

@ -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;
}
}

View File

@ -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
}