[clang] [NFC][analyzer][docs] Document MallocChecker's ownership attributes (PR #121759)

Kristóf Umann via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 7 01:53:05 PST 2025


https://github.com/Szelethus updated https://github.com/llvm/llvm-project/pull/121759

>From 24b15119f476bf8c981618132b05357a87d98476 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Umann?= <dkszelethus at gmail.com>
Date: Mon, 6 Jan 2025 13:14:37 +0100
Subject: [PATCH 1/5] [analyzer][docs] Document MallocChecker's ownership
 attributes

Exactly what it says on the tin! These were written ages ago (2010s),
but are still functional, only the docs are missing.
---
 clang/include/clang/Basic/Attr.td     |  2 +-
 clang/include/clang/Basic/AttrDocs.td | 62 +++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 90d2a2056fe1ba..0454642b52cf35 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2776,7 +2776,7 @@ def Ownership : InheritableAttr {
   let Args = [IdentifierArgument<"Module">,
               VariadicParamIdxArgument<"Args">];
   let Subjects = SubjectList<[HasFunctionProto]>;
-  let Documentation = [Undocumented];
+  let Documentation = [OwnershipDocs];
 }
 
 def Packed : InheritableAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index fdad4c9a3ea191..b1b4685ae9259b 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1389,6 +1389,68 @@ Query for this attribute with ``__has_attribute(overloadable)``.
   }];
 }
 
+def OwnershipDocs : Documentation {
+  let Heading = "ownership_holds, ownership_returns, ownership_takes (Clang "
+                "Static Analyzer)";
+  let Category = DocCatFunction;
+  let Content = [{
+
+.. note::
+
+  In order for the Clang Static Analyzer to acknowledge these attributes, the
+  ``Optimistic`` config needs to be set to true for the checker
+  ``unix.DynamicMemoryModeling``:
+
+  ``-Xclang -analyzer-config -Xclang unix.DynamicMemoryModeling:Optimistic=true``
+
+These attributes are used by the Clang Static Analyzer's dynamic memory modeling
+facilities to mark custom allocating/deallocating functions.
+
+All 3 attributes' first parameter of type string is the type of the allocation:
+``malloc``, ``new``, etc. to allow for catching mismatched deallocation bugs to
+be found.
+
+* Use ``ownership_returns`` to mark a function as an allocating function. Takes
+  1 parameter to denote the allocation type.
+* Use ``ownership_takes`` to mark a function as a deallocating function. Takes 2
+  parameters: the allocation type, and the index of the parameter that is being
+  deallocated (counting from 1).
+* Use ``ownership_holds`` to mark that a function takes over the ownership of a
+  piece of memory. The analyzer will assume that the memory is not leaked even
+  if it finds that the last pointer referencing it went out of scope (almost as
+  if it was freed). Takes 2 parameters: the allocation type, and the index of
+  the parameter whose ownership will be taken over (counting from 1).
+
+Example:
+
+.. code-block:: c
+
+  // Denotes that my_malloc will return with adynamically allocated piece of
+  // memory using malloc().
+  void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+
+  // Denotes that my_free will deallocate its parameter using free().
+  void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+  // Denotes that my_hold will take over the ownership of its parameter that was
+  // allocated via malloc().
+  void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
+
+Further reading about dynamic memory modeling in the Clang Static Analyzer is
+found in these checker docs:
+:ref:`unix.Malloc <unix-Malloc>`, :ref:`unix.MallocSizeof <unix-MallocSizeof>`,
+:ref:`unix.MismatchedDeallocator <unix-MismatchedDeallocator>`,
+:ref:`cplusplus.NewDelete <cplusplus-NewDelete>`,
+:ref:`cplusplus.NewDeleteLeaks <cplusplus-NewDeleteLeaks>`,
+:ref:`optin.taint.TaintedAlloc <optin-taint-TaintedAlloc>`.
+Mind that many more checkers are affected by dynamic memory modeling changes to
+some extent.
+
+Further reading for other annotations:
+`Source Annotations in the Clang Static Analyzer <https://clang-analyzer.llvm.org/annotations.html>`_.
+}];
+}
+
 def ObjCMethodFamilyDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

>From 00c2349d7a0affd27fbc65c0bce18982e6d81481 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Umann?= <dkszelethus at gmail.com>
Date: Mon, 6 Jan 2025 15:41:39 +0100
Subject: [PATCH 2/5] Apply suggestions from code review
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Donát Nagy <donat.nagy at ericsson.com>
Co-authored-by: Balazs Benics <benicsbalazs at gmail.com>
---
 clang/include/clang/Basic/AttrDocs.td | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index b1b4685ae9259b..e4e2fca193a256 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1416,16 +1416,19 @@ be found.
   parameters: the allocation type, and the index of the parameter that is being
   deallocated (counting from 1).
 * Use ``ownership_holds`` to mark that a function takes over the ownership of a
-  piece of memory. The analyzer will assume that the memory is not leaked even
-  if it finds that the last pointer referencing it went out of scope (almost as
-  if it was freed). Takes 2 parameters: the allocation type, and the index of
-  the parameter whose ownership will be taken over (counting from 1).
+  piece of memory and will free it at some unspecified point in the future. Like
+  ``ownership_takes``, this takes 2 parameters: the allocation type, and the
+  index of the parameter whose ownership will be taken over (counting from 1).
+The annotations ``ownership_takes`` and ``ownership_holds`` both prevent memory
+leak reports (concerning the specified argument); the difference between them
+is that using taken memory is a use-after-free error, while using held memory
+is assumed to be legitimate.
 
 Example:
 
 .. code-block:: c
 
-  // Denotes that my_malloc will return with adynamically allocated piece of
+  // Denotes that my_malloc will return with a dynamically allocated piece of
   // memory using malloc().
   void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
 

>From 84da033c35978892da040eaaf1846577d2eedc38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Umann?= <dkszelethus at gmail.com>
Date: Mon, 6 Jan 2025 17:44:44 +0100
Subject: [PATCH 3/5] Expand on allocation type

---
 clang/include/clang/Basic/AttrDocs.td | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index e4e2fca193a256..c7f3399355e2a3 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1407,8 +1407,17 @@ These attributes are used by the Clang Static Analyzer's dynamic memory modeling
 facilities to mark custom allocating/deallocating functions.
 
 All 3 attributes' first parameter of type string is the type of the allocation:
-``malloc``, ``new``, etc. to allow for catching mismatched deallocation bugs to
-be found.
+``malloc``, ``new``, etc. to allow for catching :ref:`mismatched deallocation
+<unix-MismatchedDeallocator>` bugs to
+be found. The allocation type can be any string, e.g. a function annotated with
+returning a piece of memory of type ``lasagna`` but freed with a function
+annoteted to release ``cheese`` typed memory will result in mismatched
+deallocation warning.
+
+The (currently) only allocation type having special meaning is ``malloc`` --
+the Clang Static Analyzer makes sure that allocating functions annotated with
+``malloc`` are treated like they used the standard ``malloc()``, and can be
+safely deallocated with the standard ``free()``.
 
 * Use ``ownership_returns`` to mark a function as an allocating function. Takes
   1 parameter to denote the allocation type.
@@ -1419,6 +1428,7 @@ be found.
   piece of memory and will free it at some unspecified point in the future. Like
   ``ownership_takes``, this takes 2 parameters: the allocation type, and the
   index of the parameter whose ownership will be taken over (counting from 1).
+
 The annotations ``ownership_takes`` and ``ownership_holds`` both prevent memory
 leak reports (concerning the specified argument); the difference between them
 is that using taken memory is a use-after-free error, while using held memory

>From 906a47718cd2011a3f24f3dc4625eae0bcd8017b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Umann?= <dkszelethus at gmail.com>
Date: Mon, 6 Jan 2025 17:50:53 +0100
Subject: [PATCH 4/5] Fix some engrish

---
 clang/include/clang/Basic/AttrDocs.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index c7f3399355e2a3..ec3fac86656e33 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1408,8 +1408,8 @@ facilities to mark custom allocating/deallocating functions.
 
 All 3 attributes' first parameter of type string is the type of the allocation:
 ``malloc``, ``new``, etc. to allow for catching :ref:`mismatched deallocation
-<unix-MismatchedDeallocator>` bugs to
-be found. The allocation type can be any string, e.g. a function annotated with
+<unix-MismatchedDeallocator>` bugs. The allocation type can be any string, e.g.
+a function annotated with
 returning a piece of memory of type ``lasagna`` but freed with a function
 annoteted to release ``cheese`` typed memory will result in mismatched
 deallocation warning.

>From 3aa1f68f930a27e7442396878629c91a2d8d99f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=B3f=20Umann?= <dkszelethus at gmail.com>
Date: Tue, 7 Jan 2025 10:52:55 +0100
Subject: [PATCH 5/5] Apply suggestions from code review

Co-authored-by: Balazs Benics <benicsbalazs at gmail.com>
Co-authored-by: isuckatcs <65320245+isuckatcs at users.noreply.github.com>
---
 clang/include/clang/Basic/AttrDocs.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index ec3fac86656e33..ba581e02542fc6 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1411,7 +1411,7 @@ All 3 attributes' first parameter of type string is the type of the allocation:
 <unix-MismatchedDeallocator>` bugs. The allocation type can be any string, e.g.
 a function annotated with
 returning a piece of memory of type ``lasagna`` but freed with a function
-annoteted to release ``cheese`` typed memory will result in mismatched
+annotated to release ``cheese`` typed memory will result in mismatched
 deallocation warning.
 
 The (currently) only allocation type having special meaning is ``malloc`` --
@@ -1461,7 +1461,7 @@ some extent.
 
 Further reading for other annotations:
 `Source Annotations in the Clang Static Analyzer <https://clang-analyzer.llvm.org/annotations.html>`_.
-}];
+  }];
 }
 
 def ObjCMethodFamilyDocs : Documentation {



More information about the cfe-commits mailing list