summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-08-28 17:07:04 +0000
committerJordan Rose <jordan_rose@apple.com>2013-08-28 17:07:04 +0000
commit3aa6f431897edf5fec32cbede8fcddbfb8fa16f7 (patch)
treeae2749ffab803aaec5bc94f043f174c255c5a328 /lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
parentf54617858a0df936746b7f521a8ffb032289d02f (diff)
downloadclang-3aa6f431897edf5fec32cbede8fcddbfb8fa16f7.tar.gz
[analyzer] Add support for testing the presence of weak functions.
When casting the address of a FunctionTextRegion to bool, or when adding constraints to such an address, use a stand-in symbol to represent the presence or absence of the function if the function is weakly linked. This is groundwork for possible simple availability testing checks, and can already catch mistakes involving inverted null checks for weakly-linked functions. Currently, the implementation reuses the "extent" symbols, originally created for tracking the size of a malloc region. Since FunctionTextRegions cannot be dereferenced, the extent symbol will never be used for anything else. Still, this probably deserves a refactoring in the future. This patch does not attempt to support testing the presence of weak /variables/ (global variables), which would likely require much more of a change and a generalization of "region structure metadata", like the current "extents", vs. "region contents metadata", like CStringChecker's "string length". Patch by Richard <tarka.t.otter@googlemail.com>! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189492 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp59
1 files changed, 14 insertions, 45 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index a06268dd33..e6653ae6e4 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -68,51 +68,20 @@ bool SimpleConstraintManager::canReasonAbout(SVal X) const {
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
DefinedSVal Cond,
bool Assumption) {
- if (Optional<NonLoc> NV = Cond.getAs<NonLoc>())
- return assume(state, *NV, Assumption);
- return assume(state, Cond.castAs<Loc>(), Assumption);
-}
-
-ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state, Loc cond,
- bool assumption) {
- state = assumeAux(state, cond, assumption);
- if (NotifyAssumeClients && SU)
- return SU->processAssume(state, cond, assumption);
- return state;
-}
-
-ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
- Loc Cond, bool Assumption) {
- switch (Cond.getSubKind()) {
- default:
- assert (false && "'Assume' not implemented for this Loc.");
- return state;
-
- case loc::MemRegionKind: {
- // FIXME: Should this go into the storemanager?
- const MemRegion *R = Cond.castAs<loc::MemRegionVal>().getRegion();
-
- // FIXME: now we only find the first symbolic region.
- if (const SymbolicRegion *SymR = R->getSymbolicBase()) {
- const llvm::APSInt &zero = getBasicVals().getZeroWithPtrWidth();
- if (Assumption)
- return assumeSymNE(state, SymR->getSymbol(), zero, zero);
- else
- return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
- }
-
- // FALL-THROUGH.
+ // If we have a Loc value, cast it to a bool NonLoc first.
+ if (Optional<Loc> LV = Cond.getAs<Loc>()) {
+ SValBuilder &SVB = state->getStateManager().getSValBuilder();
+ QualType T;
+ const MemRegion *MR = LV->getAsRegion();
+ if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
+ T = TR->getLocationType();
+ else
+ T = SVB.getContext().VoidPtrTy;
+
+ Cond = SVB.evalCast(*LV, SVB.getContext().BoolTy, T).castAs<DefinedSVal>();
}
- case loc::GotoLabelKind:
- return Assumption ? state : NULL;
-
- case loc::ConcreteIntKind: {
- bool b = Cond.castAs<loc::ConcreteInt>().getValue() != 0;
- bool isFeasible = b ? Assumption : !Assumption;
- return isFeasible ? state : NULL;
- }
- } // end switch
+ return assume(state, Cond.castAs<NonLoc>(), Assumption);
}
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
@@ -216,8 +185,8 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
}
case nonloc::LocAsIntegerKind:
- return assumeAux(state, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
- Assumption);
+ return assume(state, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
+ Assumption);
} // end switch
}