[cfe-commits] r152073 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp test/Analysis/inline.c

Ted Kremenek kremenek at apple.com
Mon Mar 5 15:57:15 PST 2012


Author: kremenek
Date: Mon Mar  5 17:57:14 2012
New Revision: 152073

URL: http://llvm.org/viewvc/llvm-project?rev=152073&view=rev
Log:
Teak CallAndMessageChecker to only warn about uninitialized struct fields in call arguments
when the called function is never inlined.

Fixes <rdar://problem/10977037>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
    cfe/trunk/test/Analysis/inline.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=152073&r1=152072&r2=152073&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Mon Mar  5 17:57:14 2012
@@ -44,7 +44,10 @@
   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 @@
                                                 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 @@
 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 @@
     return true;
   }
 
+  if (!checkUninitFields)
+    return false;
+  
   if (const nonloc::LazyCompoundVal *LV =
         dyn_cast<nonloc::LazyCompoundVal>(&V)) {
 

Modified: cfe/trunk/test/Analysis/inline.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.c?rev=152073&r1=152072&r2=152073&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.c (original)
+++ cfe/trunk/test/Analysis/inline.c Mon Mar  5 17:57:14 2012
@@ -77,3 +77,16 @@
   return x; // expected-warning {{stack memory associated}}
 }
 
+// Test that passing a struct value with an uninitialized field does
+// not trigger a warning if we are inlining and the body is available.
+struct rdar10977037 { int x, y; };
+int test_rdar10977037_aux(struct rdar10977037 v) { return v.y; }
+int test_rdar10977037_aux_2(struct rdar10977037 v);
+int test_rdar10977037() {
+  struct rdar10977037 v;
+  v.y = 1;
+  v. y += test_rdar10977037_aux(v); // no-warning
+  return test_rdar10977037_aux_2(v); // expected-warning {{Passed-by-value struct argument contains uninitialized data}}
+}
+
+





More information about the cfe-commits mailing list