aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-08-22 19:58:20 +0000
committerTed Kremenek <kremenek@apple.com>2012-08-22 19:58:20 +0000
commitefb3d56720654f5355ff8fc666499cc6554034f4 (patch)
tree1fa7a7a9769bb014b5b8a48cd66709c9d9ac8c17
parent153f8ecb5169347e41a0734ee1698498d88b96c5 (diff)
Despite me asking Jordan to do r162313, revert it. We can provide
another way to whitelist these special cases. This is an intermediate patch. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162386 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp48
-rw-r--r--test/Analysis/reference.cpp3
3 files changed, 30 insertions, 33 deletions
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 550404a510..2b883cf9b9 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -380,7 +380,17 @@ RangeConstraintManager::GetRange(ProgramStateRef state, SymbolRef sym) {
// given symbol type.
BasicValueFactory &BV = getBasicVals();
QualType T = sym->getType(BV.getContext());
- return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
+
+ RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
+
+ // Special case: references are known to be non-zero.
+ if (T->isReferenceType()) {
+ APSIntType IntType = BV.getAPSIntType(T);
+ Result = Result.Intersect(BV, F, ++IntType.getZeroValue(),
+ --IntType.getZeroValue());
+ }
+
+ return Result;
}
//===------------------------------------------------------------------------===
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index 0f675cdba7..5568f1ca55 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -84,9 +84,14 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
const SubRegion *SubR = dyn_cast<SubRegion>(R);
while (SubR) {
- if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
- return assumeAuxForSymbol(state, SymR->getSymbol(), Assumption);
-
+ // FIXME: now we only find the first symbolic region.
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
+ const llvm::APSInt &zero = getBasicVals().getZeroWithPtrWidth();
+ if (Assumption)
+ return assumeSymNE(state, SymR->getSymbol(), zero, zero);
+ else
+ return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
+ }
SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
}
@@ -133,13 +138,10 @@ SimpleConstraintManager::assumeAuxForSymbol(ProgramStateRef State,
BasicValueFactory &BVF = getBasicVals();
QualType T = Sym->getType(BVF.getContext());
- // Don't do anything if this isn't a type we can constrain.
- if (!(T->isIntegralOrEnumerationType() || Loc::isLocType(T)))
+ // None of the constraint solvers currently support non-integer types.
+ if (!T->isIntegerType())
return State;
- if (T->isReferenceType())
- return Assumption ? State : NULL;
-
const llvm::APSInt &zero = BVF.getValue(0, T);
if (Assumption)
return assumeSymNE(State, Sym, zero, zero);
@@ -159,6 +161,8 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
return assumeAuxForSymbol(state, sym, Assumption);
}
+ BasicValueFactory &BasicVals = getBasicVals();
+
switch (Cond.getSubKind()) {
default:
llvm_unreachable("'Assume' not implemented for this NonLoc");
@@ -181,9 +185,12 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
BinaryOperator::Opcode op = SE->getOpcode();
// Implicitly compare non-comparison expressions to 0.
- if (!BinaryOperator::isComparisonOp(op))
- return assumeAuxForSymbol(state, SE, Assumption);
-
+ if (!BinaryOperator::isComparisonOp(op)) {
+ QualType T = SE->getType(BasicVals.getContext());
+ const llvm::APSInt &zero = BasicVals.getValue(0, T);
+ op = (Assumption ? BO_NE : BO_EQ);
+ return assumeSymRel(state, SE, op, zero);
+ }
// From here on out, op is the real comparison we'll be testing.
if (!Assumption)
op = NegateComparison(op);
@@ -231,25 +238,8 @@ ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef state,
BasicValueFactory &BVF = getBasicVals();
ASTContext &Ctx = BVF.getContext();
- // Special case for references, which cannot be null.
- QualType Ty = LHS->getType(Ctx);
- if (Ty->isReferenceType() && Int == 0) {
- switch (op) {
- case BO_EQ:
- case BO_LE:
- case BO_LT:
- return NULL;
- case BO_NE:
- case BO_GT:
- case BO_GE:
- return state;
- default:
- llvm_unreachable("We should only be handling comparisons here.");
- }
- }
-
// Get the type used for calculating wraparound.
- APSIntType WraparoundType = BVF.getAPSIntType(Ty);
+ APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType(Ctx));
// We only handle simple comparisons of the form "$sym == constant"
// or "($sym+constant1) == constant2".
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index f6200c5d38..657795f382 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -118,9 +118,6 @@ void testReferenceAddress(int &x) {
extern S *getS();
clang_analyzer_eval(&getS()->x != 0); // expected-warning{{TRUE}}
-
- // This actually takes a different path, because it's not a BinaryOperator.
- clang_analyzer_eval(&getS()->x); // expected-warning{{TRUE}}
}