summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-21 20:52:19 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-21 20:52:19 +0000
commit58fc86d68d53eb6c47cc34974b6f37627a5f386c (patch)
tree7de669d7b0955cbe94c4808e3eaa60dbbf8b1d80 /lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
parent51a6b3f58b0dbbc51a77b8f4a509720954406ceb (diff)
downloadclang-58fc86d68d53eb6c47cc34974b6f37627a5f386c.tar.gz
[analyzer] Push "references are non-null" knowledge up to the common parent.
This reduces duplication across the Basic and Range constraint managers, and keeps their internals free of dealing with the semantics of C++. It's still a little unfortunate that the constraint manager is dealing with this at all, but this is pretty much the only place to put it so that it will apply to all symbolic values, even when embedded in larger expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162313 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index 5568f1ca55..0f675cdba7 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -84,14 +84,9 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
const SubRegion *SubR = dyn_cast<SubRegion>(R);
while (SubR) {
- // 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);
- }
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
+ return assumeAuxForSymbol(state, SymR->getSymbol(), Assumption);
+
SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
}
@@ -138,10 +133,13 @@ SimpleConstraintManager::assumeAuxForSymbol(ProgramStateRef State,
BasicValueFactory &BVF = getBasicVals();
QualType T = Sym->getType(BVF.getContext());
- // None of the constraint solvers currently support non-integer types.
- if (!T->isIntegerType())
+ // Don't do anything if this isn't a type we can constrain.
+ if (!(T->isIntegralOrEnumerationType() || Loc::isLocType(T)))
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);
@@ -161,8 +159,6 @@ 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");
@@ -185,12 +181,9 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
BinaryOperator::Opcode op = SE->getOpcode();
// Implicitly compare non-comparison expressions to 0.
- 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);
- }
+ if (!BinaryOperator::isComparisonOp(op))
+ return assumeAuxForSymbol(state, SE, Assumption);
+
// From here on out, op is the real comparison we'll be testing.
if (!Assumption)
op = NegateComparison(op);
@@ -238,8 +231,25 @@ 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(LHS->getType(Ctx));
+ APSIntType WraparoundType = BVF.getAPSIntType(Ty);
// We only handle simple comparisons of the form "$sym == constant"
// or "($sym+constant1) == constant2".