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
This commit is contained in:
Ted Kremenek 2012-08-22 19:58:20 +00:00
Родитель 153f8ecb51
Коммит efb3d56720
3 изменённых файлов: 30 добавлений и 33 удалений

Просмотреть файл

@ -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;
}
//===------------------------------------------------------------------------===

Просмотреть файл

@ -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".

Просмотреть файл

@ -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}}
}