зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
153f8ecb51
Коммит
efb3d56720
|
@ -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}}
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче