diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/BasicConstraintManager.cpp | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp | 48 | ||||
-rw-r--r-- | test/Analysis/reference.cpp | 3 |
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}} } |