diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-03-05 23:57:14 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-03-05 23:57:14 +0000 |
commit | e4d653b5a4cba281502177f6ef03d43e3ebb2b6a (patch) | |
tree | 50186520e83c63a188f58563e79043af27b6a99e /lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | |
parent | 8fbb4e665dda8227f369877c11828e4402c48eba (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.cpp | 20 |
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)) { |