[cfe-commits] r160020 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp lib/StaticAnalyzer/Core/Calls.cpp lib/StaticAnalyzer/Core/ExprEngineCXX.cpp lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Jordan Rose jordan_rose at apple.com
Tue Jul 10 15:07:48 PDT 2012


Author: jrose
Date: Tue Jul 10 17:07:47 2012
New Revision: 160020

URL: http://llvm.org/viewvc/llvm-project?rev=160020&view=rev
Log:
[analyzer] Add a CXXDestructorCall CallEvent.

While this work is still fairly tentative (destructors are still left out of
the CFG by default), we now handle destructors in the same way as any other
calls, instead of just automatically trying to inline them.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h?rev=160020&r1=160019&r2=160020&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h Tue Jul 10 17:07:47 2012
@@ -37,6 +37,7 @@
   CE_BEG_SIMPLE_CALLS = CE_Function,
   CE_END_SIMPLE_CALLS = CE_Block,
   CE_CXXConstructor,
+  CE_CXXDestructor,
   CE_CXXAllocator,
   CE_BEG_FUNCTION_CALLS = CE_Function,
   CE_END_FUNCTION_CALLS = CE_CXXAllocator,
@@ -159,7 +160,7 @@
   }
 
   /// \brief Returns an appropriate ProgramPoint for this call.
-  ProgramPoint getProgramPoint(bool IsPreVisit,
+  ProgramPoint getProgramPoint(bool IsPreVisit = false,
                                const ProgramPointTag *Tag = 0) const;
 
   /// \brief Returns a new state with all argument regions invalidated.
@@ -391,6 +392,36 @@
   }
 };
 
+/// \brief Represents an implicit call to a C++ destructor.
+///
+/// This can occur at the end of a scope (for automatic objects), at the end
+/// of a full-expression (for temporaries), or as part of a delete.
+class CXXDestructorCall : public AnyFunctionCall {
+  const CXXDestructorDecl *DD;
+  const MemRegion *Target;
+  SourceLocation Loc;
+
+protected:
+  void addExtraInvalidatedRegions(RegionList &Regions) const;
+
+public:
+  CXXDestructorCall(const CXXDestructorDecl *dd, const Stmt *Trigger,
+                    const MemRegion *target, ProgramStateRef St,
+                    const LocationContext *LCtx)
+    : AnyFunctionCall(St, LCtx, CE_CXXDestructor), DD(dd), Target(target),
+      Loc(Trigger->getLocEnd()) {}
+
+  const Expr *getOriginExpr() const { return 0; }
+  SourceRange getSourceRange() const { return Loc; }
+
+  const CXXDestructorDecl *getDecl() const { return DD; }
+  unsigned getNumArgs() const { return 0; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXDestructor;
+  }
+};
+
 /// \brief Represents the memory allocation call in a C++ new-expression.
 ///
 /// This is a call to "operator new".

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=160020&r1=160019&r2=160020&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Jul 10 17:07:47 2012
@@ -948,6 +948,7 @@
   case CE_CXXMemberOperator:
   case CE_Block:
   case CE_CXXConstructor:
+  case CE_CXXDestructor:
   case CE_CXXAllocator:
     // FIXME: These calls are currently unsupported.
     return getPersistentStopSummary();

Modified: cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp?rev=160020&r1=160019&r2=160020&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Calls.cpp Tue Jul 10 17:07:47 2012
@@ -372,6 +372,12 @@
 }
 
 
+void CXXDestructorCall::addExtraInvalidatedRegions(RegionList &Regions) const {
+  if (Target)
+    Regions.push_back(Target);
+}
+
+
 CallEvent::param_iterator ObjCMethodCall::param_begin() const {
   const ObjCMethodDecl *D = getDecl();
   if (!D)

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=160020&r1=160019&r2=160020&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Tue Jul 10 17:07:47 2012
@@ -75,21 +75,21 @@
                                       const Stmt *S,
                                       ExplodedNode *Pred, 
                                       ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
-  if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall()))
-    return;
+  CXXDestructorCall Call(DD, S, Dest, Pred->getState(),
+                         Pred->getLocationContext());
 
-  // Create the context for 'this' region.
-  const StackFrameContext *SFC =
-    AnalysisDeclContexts.getContext(DD)->
-      getStackFrame(Pred->getLocationContext(), S,
-      currentBuilderContext->getBlock(), currentStmtIdx);
-
-  CallEnter PP(S, SFC, Pred->getLocationContext());
-  ProgramStateRef state = Pred->getState();
-  state = state->bindLoc(svalBuilder.getCXXThis(DD->getParent(), SFC),
-                         loc::MemRegionVal(Dest));
-  Bldr.generateNode(PP, Pred, state);
+  ExplodedNodeSet DstPreCall;
+  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
+                                            Call, *this);
+
+  ExplodedNodeSet DstInvalidated;
+  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+       I != E; ++I)
+    defaultEvalCall(DstInvalidated, *I, Call);
+
+  ExplodedNodeSet DstPostCall;
+  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
+                                             Call, *this);
 }
 
 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=160020&r1=160019&r2=160020&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Jul 10 17:07:47 2012
@@ -292,7 +292,8 @@
     // enterStackFrame as well.
     return false;
   case CE_CXXConstructor:
-    // Do not inline constructors until we can model destructors.
+  case CE_CXXDestructor:
+    // Do not inline constructors until we can really model destructors.
     // This is unfortunate, but basically necessary for smart pointers and such.
     return false;
   case CE_CXXAllocator:
@@ -430,7 +431,7 @@
     return;
 
   // If we can't inline it, handle the return value and invalidate the regions.
-  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
+  NodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
 
   // Invalidate any regions touched by the call.
   unsigned Count = currentBuilderContext->getCurrentBlockCount();
@@ -439,16 +440,17 @@
   state = Call.invalidateRegions(Count, state);
 
   // Conjure a symbol value to use as the result.
-  assert(Call.getOriginExpr() && "Must have an expression to bind the result");
-  QualType ResultTy = Call.getResultType();
-  SValBuilder &SVB = getSValBuilder();
-  const LocationContext *LCtx = Pred->getLocationContext();
-  SVal RetVal = SVB.getConjuredSymbolVal(0, Call.getOriginExpr(), LCtx,
-                                         ResultTy, Count);
+  if (E) {
+    QualType ResultTy = Call.getResultType();
+    SValBuilder &SVB = getSValBuilder();
+    const LocationContext *LCtx = Pred->getLocationContext();
+    SVal RetVal = SVB.getConjuredSymbolVal(0, E, LCtx, ResultTy, Count);
+
+    state = state->BindExpr(E, LCtx, RetVal);
+  }
 
   // And make the result node.
-  state = state->BindExpr(Call.getOriginExpr(), LCtx, RetVal);
-  Bldr.generateNode(Call.getOriginExpr(), Pred, state);
+  Bldr.generateNode(Call.getProgramPoint(), state, Pred);
 }
 
 void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,





More information about the cfe-commits mailing list