]> granicus.if.org Git - clang/commitdiff
[analyzer] Finish replacing ObjCMessage with ObjCMethodDecl and friends.
authorJordan Rose <jordan_rose@apple.com>
Mon, 2 Jul 2012 19:28:04 +0000 (19:28 +0000)
committerJordan Rose <jordan_rose@apple.com>
Mon, 2 Jul 2012 19:28:04 +0000 (19:28 +0000)
The preObjCMessage and postObjCMessage callbacks now take an ObjCMethodCall
argument, which can represent an explicit message send (ObjCMessageSend) or an
implicit message generated by a property access (ObjCPropertyAccess).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159559 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
include/clang/StaticAnalyzer/Core/Checker.h
include/clang/StaticAnalyzer/Core/CheckerManager.h
include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h [deleted file]
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
lib/StaticAnalyzer/Checkers/MallocChecker.cpp
lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
lib/StaticAnalyzer/Core/Calls.cpp
lib/StaticAnalyzer/Core/CheckerManager.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Core/ExprEngineObjC.cpp

index fb224ef1587deda6483aacdefc375710bbe8743f..07a1ccff6c793074854c3db0336b4bce2d7399a0 100644 (file)
@@ -122,7 +122,7 @@ public:
 
 class PreObjCMessage {
   template <typename CHECKER>
-  static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
+  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
                                 CheckerContext &C) {
     ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
   }
@@ -137,7 +137,7 @@ public:
 
 class PostObjCMessage {
   template <typename CHECKER>
-  static void _checkObjCMessage(void *checker, const ObjCMessage &msg,
+  static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
                                 CheckerContext &C) {
     ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
   }
index 3202fbe6b8adeda90a4c625a6e45a1bbd2c9374d..eef82fe84830688ecb344a7d79b564e3428e0c53 100644 (file)
@@ -33,7 +33,7 @@ namespace ento {
   class AnalysisManager;
   class BugReporter;
   class CheckerContext;
-  class ObjCMessage;
+  class ObjCMethodCall;
   class SVal;
   class ExplodedNode;
   class ExplodedNodeSet;
@@ -207,7 +207,7 @@ public:
   /// \brief Run checkers for pre-visiting obj-c messages.
   void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
                                     const ExplodedNodeSet &Src,
-                                    const ObjCMessage &msg,
+                                    const ObjCMethodCall &msg,
                                     ExprEngine &Eng) {
     runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
   }
@@ -215,7 +215,7 @@ public:
   /// \brief Run checkers for post-visiting obj-c messages.
   void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
                                      const ExplodedNodeSet &Src,
-                                     const ObjCMessage &msg,
+                                     const ObjCMethodCall &msg,
                                      ExprEngine &Eng) {
     runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
   }
@@ -224,7 +224,7 @@ public:
   void runCheckersForObjCMessage(bool isPreVisit,
                                  ExplodedNodeSet &Dst,
                                  const ExplodedNodeSet &Src,
-                                 const ObjCMessage &msg, ExprEngine &Eng);
+                                 const ObjCMethodCall &msg, ExprEngine &Eng);
 
   /// \brief Run checkers for load/store of a location.
   void runCheckersForLocation(ExplodedNodeSet &Dst,
@@ -343,7 +343,7 @@ public:
 
   typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
   
-  typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
+  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
       CheckObjCMessageFunc;
   
   typedef CheckerFn<void (const SVal &location, bool isLoad,
index fdfb485a52c7d774bc26eae5ddd6b66bb07d537c..a16eb4afef109198352a7b53cbe6195ab0bffb34 100644 (file)
@@ -20,8 +20,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 
 namespace clang {
@@ -114,6 +113,10 @@ public:
   /// \brief Returns the kind of call this is.
   Kind getKind() const { return K; }
 
+  /// \brief Returns a source range for the entire call, suitable for
+  /// outputting in diagnostics.
+  virtual SourceRange getSourceRange() const = 0;
+
   /// \brief Returns the value of a given argument at the time of the call.
   virtual SVal getArgSVal(unsigned Index) const;
 
@@ -213,6 +216,7 @@ public:
   const FunctionDecl *getDecl() const;
 
   unsigned getNumArgs() const { return CE->getNumArgs(); }
+  SourceRange getSourceRange() const { return CE->getSourceRange(); }
   
   const Expr *getArgExpr(unsigned Index) const {
     return CE->getArg(Index);
@@ -305,6 +309,7 @@ public:
     : AnyFunctionCall(St, LCtx, CE_CXXConstructor), CE(ce), Target(target) {}
 
   const CXXConstructExpr *getOriginExpr() const { return CE; }
+  SourceRange getSourceRange() const { return CE->getSourceRange(); }
 
   const CXXConstructorDecl *getDecl() const {
     return CE->getConstructor();
@@ -341,7 +346,9 @@ public:
   Selector getSelector() const { return Msg->getSelector(); }
   bool isInstanceMessage() const { return Msg->isInstanceMessage(); }
   ObjCMethodFamily getMethodFamily() const { return Msg->getMethodFamily(); }
+
   const ObjCMethodDecl *getDecl() const { return Msg->getMethodDecl(); }
+  SourceRange getSourceRange() const { return Msg->getSourceRange(); }
   unsigned getNumArgs() const { return Msg->getNumArgs(); }
   const Expr *getArgExpr(unsigned Index) const {
     return Msg->getArg(Index);
@@ -351,6 +358,10 @@ public:
 
   SVal getReceiverSVal() const;
 
+  const Expr *getInstanceReceiverExpr() const {
+    return Msg->getInstanceReceiver();
+  }
+
   const ObjCInterfaceDecl *getReceiverInterface() const {
     return Msg->getReceiverInterface();
   }
@@ -359,11 +370,6 @@ public:
     return Msg->getReceiverRange();
   }
 
-  // FIXME: Remove this once everything is converted to use ObjCMethodCall.
-  virtual operator ObjCMessage() const {
-    return ObjCMessage(Msg);
-  }
-
   static bool classof(const CallEvent *CA) {
     return CA->getKind() >= CE_BEG_OBJC_CALLS &&
            CA->getKind() <= CE_END_OBJC_CALLS;
@@ -389,20 +395,23 @@ public:
 /// Example: obj.prop += 1;
 class ObjCPropertyAccess : public ObjCMethodCall {
   const ObjCPropertyRefExpr *PropE;
+  SourceRange EntireRange;
 
 public:
-  ObjCPropertyAccess(const ObjCPropertyRefExpr *pe, const ObjCMessageExpr *Msg,
-                     const ProgramStateRef St, const LocationContext *LCtx)
-    : ObjCMethodCall(Msg, St, LCtx, CE_ObjCPropertyAccess), PropE(pe) {}
+  ObjCPropertyAccess(const ObjCPropertyRefExpr *pe, SourceRange range,
+                     const ObjCMessageExpr *Msg, const ProgramStateRef St,
+                     const LocationContext *LCtx)
+    : ObjCMethodCall(Msg, St, LCtx, CE_ObjCPropertyAccess), PropE(pe),
+      EntireRange(range)
+    {}
 
   /// \brief Returns true if this property access is calling the setter method.
   bool isSetter() const {
     return getNumArgs() > 0;
   }
 
-  // FIXME: Remove this once everything is converted to use ObjCMethodCall.
-  operator ObjCMessage() const {
-    return ObjCMessage(getOriginExpr(), PropE, isSetter());
+  SourceRange getSourceRange() const {
+    return EntireRange;
   }
 
   static bool classof(const CallEvent *CA) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
deleted file mode 100644 (file)
index f64326d..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-//===- ObjCMessage.h - Wrapper for ObjC messages and dot syntax ---*- C++ -*--//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines ObjCMessage which serves as a common wrapper for ObjC
-// message expressions or implicit messages for loading/storing ObjC properties.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE
-#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_OBJCMESSAGE
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Compiler.h"
-
-namespace clang {
-namespace ento {
-using llvm::StrInStrNoCase;
-
-/// \brief Represents both explicit ObjC message expressions and implicit
-/// messages that are sent for handling properties in dot syntax.
-class ObjCMessage {
-  const ObjCMessageExpr *Msg;
-  const ObjCPropertyRefExpr *PE;
-  const bool IsPropSetter;
-public:
-  ObjCMessage() : Msg(0), PE(0), IsPropSetter(false) {}
-
-  ObjCMessage(const ObjCMessageExpr *E, const ObjCPropertyRefExpr *pe = 0,
-              bool isSetter = false)
-    : Msg(E), PE(pe), IsPropSetter(isSetter) {
-    assert(E && "should not be initialized with null expression");
-  }
-
-  bool isValid() const { return Msg; }
-  
-  bool isPureMessageExpr() const { return !PE; }
-
-  bool isPropertyGetter() const { return PE && !IsPropSetter; }
-
-  bool isPropertySetter() const {
-    return IsPropSetter;
-  }
-
-  const ObjCMessageExpr *getMessageExpr() const {
-    return Msg;
-  }
-
-  QualType getType(ASTContext &ctx) const {
-    return Msg->getType();
-  }
-
-  QualType getResultType(ASTContext &ctx) const {
-    if (const ObjCMethodDecl *MD = Msg->getMethodDecl())
-      return MD->getResultType();
-    return getType(ctx);
-  }
-
-  ObjCMethodFamily getMethodFamily() const {
-    return Msg->getMethodFamily();
-  }
-
-  Selector getSelector() const {
-    return Msg->getSelector();
-  }
-
-  const Expr *getInstanceReceiver() const {
-    return Msg->getInstanceReceiver();
-  }
-
-  SVal getInstanceReceiverSVal(ProgramStateRef State,
-                               const LocationContext *LC) const {
-    if (!isInstanceMessage())
-      return UndefinedVal();
-    if (const Expr *Ex = getInstanceReceiver())
-      return State->getSValAsScalarOrLoc(Ex, LC);
-
-    // An instance message with no expression means we are sending to super.
-    // In this case the object reference is the same as 'self'.
-    const ImplicitParamDecl *SelfDecl = LC->getSelfDecl();
-    assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
-    return State->getSVal(State->getRegion(SelfDecl, LC));
-  }
-
-  bool isInstanceMessage() const {
-    return Msg->isInstanceMessage();
-  }
-
-  const ObjCMethodDecl *getMethodDecl() const {
-    return Msg->getMethodDecl();
-  }
-
-  const ObjCInterfaceDecl *getReceiverInterface() const {
-    return Msg->getReceiverInterface();
-  }
-
-  SourceLocation getSuperLoc() const {
-    if (PE)
-      return PE->getReceiverLocation();
-    return Msg->getSuperLoc();
-  }  
-
-  SourceRange getSourceRange() const LLVM_READONLY {
-    if (PE)
-      return PE->getSourceRange();
-    return Msg->getSourceRange();
-  }
-
-  unsigned getNumArgs() const {
-    return Msg->getNumArgs();
-  }
-
-  SVal getArgSVal(unsigned i,
-                  const LocationContext *LCtx,
-                  ProgramStateRef state) const {
-    assert(i < getNumArgs() && "Invalid index for argument");
-    return state->getSVal(Msg->getArg(i), LCtx);
-  }
-
-  QualType getArgType(unsigned i) const {
-    assert(i < getNumArgs() && "Invalid index for argument");
-    return Msg->getArg(i)->getType();
-  }
-
-  const Expr *getArgExpr(unsigned i) const {
-    assert(i < getNumArgs() && "Invalid index for argument");
-    return Msg->getArg(i);
-  }
-
-  SourceRange getArgSourceRange(unsigned i) const {
-    const Expr *argE = getArgExpr(i);
-    return argE->getSourceRange();
-  }
-
-  SourceRange getReceiverSourceRange() const {
-    if (PE) {
-      if (PE->isObjectReceiver())
-        return PE->getBase()->getSourceRange();
-    }
-    else {
-      return Msg->getReceiverRange();
-    }
-
-    // FIXME: This isn't a range.
-    return PE->getReceiverLocation();
-  }
-};
-
-}
-}
-
-#endif
index c75c86faf4690b9e0816fa9f8642c869765f8bcd..1d0c4b336b1e824b0aada2fdfe428d18ba0be8d6 100644 (file)
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -46,10 +46,10 @@ public:
 // Utility functions.
 //===----------------------------------------------------------------------===//
 
-static const char* GetReceiverNameType(const ObjCMessage &msg) {
+static StringRef GetReceiverInterfaceName(const ObjCMethodCall &msg) {
   if (const ObjCInterfaceDecl *ID = msg.getReceiverInterface())
-    return ID->getIdentifier()->getNameStart();
-  return 0;
+    return ID->getIdentifier()->getName();
+  return StringRef();
 }
 
 enum FoundationClass {
@@ -95,15 +95,15 @@ namespace {
     mutable OwningPtr<APIMisuse> BT;
 
     void WarnNilArg(CheckerContext &C,
-                    const ObjCMessage &msg, unsigned Arg) const;
+                    const ObjCMethodCall &msg, unsigned Arg) const;
 
   public:
-    void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+    void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
   };
 }
 
 void NilArgChecker::WarnNilArg(CheckerContext &C,
-                               const ObjCMessage &msg,
+                               const ObjCMethodCall &msg,
                                unsigned int Arg) const
 {
   if (!BT)
@@ -112,7 +112,7 @@ void NilArgChecker::WarnNilArg(CheckerContext &C,
   if (ExplodedNode *N = C.generateSink()) {
     SmallString<128> sbuf;
     llvm::raw_svector_ostream os(sbuf);
-    os << "Argument to '" << GetReceiverNameType(msg) << "' method '"
+    os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '"
        << msg.getSelector().getAsString() << "' cannot be nil";
 
     BugReport *R = new BugReport(*BT, os.str(), N);
@@ -121,7 +121,7 @@ void NilArgChecker::WarnNilArg(CheckerContext &C,
   }
 }
 
-void NilArgChecker::checkPreObjCMessage(ObjCMessage msg,
+void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                         CheckerContext &C) const {
   const ObjCInterfaceDecl *ID = msg.getReceiverInterface();
   if (!ID)
@@ -151,7 +151,7 @@ void NilArgChecker::checkPreObjCMessage(ObjCMessage msg,
         Name == "compare:options:range:locale:" ||
         Name == "componentsSeparatedByCharactersInSet:" ||
         Name == "initWithFormat:") {
-      if (isNil(msg.getArgSVal(0, C.getLocationContext(), C.getState())))
+      if (isNil(msg.getArgSVal(0)))
         WarnNilArg(C, msg, 0);
     }
   }
@@ -455,11 +455,11 @@ class ClassReleaseChecker : public Checker<check::PreObjCMessage> {
   mutable OwningPtr<BugType> BT;
 
 public:
-  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
 };
 }
 
-void ClassReleaseChecker::checkPreObjCMessage(ObjCMessage msg,
+void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                               CheckerContext &C) const {
   
   if (!BT) {
@@ -511,18 +511,18 @@ class VariadicMethodTypeChecker : public Checker<check::PreObjCMessage> {
   mutable Selector initWithObjectsAndKeysS;
   mutable OwningPtr<BugType> BT;
 
-  bool isVariadicMessage(const ObjCMessage &msg) const;
+  bool isVariadicMessage(const ObjCMethodCall &msg) const;
 
 public:
-  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
 };
 }
 
 /// isVariadicMessage - Returns whether the given message is a variadic message,
 /// where all arguments must be Objective-C types.
 bool
-VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
-  const ObjCMethodDecl *MD = msg.getMethodDecl();
+VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
+  const ObjCMethodDecl *MD = msg.getDecl();
   
   if (!MD || !MD->isVariadic() || isa<ObjCProtocolDecl>(MD->getDeclContext()))
     return false;
@@ -566,7 +566,7 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMessage &msg) const {
   }
 }
 
-void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
+void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                     CheckerContext &C) const {
   if (!BT) {
     BT.reset(new APIMisuse("Arguments passed to variadic method aren't all "
@@ -602,7 +602,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
   ProgramStateRef state = C.getState();
   
   for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
-    QualType ArgTy = msg.getArgType(I);
+    QualType ArgTy = msg.getArgExpr(I)->getType();
     if (ArgTy->isObjCObjectPointerType())
       continue;
 
@@ -611,8 +611,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
       continue;
 
     // Ignore pointer constants.
-    if (isa<loc::ConcreteInt>(msg.getArgSVal(I, C.getLocationContext(),
-                                             state)))
+    if (isa<loc::ConcreteInt>(msg.getArgSVal(I)))
       continue;
     
     // Ignore pointer types annotated with 'NSObject' attribute.
@@ -624,9 +623,8 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
       continue;
 
     // Generate only one error node to use for all bug reports.
-    if (!errorNode.hasValue()) {
+    if (!errorNode.hasValue())
       errorNode = C.addTransition();
-    }
 
     if (!errorNode.getValue())
       continue;
@@ -634,17 +632,18 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
     SmallString<128> sbuf;
     llvm::raw_svector_ostream os(sbuf);
 
-    if (const char *TypeName = GetReceiverNameType(msg))
+    StringRef TypeName = GetReceiverInterfaceName(msg);
+    if (!TypeName.empty())
       os << "Argument to '" << TypeName << "' method '";
     else
       os << "Argument to method '";
 
     os << msg.getSelector().getAsString() 
-      << "' should be an Objective-C pointer type, not '" 
-      << ArgTy.getAsString() << "'";
+       << "' should be an Objective-C pointer type, not '";
+    ArgTy.print(os, C.getLangOpts());
+    os << "'";
 
-    BugReport *R = new BugReport(*BT, os.str(),
-                                             errorNode.getValue());
+    BugReport *R = new BugReport(*BT, os.str(), errorNode.getValue());
     R->addRange(msg.getArgSourceRange(I));
     C.EmitReport(R);
   }
index 30be60c9a6f9dc64434997006820afe51a7ea7fc..083f21ea3ff979bf95bbb71274637a3dbca50150 100644 (file)
@@ -17,7 +17,6 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/Basic/TargetInfo.h"
@@ -39,7 +38,7 @@ class CallAndMessageChecker
 public:
 
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
-  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
 
 private:
   static void PreVisitProcessArgs(CheckerContext &C, const CallEvent &Call,
@@ -51,12 +50,12 @@ private:
                                  OwningPtr<BugType> &BT);
 
   static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
-  void emitNilReceiverBug(CheckerContext &C, const ObjCMessage &msg,
+  void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
                           ExplodedNode *N) const;
 
   void HandleNilReceiver(CheckerContext &C,
                          ProgramStateRef state,
-                         ObjCMessage msg) const;
+                         const ObjCMethodCall &msg) const;
 
   static void LazyInit_BT(const char *desc, OwningPtr<BugType> &BT) {
     if (!BT)
@@ -248,65 +247,61 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
   }
 }
 
-void CallAndMessageChecker::checkPreObjCMessage(ObjCMessage msg,
+void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                 CheckerContext &C) const {
+  SVal recVal = msg.getReceiverSVal();
+  if (recVal.isUndef()) {
+    if (ExplodedNode *N = C.generateSink()) {
+      BugType *BT = 0;
+      if (isa<ObjCPropertyAccess>(msg)) {
+        if (!BT_objc_prop_undef)
+          BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
+                                                  "uninitialized object pointer"));
+        BT = BT_objc_prop_undef.get();
+      } else {
+        if (!BT_msg_undef)
+          BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
+                                            "is an uninitialized value"));
+        BT = BT_msg_undef.get();
+      }
+      BugReport *R = new BugReport(*BT, BT->getName(), N);
+      R->addRange(msg.getReceiverSourceRange());
 
-  ProgramStateRef state = C.getState();
-  const LocationContext *LCtx = C.getLocationContext();
-
-  // FIXME: Handle 'super'?
-  if (const Expr *receiver = msg.getInstanceReceiver()) {
-    SVal recVal = state->getSVal(receiver, LCtx);
-    if (recVal.isUndef()) {
-      if (ExplodedNode *N = C.generateSink()) {
-        BugType *BT = 0;
-        if (msg.isPureMessageExpr()) {
-          if (!BT_msg_undef)
-            BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
-                                              "is an uninitialized value"));
-          BT = BT_msg_undef.get();
-        }
-        else {
-          if (!BT_objc_prop_undef)
-            BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
-                                              "uninitialized object pointer"));
-          BT = BT_objc_prop_undef.get();
-        }
-        BugReport *R =
-          new BugReport(*BT, BT->getName(), N);
-        R->addRange(receiver->getSourceRange());
+      // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
+      if (const Expr *ReceiverE = msg.getInstanceReceiverExpr())
         R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                   receiver,
+                                                                   ReceiverE,
                                                                    R));
-        C.EmitReport(R);
-      }
+      C.EmitReport(R);
+    }
+    return;
+  } else {
+    // Bifurcate the state into nil and non-nil ones.
+    DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
+
+    ProgramStateRef state = C.getState();
+    ProgramStateRef notNilState, nilState;
+    llvm::tie(notNilState, nilState) = state->assume(receiverVal);
+
+    // Handle receiver must be nil.
+    if (nilState && !notNilState) {
+      HandleNilReceiver(C, state, msg);
       return;
-    } else {
-      // Bifurcate the state into nil and non-nil ones.
-      DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
-  
-      ProgramStateRef notNilState, nilState;
-      llvm::tie(notNilState, nilState) = state->assume(receiverVal);
-  
-      // Handle receiver must be nil.
-      if (nilState && !notNilState) {
-        HandleNilReceiver(C, state, msg);
-        return;
-      }
     }
   }
 
-  const char *bugDesc = msg.isPropertySetter() ?
-                     "Argument for property setter is an uninitialized value"
-                   : "Argument in message expression is an uninitialized value";
+  const char *bugDesc = "Argument in message expression is an "
+                        "uninitialized value";
+  if (const ObjCPropertyAccess *Prop = dyn_cast<ObjCPropertyAccess>(&msg))
+    if (Prop->isSetter())
+      bugDesc = "Argument for property setter is an uninitialized value";
+
   // Check for any arguments that are uninitialized/undefined.
-  // FIXME: ObjCMessage is set to be removed soon.
-  PreVisitProcessArgs(C, ObjCMessageSend(msg.getMessageExpr(), state, LCtx),
-                      bugDesc, BT_msg_arg);
+  PreVisitProcessArgs(C, msg, bugDesc, BT_msg_arg);
 }
 
 void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
-                                               const ObjCMessage &msg,
+                                               const ObjCMethodCall &msg,
                                                ExplodedNode *N) const {
 
   if (!BT_msg_ret)
@@ -317,11 +312,13 @@ void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
   SmallString<200> buf;
   llvm::raw_svector_ostream os(buf);
   os << "The receiver of message '" << msg.getSelector().getAsString()
-     << "' is nil and returns a value of type '"
-     << msg.getType(C.getASTContext()).getAsString() << "' that will be garbage";
+     << "' is nil and returns a value of type '";
+  msg.getResultType().print(os, C.getLangOpts());
+  os << "' that will be garbage";
 
   BugReport *report = new BugReport(*BT_msg_ret, os.str(), N);
-  if (const Expr *receiver = msg.getInstanceReceiver()) {
+  // FIXME: This won't track "self" in messages to super.
+  if (const Expr *receiver = msg.getInstanceReceiverExpr()) {
     report->addRange(receiver->getSourceRange());
     report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
                                                                     receiver,
@@ -338,25 +335,25 @@ static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
 
 void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
                                               ProgramStateRef state,
-                                              ObjCMessage msg) const {
+                                              const ObjCMethodCall &Msg) const {
   ASTContext &Ctx = C.getASTContext();
 
   // Check the return type of the message expression.  A message to nil will
   // return different values depending on the return type and the architecture.
-  QualType RetTy = msg.getType(Ctx);
+  QualType RetTy = Msg.getResultType();
   CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
   const LocationContext *LCtx = C.getLocationContext();
 
   if (CanRetTy->isStructureOrClassType()) {
     // Structure returns are safe since the compiler zeroes them out.
-    SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
-    C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
+    SVal V = C.getSValBuilder().makeZeroVal(RetTy);
+    C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
     return;
   }
 
   // Other cases: check if sizeof(return type) > sizeof(void*)
   if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
-                                  .isConsumedExpr(msg.getMessageExpr())) {
+                                  .isConsumedExpr(Msg.getOriginExpr())) {
     // Compute: sizeof(void *) and sizeof(return type)
     const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
     const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
@@ -369,7 +366,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
            Ctx.LongLongTy == CanRetTy ||
            Ctx.UnsignedLongLongTy == CanRetTy))) {
       if (ExplodedNode *N = C.generateSink(state))
-        emitNilReceiverBug(C, msg, N);
+        emitNilReceiverBug(C, Msg, N);
       return;
     }
 
@@ -386,8 +383,8 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
     // it most likely isn't nil.  We should assume the semantics
     // of this case unless we have *a lot* more knowledge.
     //
-    SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx));
-    C.addTransition(state->BindExpr(msg.getMessageExpr(), LCtx, V));
+    SVal V = C.getSValBuilder().makeZeroVal(RetTy);
+    C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
     return;
   }
 
index 61582d028a617f60c41c02d52684ca7889412e17..751b8f4c8987625c7e28c865ab21a47ee8b48848 100644 (file)
@@ -76,10 +76,10 @@ public:
   void checkPostStmt(const CallExpr *DS, CheckerContext &C) const;
 
   /// \brief Pre-visit the Objective C messages.
-  void checkPreObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const {}
+  void checkPreObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
 
   /// \brief Post-visit the Objective C messages.
-  void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const {}
+  void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const {}
 
   /// \brief Pre-visit of the condition statement of a branch (such as IfStmt).
   void checkBranchCondition(const Stmt *Condition, CheckerContext &Ctx) const {}
index 2c960921a429236c9e351895b8b738c900f6a898..41cd80e01e0b2ef2add916ca2423d3d0ec1d4bf3 100644 (file)
@@ -124,7 +124,7 @@ public:
 
   void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
-  void checkPreObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const;
+  void checkPreObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
   void checkEndPath(CheckerContext &C) const;
@@ -491,29 +491,21 @@ static bool isFreeWhenDoneSetToZero(const ObjCMethodCall &Call) {
   return false;
 }
 
-void MallocChecker::checkPreObjCMessage(const ObjCMessage &Msg,
+void MallocChecker::checkPreObjCMessage(const ObjCMethodCall &Call,
                                         CheckerContext &C) const {
-  const ObjCMethodDecl *MD = Msg.getMethodDecl();
-  if (!MD)
-    return;
-
-  // FIXME: ObjCMessage is going away soon.
-  ObjCMessageSend Call(Msg.getMessageExpr(), C.getState(),
-                       C.getLocationContext());
-  Selector S = Msg.getSelector();
-
   // If the first selector is dataWithBytesNoCopy, assume that the memory will
   // be released with 'free' by the new object.
   // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
   // Unless 'freeWhenDone' param set to 0.
   // TODO: Check that the memory was allocated with malloc.
+  Selector S = Call.getSelector();
   if ((S.getNameForSlot(0) == "dataWithBytesNoCopy" ||
        S.getNameForSlot(0) == "initWithBytesNoCopy" ||
        S.getNameForSlot(0) == "initWithCharactersNoCopy") &&
       !isFreeWhenDoneSetToZero(Call)){
     unsigned int argIdx  = 0;
     C.addTransition(FreeMemAux(C, Call.getArgExpr(argIdx),
-                    Msg.getMessageExpr(), C.getState(), true));
+                    Call.getOriginExpr(), C.getState(), true));
   }
 }
 
index 4989ba88680ebb09b02ba98476878e4d9f8531f2..bc0835a9ed8037388e49d77eddd051556d111b1e 100644 (file)
@@ -20,9 +20,9 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Decl.h"
 
@@ -36,29 +36,20 @@ class NSAutoreleasePoolChecker
   mutable Selector releaseS;
 
 public:
-  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;    
+  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
 };
 
 } // end anonymous namespace
 
-void NSAutoreleasePoolChecker::checkPreObjCMessage(ObjCMessage msg,
+void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                    CheckerContext &C) const {
-  
-  const Expr *receiver = msg.getInstanceReceiver();
-  if (!receiver)
+  if (!msg.isInstanceMessage())
     return;
-  
-  // FIXME: Enhance with value-tracking information instead of consulting
-  // the type of the expression.
-  const ObjCObjectPointerType* PT =
-    receiver->getType()->getAs<ObjCObjectPointerType>();
-  
-  if (!PT)
-    return;  
-  const ObjCInterfaceDecl *OD = PT->getInterfaceDecl();
+
+  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
   if (!OD)
     return;  
-  if (!OD->getIdentifier()->getName().equals("NSAutoreleasePool"))
+  if (!OD->getIdentifier()->isStr("NSAutoreleasePool"))
     return;
 
   if (releaseS.isNull())
index c2d7c09cf3b9a6bbfbce3aae49b92a68c3fd3912..b3b212f8f4ce7854fc4654eb3902e4cf84940b9f 100644 (file)
@@ -15,8 +15,8 @@
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "llvm/ADT/StringSwitch.h"
 #include <cstdarg>
 
@@ -29,7 +29,7 @@ class NoReturnFunctionChecker : public Checker< check::PostStmt<CallExpr>,
                                                 check::PostObjCMessage > {
 public:
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
-  void checkPostObjCMessage(const ObjCMessage &msg, CheckerContext &C) const;
+  void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
 };
 
 }
@@ -98,7 +98,7 @@ static bool END_WITH_NULL isMultiArgSelector(const Selector *Sel, ...) {
   return (Arg == NULL);
 }
 
-void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMessage &Msg,
+void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                                    CheckerContext &C) const {
   // HACK: This entire check is to handle two messages in the Cocoa frameworks:
   // -[NSAssertionHandler
index f4655b6793d25097237b7359c7f4d7653ef303c1..2ab49ed12a142af6d7e50c0f0420ce9c45f350ac 100644 (file)
@@ -21,7 +21,6 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/AST/ParentMap.h"
 
index c25da874051aecd5427648da650c071e36ce820c..40eb381999219556c003766fd52e5af445ffe9f6 100644 (file)
@@ -42,7 +42,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/AST/ParentMap.h"
 
@@ -51,7 +50,7 @@ using namespace ento;
 
 static bool shouldRunOnFunctionOrMethod(const NamedDecl *ND);
 static bool isInitializationMethod(const ObjCMethodDecl *MD);
-static bool isInitMessage(const ObjCMessage &msg);
+static bool isInitMessage(const ObjCMethodCall &Msg);
 static bool isSelfVar(SVal location, CheckerContext &C);
 
 namespace {
@@ -64,8 +63,8 @@ class ObjCSelfInitChecker : public Checker<  check::PreObjCMessage,
                                              check::Location,
                                              check::Bind > {
 public:
-  void checkPreObjCMessage(ObjCMessage msg, CheckerContext &C) const;
-  void checkPostObjCMessage(ObjCMessage msg, CheckerContext &C) const;
+  void checkPreObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
+  void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
   void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -184,7 +183,7 @@ static void checkForInvalidSelf(const Expr *E, CheckerContext &C,
   C.EmitReport(report);
 }
 
-void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
+void ObjCSelfInitChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                                CheckerContext &C) const {
   // When encountering a message that does initialization (init rule),
   // tag the return value so that we know later on that if self has this value
@@ -195,7 +194,7 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
                                 C.getCurrentAnalysisDeclContext()->getDecl())))
     return;
 
-  if (isInitMessage(msg)) {
+  if (isInitMessage(Msg)) {
     // Tag the return value as the result of an initializer.
     ProgramStateRef state = C.getState();
     
@@ -204,15 +203,12 @@ void ObjCSelfInitChecker::checkPostObjCMessage(ObjCMessage msg,
     // value out when we return from this method.
     state = state->set<CalledInit>(true);
     
-    SVal V = state->getSVal(msg.getMessageExpr(), C.getLocationContext());
+    SVal V = state->getSVal(Msg.getOriginExpr(), C.getLocationContext());
     addSelfFlag(state, V, SelfFlag_InitRes, C);
     return;
   }
 
-  // FIXME: ObjCMessage is going away.
-  ObjCMessageSend MsgWrapper(msg.getMessageExpr(), C.getState(),
-                             C.getLocationContext());
-  checkPostStmt(MsgWrapper, C);
+  checkPostStmt(Msg, C);
 
   // We don't check for an invalid 'self' in an obj-c message expression to cut
   // down false positives where logging functions get information from self
@@ -300,12 +296,9 @@ void ObjCSelfInitChecker::checkPostStmt(const CallExpr *CE,
   }
 }
 
-void ObjCSelfInitChecker::checkPreObjCMessage(ObjCMessage Msg,
+void ObjCSelfInitChecker::checkPreObjCMessage(const ObjCMethodCall &Msg,
                                               CheckerContext &C) const {
-  // FIXME: ObjCMessage is going away.
-  ObjCMessageSend MsgWrapper(Msg.getMessageExpr(), C.getState(),
-                             C.getLocationContext());
-  checkPreStmt(MsgWrapper, C);
+  checkPreStmt(Msg, C);
 }
 
 void ObjCSelfInitChecker::checkPreStmt(const CallEvent &CE,
@@ -440,8 +433,8 @@ static bool isInitializationMethod(const ObjCMethodDecl *MD) {
   return MD->getMethodFamily() == OMF_init;
 }
 
-static bool isInitMessage(const ObjCMessage &msg) {
-  return msg.getMethodFamily() == OMF_init;
+static bool isInitMessage(const ObjCMethodCall &Call) {
+  return Call.getMethodFamily() == OMF_init;
 }
 
 //===----------------------------------------------------------------------===//
index 12b74e7e29cff8c276359d6065443a60cec67319..80ebaa2e695e8d98120e77f4f3a63951528f5f5e 100644 (file)
@@ -27,7 +27,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -2530,7 +2529,7 @@ public:
   void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
   void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
 
-  void checkPostObjCMessage(const ObjCMessage &Msg, CheckerContext &C) const;
+  void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
                       
   void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
                     CheckerContext &C) const;
@@ -2792,17 +2791,12 @@ void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
   C.addTransition(State);
 }
 
-void RetainCountChecker::checkPostObjCMessage(const ObjCMessage &Msg, 
+void RetainCountChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                               CheckerContext &C) const {
-  ProgramStateRef state = C.getState();
-  const LocationContext *LC = C.getLocationContext();
-  // FIXME: ObjCMessage is going away.
-  ObjCMessageSend Call(Msg.getMessageExpr(), state, LC);
-
   RetainSummaryManager &Summaries = getSummaryManager(C);
-  const RetainSummary *Summ = Summaries.getSummary(Call, state);
+  const RetainSummary *Summ = Summaries.getSummary(Msg, C.getState());
 
-  checkSummary(*Summ, Call, C);
+  checkSummary(*Summ, Msg, C);
 }
 
 /// GetReturnType - Used to get the return type of a message expression or
index bdd4508ceafc8e29cdab48ca79c03d4f61830971..4fec757e0eec73e09b08b32f8dff46a4ce8e3dc2 100644 (file)
@@ -14,8 +14,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringExtras.h"
 
 using namespace clang;
 using namespace ento;
index b3d93cfe3585e5992adf789fcef272dfa0e1aa56..5cb1b49c1500ae241f93287203e11c4a074f2bf8 100644 (file)
@@ -14,7 +14,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/AST/DeclBase.h"
 
@@ -178,14 +178,14 @@ namespace {
     typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
     bool IsPreVisit;
     const CheckersTy &Checkers;
-    const ObjCMessage &Msg;
+    const ObjCMethodCall &Msg;
     ExprEngine &Eng;
 
     CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
     CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
 
     CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
-                            const ObjCMessage &msg, ExprEngine &eng)
+                            const ObjCMethodCall &msg, ExprEngine &eng)
       : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
@@ -193,7 +193,7 @@ namespace {
       ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
                                            ProgramPoint::PostStmtKind;
       const ProgramPoint &L =
-        ProgramPoint::getProgramPoint(Msg.getMessageExpr(),
+        ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
                                       K, Pred->getLocationContext(),
                                       checkFn.Checker);
       CheckerContext C(Bldr, Eng, Pred, L);
@@ -207,7 +207,7 @@ namespace {
 void CheckerManager::runCheckersForObjCMessage(bool isPreVisit,
                                                ExplodedNodeSet &Dst,
                                                const ExplodedNodeSet &Src,
-                                               const ObjCMessage &msg,
+                                               const ObjCMethodCall &msg,
                                                ExprEngine &Eng) {
   CheckObjCMessageContext C(isPreVisit,
                             isPreVisit ? PreObjCMessageCheckers
index 141c5bbf030a44432baa1abd20bedf20aec424f5..63aa28fa0aab34d6875095b7aff8bfb7f1db6af9 100644 (file)
@@ -20,7 +20,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtObjC.h"
@@ -884,7 +883,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
 
         if (const ObjCPropertyRefExpr *PR =
               dyn_cast<ObjCPropertyRefExpr>(syntactic)) {
-          VisitObjCMessage(ObjCPropertyAccess(PR, ME, Pred->getState(), LCtx),
+          VisitObjCMessage(ObjCPropertyAccess(PR, PO->getSourceRange(), ME,
+                                              Pred->getState(), LCtx),
                            Pred, Dst);
           evaluated = true;
         }
index 86630a8c02845754d1dd42678dd41e9e82cdcaf7..5444b74dfbdc3b8ba93b89ac568d78de1a24ddd0 100644 (file)
@@ -15,7 +15,6 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
 
 using namespace clang;
 using namespace ento;