[clang] [analyzer] Model GCC 'cleanup' attribute function calls (PR #221110)

Arseniy Zaostrovnykh via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 9 06:44:48 PDT 2026


================
@@ -1239,6 +1245,60 @@ class CXXDeallocatorCall : public AnyFunctionCall {
   }
 };
 
+/// Represents an implicit call to a cleanup function, triggered by a
+/// `__attribute__((cleanup(f)))` variable going out of scope.
+///
+/// The call has no syntactic representation: like \c CXXDestructorCall it is
+/// Decl-origin, and its single argument, the address of the annotated
+/// variable, is not written in the source.
+class CleanupFunctionCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  CleanupFunctionCall(const FunctionDecl *FD, const VarDecl *VD,
+                      ProgramStateRef St, const StackFrame *SF,
+                      CFGBlock::ConstCFGElementRef ElemRef)
+      : AnyFunctionCall(FD, St, SF, ElemRef) {
+    Data = VD;
+    Location = VD->getAttr<CleanupAttr>()->getLoc();
+  }
+
+  CleanupFunctionCall(const CleanupFunctionCall &Other) = default;
+
+  void cloneTo(void *Dest) const override {
+    new (Dest) CleanupFunctionCall(*this);
+  }
+
+public:
+  /// Returns the variable declaration whose scope exit triggered this call.
+  const VarDecl *getVarDecl() const {
+    return static_cast<const VarDecl *>(Data);
+  }
+
+  SourceRange getSourceRange() const override { return Location; }
+
+  unsigned getNumArgs() const override { return 1; }
+
+  // The implicit `&var` argument has no expression in the source.
+  const Expr *getArgExpr(unsigned Index) const override { return nullptr; }
----------------
necto wrote:

It seems to be the first time a `CallEvent::getArgExpr` can return `nullptr` for an arg index that is within `getNumArgs()`. I can't think of any, but is there a way to handle this situation without introducing this pitfall?
If not, It might make sense to run a test that contains a cleanup attribute with as many checkers as possible so that a potential crash is explosed early.

https://github.com/llvm/llvm-project/pull/221110


More information about the cfe-commits mailing list