xazax.hun updated this revision to Diff 232955.
xazax.hun added a comment.

- Do not track explicitly if a call was conservative.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71224/new/

https://reviews.llvm.org/D71224

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Index: clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/Type.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "PrettyStackTraceLocationContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -18,6 +19,8 @@
 #include "clang/Analysis/ConstructionContext.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
@@ -576,15 +579,14 @@
 
   // Run any pre-call checks using the generic call interface.
   ExplodedNodeSet dstPreVisit;
-  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred,
-                                            Call, *this);
+  getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
 
   // Actually evaluate the function call.  We try each of the checkers
   // to see if the can evaluate the function call, and get a callback at
   // defaultEvalCall if all of them fail.
   ExplodedNodeSet dstCallEvaluated;
-  getCheckerManager().runCheckersForEvalCall(dstCallEvaluated, dstPreVisit,
-                                             Call, *this);
+  getCheckerManager().runCheckersForEvalCall(
+      dstCallEvaluated, dstPreVisit, Call, *this);
 
   // If there were other constructors called for object-type arguments
   // of this call, clean them up.
@@ -592,9 +594,72 @@
   for (auto I : dstCallEvaluated)
     finishArgumentConstruction(dstArgumentCleanup, I, Call);
 
-  // Finally, run any post-call checks.
-  getCheckerManager().runCheckersForPostCall(Dst, dstArgumentCleanup,
+  ExplodedNodeSet dstPostCall;
+  getCheckerManager().runCheckersForPostCall(dstPostCall, dstArgumentCleanup,
                                              Call, *this);
+
+  // Escaping symbols conjured during invalidationg the regions above.
+  // Note that, for inlined calls the nodes were put back into the worklist,
+  // so we can assume that every node belongs to a conservative call at this
+  // point.
+  class CollectReachableSymbolsCallback final : public SymbolVisitor {
+    ProgramStateRef State;
+    InvalidatedSymbols &Symbols;
+
+  public:
+    explicit CollectReachableSymbolsCallback(ProgramStateRef State,
+                                             InvalidatedSymbols &Symbols)
+        : State(State), Symbols(Symbols) {}
+
+    bool VisitSymbol(SymbolRef Sym) override { return true; }
+    bool VisitMemRegion(const MemRegion *MR) override {
+      if (MR->hasStackStorage())
+        return false;
+      QualType T;
+      if (const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
+        T = TR->getLocationType();
+      else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+        T = SR->getSymbol()->getType();
+      if (T->isVoidPointerType())
+        return false;
+      SVal StoredVal = State->getSVal(MR);
+      if (SymbolRef Sym = StoredVal.getAsSymbol())
+        Symbols.insert(Sym);
+      return true;
+    }
+  };
+
+  // Run pointerEscape callback with the newly conjured symbols.
+  for (auto I : dstPostCall) {
+    NodeBuilder B(I, Dst, *currBldrCtx);
+    InvalidatedSymbols Symbols;
+    ProgramStateRef State = I->getState();
+    CollectReachableSymbolsCallback Scanner(State, Symbols);
+    const FunctionDecl *FuncDecl =
+        dyn_cast_or_null<FunctionDecl>(Call.getDecl());
+    if (FuncDecl) {
+      for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
+        if (Arg >= FuncDecl->getNumParams())
+          break;
+        QualType ParamTy = FuncDecl->getParamDecl(Arg)->getType();
+        if (ParamTy.isNull() ||
+            (!ParamTy->isPointerType() && !ParamTy->isReferenceType()))
+          continue;
+        if (ParamTy->getPointeeType().isConstQualified())
+          continue;
+        State->scanReachableSymbols(Call.getArgSVal(Arg), Scanner);
+      }
+    }
+
+    // TODO: the PSK is a lie.
+    State = getCheckerManager().runCheckersForPointerEscape(
+        State, Symbols, &Call, PSK_DirectEscapeOnCall, nullptr);
+
+    if (State != I->getState())
+      B.generateNode(I->getLocation(), State, I);
+    else
+      Dst.insert(I);
+  }
 }
 
 ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
@@ -644,8 +709,8 @@
     ITraits.setTrait(TargetR,
         RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
     State = State->invalidateRegions(TargetR, E, Count, LCtx,
-                                     /* CausesPointerEscape=*/false, nullptr,
-                                     &Call, &ITraits);
+                                     /* CausesPointerEscape=*/false,
+                                     nullptr, &Call, &ITraits);
 
     R = State->getSVal(Target.castAs<Loc>(), E->getType());
   } else {
@@ -670,8 +735,7 @@
 // Conservatively evaluate call by invalidating regions and binding
 // a conjured return value.
 void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
-                                      ExplodedNode *Pred,
-                                      ProgramStateRef State) {
+                                      ExplodedNode *Pred, ProgramStateRef State) {
   State = Call.invalidateRegions(currBldrCtx->blockCount(), State);
   State = bindReturnValue(Call, Pred->getLocationContext(), State);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to