aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-03-05 23:57:14 +0000
committerTed Kremenek <kremenek@apple.com>2012-03-05 23:57:14 +0000
commite4d653b5a4cba281502177f6ef03d43e3ebb2b6a (patch)
tree50186520e83c63a188f58563e79043af27b6a99e /lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
parent8fbb4e665dda8227f369877c11828e4402c48eba (diff)
Teak CallAndMessageChecker to only warn about uninitialized struct fields in call arguments
when the called function is never inlined. Fixes <rdar://problem/10977037>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152073 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp20
1 files changed, 18 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 3a4c15f0d2..de48769d78 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -44,7 +44,10 @@ private:
static void PreVisitProcessArgs(CheckerContext &C,CallOrObjCMessage callOrMsg,
const char *BT_desc, OwningPtr<BugType> &BT);
static bool PreVisitProcessArg(CheckerContext &C, SVal V,SourceRange argRange,
- const Expr *argEx, const char *BT_desc, OwningPtr<BugType> &BT);
+ const Expr *argEx,
+ const bool checkUninitFields,
+ const char *BT_desc,
+ OwningPtr<BugType> &BT);
static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
void emitNilReceiverBug(CheckerContext &C, const ObjCMessage &msg,
@@ -77,9 +80,19 @@ void CallAndMessageChecker::PreVisitProcessArgs(CheckerContext &C,
CallOrObjCMessage callOrMsg,
const char *BT_desc,
OwningPtr<BugType> &BT) {
+ // Don't check for uninitialized field values in arguments if the
+ // caller has a body that is available and we have the chance to inline it.
+ // This is a hack, but is a reasonable compromise betweens sometimes warning
+ // and sometimes not depending on if we decide to inline a function.
+ const Decl *D = callOrMsg.getDecl();
+ const bool checkUninitFields =
+ !(C.getAnalysisManager().shouldInlineCall() &&
+ (D && D->getBody()));
+
for (unsigned i = 0, e = callOrMsg.getNumArgs(); i != e; ++i)
if (PreVisitProcessArg(C, callOrMsg.getArgSVal(i),
callOrMsg.getArgSourceRange(i), callOrMsg.getArg(i),
+ checkUninitFields,
BT_desc, BT))
return;
}
@@ -87,9 +100,9 @@ void CallAndMessageChecker::PreVisitProcessArgs(CheckerContext &C,
bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
SVal V, SourceRange argRange,
const Expr *argEx,
+ const bool checkUninitFields,
const char *BT_desc,
OwningPtr<BugType> &BT) {
-
if (V.isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
LazyInit_BT(BT_desc, BT);
@@ -104,6 +117,9 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
return true;
}
+ if (!checkUninitFields)
+ return false;
+
if (const nonloc::LazyCompoundVal *LV =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {