================
@@ -0,0 +1,93 @@
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "AllocationState.h"
+#include "clang/Analysis/Analyses/LifetimeSafety/LifetimeAnnotations.h"
+
+
+using namespace clang;
+using namespace ento;
+using namespace clang::lifetimes;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(LifetimeBoundMap, SymbolRef,
+                               const MemRegion *);
+
+class LifetimeAnnotations : public Checker<check::PostCall> {
+public:
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+  void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
+                  const char *Sep) const override;
+};
+
+void LifetimeAnnotations::checkPostCall(const CallEvent &Call,
+                                        CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+
+  const auto *FC = dyn_cast_if_present<AnyFunctionCall>(&Call);
+  if (!FC)
+    return;
+
+  const FunctionDecl *FD = FC->getDecl();
+  if (!FD)
+    return;
+
+  unsigned LBParamIdx = FD->getNumParams();
+  // FIXME: Use range based for loop instead. Currently that would require
+  // to also change how we create ArgVal which would need a new logic to
+  // be implemented.
+  for (unsigned I = 0, E = FD->getNumParams(); I != E; I++) {
+    if (FD->getParamDecl(I)->hasAttr<LifetimeBoundAttr>()) {
+      LBParamIdx = I;
+      // FIXME: If multiple parameters are annotated this logic would
+      // prevent the analyzer to read after the first parameter.
+      break;
+    }
+  }
+  SVal RetVal = Call.getReturnValue();
+
+  SymbolRef RetValSym = RetVal.getAsSymbol(/*IncludeBaseRegions=*/true);
+  if(!RetValSym)
+    return;
+
+  if (LBParamIdx != FD->getNumParams()) {
+    SVal ArgVal = Call.getArgSVal(LBParamIdx);
+    const MemRegion *ArgValRegion = ArgVal.getAsRegion();
+    // FIXME: if(!ArgValRegion) should be also handled since in those cases
+    // the argument has no region, but still needs to be tracked.
+    if (ArgValRegion)
+        State = State->set<LifetimeBoundMap>(RetValSym, ArgValRegion);
+  }
+
+  if (const auto *IC = dyn_cast<CXXInstanceCall>(&Call)) {
+    if (implicitObjectParamIsLifetimeBound(FD)) {
----------------
isuckatcs wrote:

Keep in mind that you probably have to track when the object is destroyed, so 
that you know if its lifetime ended, or not.

https://github.com/llvm/llvm-project/pull/200145
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to