[cfe-commits] r89519 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp lib/Analysis/GRExprEngineInternalChecks.cpp lib/Analysis/UndefinedArgChecker.cpp test/Analysis/misc-ps.m

Ted Kremenek kremenek at apple.com
Fri Nov 20 16:49:42 PST 2009


Author: kremenek
Date: Fri Nov 20 18:49:41 2009
New Revision: 89519

URL: http://llvm.org/viewvc/llvm-project?rev=89519&view=rev
Log:
More checker refactoring.  Passing undefined values in a message expression is now handled by UndefinedArgChecker.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
    cfe/trunk/lib/Analysis/UndefinedArgChecker.cpp
    cfe/trunk/test/Analysis/misc-ps.m

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=89519&r1=89518&r2=89519&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Nov 20 18:49:41 2009
@@ -89,7 +89,6 @@
 
 public:
   typedef llvm::SmallPtrSet<ExplodedNode*,2> ErrorNodes;
-  typedef llvm::DenseMap<ExplodedNode*, Expr*> UndefArgsTy;
 
   /// NilReceiverStructRetExplicit - Nodes in the ExplodedGraph that resulted
   ///  from [x ...] with 'x' definitely being nil and the result was a 'struct'
@@ -131,11 +130,6 @@
   ///  ObjC message expressions where the receiver is undefined (uninitialized).
   ErrorNodes UndefReceivers;
 
-  /// MsgExprUndefArgs - Nodes in the ExplodedGraph resulting from
-  ///   message expressions where a pass-by-value argument has an undefined
-  ///  value.
-  UndefArgsTy MsgExprUndefArgs;
-
 public:
   GRExprEngine(AnalysisManager &mgr);
 
@@ -229,14 +223,6 @@
   undef_result_iterator undef_results_begin() { return UndefResults.begin(); }
   undef_result_iterator undef_results_end() { return UndefResults.end(); }
 
-  typedef UndefArgsTy::iterator undef_arg_iterator;
-  undef_arg_iterator msg_expr_undef_arg_begin() {
-    return MsgExprUndefArgs.begin();
-  }
-  undef_arg_iterator msg_expr_undef_arg_end() {
-    return MsgExprUndefArgs.end();
-  }
-
   typedef ErrorNodes::iterator undef_receivers_iterator;
 
   undef_receivers_iterator undef_receivers_begin() {

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=89519&r1=89518&r2=89519&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Nov 20 18:49:41 2009
@@ -1998,26 +1998,6 @@
     }
   }
 
-  // Check for any arguments that are uninitialized/undefined.
-
-  for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
-       I != E; ++I) {
-
-    if (state->getSVal(*I).isUndef()) {
-
-      // Generate an error node for passing an uninitialized/undefined value
-      // as an argument to a message expression.  This node is a sink.
-      ExplodedNode* N = Builder->generateNode(ME, state, Pred);
-
-      if (N) {
-        N->markAsSink();
-        MsgExprUndefArgs[N] = *I;
-      }
-
-      return;
-    }
-  }
-
   // Handle previsits checks.
   ExplodedNodeSet Src, DstTmp;
   Src.Add(Pred);  

Modified: cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp?rev=89519&r1=89518&r2=89519&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Fri Nov 20 18:49:41 2009
@@ -34,11 +34,6 @@
   return *I;
 }
 
-template <> inline
-ExplodedNode* GetNode(GRExprEngine::undef_arg_iterator I) {
-  return I->first;
-}
-
 //===----------------------------------------------------------------------===//
 // Bug Descriptions.
 //===----------------------------------------------------------------------===//
@@ -224,39 +219,6 @@
   const Stmt *getArg() const { return Arg; }
 };
 
-class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
-public:
-  BadArg(GRExprEngine* eng=0) : BuiltinBug(eng,"Uninitialized argument",
-    "Pass-by-value argument in function call is undefined") {}
-
-  BadArg(GRExprEngine* eng, const char* d)
-    : BuiltinBug(eng,"Uninitialized argument", d) {}
-
-  void registerInitialVisitors(BugReporterContext& BRC,
-                               const ExplodedNode* N,
-                               BuiltinBugReport *R) {
-    registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
-                                  N);
-  }
-};
-
-class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
-public:
-  BadMsgExprArg(GRExprEngine* eng)
-    : BadArg(eng,"Pass-by-value argument in message expression is undefined"){}
-
-  void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
-    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
-         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
-      // Generate a report for this bug.
-      ArgReport *report = new ArgReport(*this, desc.c_str(), I->first,
-                                        I->second);
-      report->addRange(I->second->getSourceRange());
-      BR.EmitReport(report);
-    }
-  }
-};
-
 class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
 public:
   BadReceiver(GRExprEngine* eng)
@@ -375,7 +337,6 @@
   // to 'FlushReports' from BugReporter.
   BR.Register(new UndefBranch(this));
   BR.Register(new UndefResult(this));
-  BR.Register(new BadMsgExprArg(this));
   BR.Register(new BadReceiver(this));
   BR.Register(new NilReceiverStructRet(this));
   BR.Register(new NilReceiverLargerThanVoidPtrRet(this));

Modified: cfe/trunk/lib/Analysis/UndefinedArgChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UndefinedArgChecker.cpp?rev=89519&r1=89518&r2=89519&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/UndefinedArgChecker.cpp (original)
+++ cfe/trunk/lib/Analysis/UndefinedArgChecker.cpp Fri Nov 20 18:49:41 2009
@@ -21,14 +21,16 @@
 namespace {
 class VISIBILITY_HIDDEN UndefinedArgChecker
   : public CheckerVisitor<UndefinedArgChecker> {
-  BugType *BT;
+  BugType *BT_call;
+  BugType *BT_msg;
 public:
-  UndefinedArgChecker() : BT(0) {}
+  UndefinedArgChecker() : BT_call(0), BT_msg(0) {}
   static void *getTag() {
     static int x = 0;
     return &x;
   }
   void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
+  void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);
 };
 } // end anonymous namespace
 
@@ -42,14 +44,40 @@
        I != E; ++I) {
     if (C.getState()->getSVal(*I).isUndef()) {
       if (ExplodedNode *N = C.GenerateNode(CE, true)) {
-        if (!BT)
-          BT = new BuiltinBug("Pass-by-value argument in function call is "
-                              "undefined");
+        if (!BT_call)
+          BT_call = new BuiltinBug("Pass-by-value argument in function call is "
+                                   "undefined");
         // Generate a report for this bug.
-        EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
+        EnhancedBugReport *R = new EnhancedBugReport(*BT_call,
+                                                     BT_call->getName(), N);
         R->addRange((*I)->getSourceRange());
         R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, *I);
         C.EmitReport(R);
+        return;
+      }
+    }
+  }
+}
+
+void UndefinedArgChecker::PreVisitObjCMessageExpr(CheckerContext &C,
+                                                  const ObjCMessageExpr *ME) {
+
+  // Check for any arguments that are uninitialized/undefined.
+  const GRState *state = C.getState();
+  for (ObjCMessageExpr::const_arg_iterator I = ME->arg_begin(), E = ME->arg_end();
+       I != E; ++I) {
+    if (state->getSVal(*I).isUndef()) {
+      if (ExplodedNode *N = C.GenerateNode(ME, true)) {
+        if (!BT_msg)
+          BT_msg = new BuiltinBug("Pass-by-value argument in message expression"
+                                  " is undefined");      
+        // Generate a report for this bug.
+        EnhancedBugReport *R = new EnhancedBugReport(*BT_msg, BT_msg->getName(),
+                                                     N);
+        R->addRange((*I)->getSourceRange());
+        R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, *I);
+        C.EmitReport(R);
+        return;
       }
     }
   }

Modified: cfe/trunk/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=89519&r1=89518&r2=89519&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/misc-ps.m (original)
+++ cfe/trunk/test/Analysis/misc-ps.m Fri Nov 20 18:49:41 2009
@@ -750,3 +750,23 @@
   int *p = &a[i]; // expected-warning{{Array subscript is undefined}}
 }
 @end
+
+//===----------------------------------------------------------------------===//
+// Test passing an undefined value in a message or function call.
+//===----------------------------------------------------------------------===//
+
+void test_bad_call_aux(int x);
+void test_bad_call(void) {
+  int y;
+  test_bad_call_aux(y); // expected-warning{{Pass-by-value argument in function call is undefined}}
+}
+
+ at interface TestBadArg {}
+- (void) testBadArg:(int) x;
+ at end
+
+void test_bad_msg(TestBadArg *p) {
+  int y;
+  [p testBadArg:y]; // expected-warning{{Pass-by-value argument in message expression is undefined}}
+}
+





More information about the cfe-commits mailing list