================
@@ -284,6 +284,76 @@ static bool checkForRecursiveFunctionCall(const 
FunctionDecl *FD, CFG *cfg) {
   return foundRecursion;
 }
 
+namespace {
+/// Walks a 'pure'/'const' function body looking for stores through pointer
+/// or reference parameters, and stores to global or static-local variables.
+/// This is a syntactic heuristic, not a proof: it only catches direct writes
+/// reachable via straightforward lvalue expressions in the function's own
+/// body. It intentionally does not attempt interprocedural analysis (that's
+/// undecidable in general), locally-allocated memory escaping, or writes
+/// mediated through a level of indirection the visitor doesn't unwrap.
+class PureConstWriteChecker : public DynamicRecursiveASTVisitor {
+public:
+  PureConstWriteChecker(Sema &sema, const FunctionDecl *functionDecl,
+                        bool isConstAttr)
+      : S(sema), FD(functionDecl), IsConstAttr(isConstAttr) {}
+
+  bool VisitBinaryOperator(BinaryOperator *BO) override {
+    if (BO->isAssignmentOp() || BO->isCompoundAssignmentOp())
+      checkLvalue(BO->getLHS());
+
+    return true;
+  }
+
+private:
+  Sema &S;
+  const FunctionDecl *FD;
+  bool IsConstAttr;
+
+  void checkLvalue(const Expr *E) {
+    E = E->IgnoreParenImpCasts();
+    if (const auto *UO = dyn_cast<UnaryOperator>(E)) {
+      if (UO->getOpcode() == UO_Deref) {
+        checkPointerBase(UO->getSubExpr());
+        return;
+      }
----------------
AhmedKamel10 wrote:

 I've updated it to return early since E can't be a DeclRefExpr if the 
UnaryOperator cast succeeds.

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

Reply via email to