aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Core/BasicConstraintManager.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp48
-rw-r--r--test/Analysis/reference.cpp3
4 files changed, 33 insertions, 35 deletions
diff --git a/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp b/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
index fb6d4be09d..9a3c5d1922 100644
--- a/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
@@ -363,11 +363,6 @@ const llvm::APSInt* BasicConstraintManager::getSymVal(ProgramStateRef state,
bool BasicConstraintManager::isNotEqual(ProgramStateRef state,
SymbolRef sym,
const llvm::APSInt& V) const {
- // Special case: references are known to be non-zero.
- if (sym->getType(getBasicVals().getContext())->isReferenceType())
- if (V == 0)
- return true;
-
// Retrieve the NE-set associated with the given symbol.
const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 2b883cf9b9..550404a510 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -380,17 +380,7 @@ RangeConstraintManager::GetRange(ProgramStateRef state, SymbolRef sym) {
// given symbol type.
BasicValueFactory &BV = getBasicVals();
QualType T = sym->getType(BV.getContext());
-
- 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;
+ return RangeSet(F, BV.getMinValue(T), BV.getMaxValue(T));
}
//===------------------------------------------------------------------------===
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".
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index d901bfee8a..f9a7e664d8 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -119,6 +119,9 @@ 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}}
}