[cfe-commits] r106458 - in /cfe/trunk: lib/Checker/SimpleConstraintManager.cpp lib/Checker/SimpleSValuator.cpp test/Analysis/additive-folding.c
Jordy Rose
jediknil at belkadan.com
Mon Jun 21 13:15:15 PDT 2010
Author: jrose
Date: Mon Jun 21 15:15:15 2010
New Revision: 106458
URL: http://llvm.org/viewvc/llvm-project?rev=106458&view=rev
Log:
When folding additive operations, convert the values to the same type. When assuming relationships, convert the integers to the same type as the symbol, at least for now.
Modified:
cfe/trunk/lib/Checker/SimpleConstraintManager.cpp
cfe/trunk/lib/Checker/SimpleSValuator.cpp
cfe/trunk/test/Analysis/additive-folding.c
Modified: cfe/trunk/lib/Checker/SimpleConstraintManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/SimpleConstraintManager.cpp?rev=106458&r1=106457&r2=106458&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/Checker/SimpleConstraintManager.cpp Mon Jun 21 15:15:15 2010
@@ -173,17 +173,6 @@
if (!SE)
return state;
- GRStateManager &StateMgr = state->getStateManager();
- ASTContext &Ctx = StateMgr.getContext();
- BasicValueFactory &BasicVals = StateMgr.getBasicVals();
-
- // FIXME: This is a hack. It silently converts the RHS integer to be
- // of the same type as on the left side. This should be removed once
- // we support truncation/extension of symbolic values.
- const SymExpr *LHS = SE->getLHS();
- QualType LHSType = LHS->getType(Ctx);
- const llvm::APSInt &RHS = BasicVals.Convert(LHSType, SE->getRHS());
-
BinaryOperator::Opcode op = SE->getOpcode();
// FIXME: We should implicitly compare non-comparison expressions to 0.
if (!BinaryOperator::isComparisonOp(op))
@@ -193,7 +182,7 @@
if (!Assumption)
op = NegateComparison(op);
- return AssumeSymRel(state, LHS, op, RHS);
+ return AssumeSymRel(state, SE->getLHS(), op, SE->getRHS());
}
case nonloc::ConcreteIntKind: {
@@ -222,11 +211,13 @@
// x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
// in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
// the subclasses of SimpleConstraintManager to handle the adjustment.
- llvm::APSInt Adjustment(Int.getBitWidth(), Int.isUnsigned());
+ llvm::APSInt Adjustment;
// First check if the LHS is a simple symbol reference.
SymbolRef Sym = dyn_cast<SymbolData>(LHS);
- if (!Sym) {
+ if (Sym) {
+ Adjustment = 0;
+ } else {
// Next, see if it's a "($sym+constant1)" expression.
const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
@@ -256,28 +247,48 @@
}
}
+ // FIXME: This next section is a hack. It silently converts the integers to
+ // be of the same type as the symbol, which is not always correct. Really the
+ // comparisons should be performed using the Int's type, then mapped back to
+ // the symbol's range of values.
+ GRStateManager &StateMgr = state->getStateManager();
+ ASTContext &Ctx = StateMgr.getContext();
+
+ QualType T = Sym->getType(Ctx);
+ assert(T->isIntegerType() || Loc::IsLocType(T));
+ unsigned bitwidth = Ctx.getTypeSize(T);
+ bool isSymUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+
+ // Convert the adjustment.
+ Adjustment.setIsUnsigned(isSymUnsigned);
+ Adjustment.extOrTrunc(bitwidth);
+
+ // Convert the right-hand side integer.
+ llvm::APSInt ConvertedInt(Int, isSymUnsigned);
+ ConvertedInt.extOrTrunc(bitwidth);
+
switch (op) {
default:
// No logic yet for other operators. Assume the constraint is feasible.
return state;
case BinaryOperator::EQ:
- return AssumeSymEQ(state, Sym, Int, Adjustment);
+ return AssumeSymEQ(state, Sym, ConvertedInt, Adjustment);
case BinaryOperator::NE:
- return AssumeSymNE(state, Sym, Int, Adjustment);
+ return AssumeSymNE(state, Sym, ConvertedInt, Adjustment);
case BinaryOperator::GT:
- return AssumeSymGT(state, Sym, Int, Adjustment);
+ return AssumeSymGT(state, Sym, ConvertedInt, Adjustment);
case BinaryOperator::GE:
- return AssumeSymGE(state, Sym, Int, Adjustment);
+ return AssumeSymGE(state, Sym, ConvertedInt, Adjustment);
case BinaryOperator::LT:
- return AssumeSymLT(state, Sym, Int, Adjustment);
+ return AssumeSymLT(state, Sym, ConvertedInt, Adjustment);
case BinaryOperator::LE:
- return AssumeSymLE(state, Sym, Int, Adjustment);
+ return AssumeSymLE(state, Sym, ConvertedInt, Adjustment);
} // end switch
}
Modified: cfe/trunk/lib/Checker/SimpleSValuator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/SimpleSValuator.cpp?rev=106458&r1=106457&r2=106458&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/SimpleSValuator.cpp (original)
+++ cfe/trunk/lib/Checker/SimpleSValuator.cpp Mon Jun 21 15:15:15 2010
@@ -411,15 +411,22 @@
BinaryOperator::Opcode lop = symIntExpr->getOpcode();
if (BinaryOperator::isAdditiveOp(lop)) {
BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+
+ // resultTy may not be the best type to convert to, but it's
+ // probably the best choice in expressions with mixed type
+ // (such as x+1U+2LL). The rules for implicit conversions should
+ // choose a reasonable type to preserve the expression, and will
+ // at least match how the value is going to be used.
+ const llvm::APSInt &first =
+ BVF.Convert(resultTy, symIntExpr->getRHS());
+ const llvm::APSInt &second =
+ BVF.Convert(resultTy, rhsInt->getValue());
+
const llvm::APSInt *newRHS;
if (lop == op)
- newRHS = BVF.EvaluateAPSInt(BinaryOperator::Add,
- symIntExpr->getRHS(),
- rhsInt->getValue());
+ newRHS = BVF.EvaluateAPSInt(BinaryOperator::Add, first, second);
else
- newRHS = BVF.EvaluateAPSInt(BinaryOperator::Sub,
- symIntExpr->getRHS(),
- rhsInt->getValue());
+ newRHS = BVF.EvaluateAPSInt(BinaryOperator::Sub, first, second);
return MakeSymIntVal(symIntExpr->getLHS(), lop, *newRHS, resultTy);
}
}
Modified: cfe/trunk/test/Analysis/additive-folding.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/additive-folding.c?rev=106458&r1=106457&r2=106458&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/additive-folding.c (original)
+++ cfe/trunk/test/Analysis/additive-folding.c Mon Jun 21 15:15:15 2010
@@ -33,6 +33,22 @@
free(buf);
}
+void mixedTypes (int a) {
+ char* buf = malloc(1);
+
+ // Different additive types should not cause crashes when constant-folding.
+ // This is part of PR7406.
+ int b = a + 1LL;
+ if (a != 0 && (b-1) == 0) // not crash
+ return; // no warning
+
+ int c = a + 1U;
+ if (a != 0 && (c-1) == 0) // not crash
+ return; // no warning
+
+ free(buf);
+}
+
//---------------
// Comparisons
//---------------
@@ -60,6 +76,30 @@
free(b);
}
+// Mixed typed inequalities (part of PR7406)
+// These should not crash.
+void mixed_eq_ne (int a) {
+ char* b = NULL;
+ if (a == 1)
+ b = malloc(1);
+ if (a+1U != 2)
+ return; // no-warning
+ if (a-1U != 0)
+ return; // no-warning
+ free(b);
+}
+
+void mixed_ne_eq (int a) {
+ char* b = NULL;
+ if (a != 1)
+ b = malloc(1);
+ if (a+1U == 2)
+ return; // no-warning
+ if (a-1U == 0)
+ return; // no-warning
+ free(b);
+}
+
// Simple order comparisons with no adjustment
void baselineGT (unsigned a) {
More information about the cfe-commits
mailing list