diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-08-22 19:58:20 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-08-22 19:58:20 +0000 |
commit | 326702f1a10db99ac7a25dfbe40d5dd0d7d66609 (patch) | |
tree | 0eb547bb6e258b39403c14143c5a835d124c2df1 /clang | |
parent | a766697f4e0f18c74c8cbd9f3813082cff08e18b (diff) | |
download | bcm5719-llvm-326702f1a10db99ac7a25dfbe40d5dd0d7d66609.tar.gz bcm5719-llvm-326702f1a10db99ac7a25dfbe40d5dd0d7d66609.zip |
Despite me asking Jordan to do r162313, revert it. We can provide
another way to whitelist these special cases. This is an intermediate patch.
llvm-svn: 162386
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp | 12 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp | 48 | ||||
-rw-r--r-- | clang/test/Analysis/reference.cpp | 3 |
3 files changed, 30 insertions, 33 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index 550404a5107..2b883cf9b9b 100644 --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/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/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp index 0f675cdba7a..5568f1ca555 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp +++ b/clang/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/clang/test/Analysis/reference.cpp b/clang/test/Analysis/reference.cpp index f6200c5d386..657795f3828 100644 --- a/clang/test/Analysis/reference.cpp +++ b/clang/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}} } |