[clang] 7ce15f3 - [NFC][analyzer][docs] Document MallocChecker's ownership attributes (#121759)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 7 02:00:08 PST 2025
Author: Kristóf Umann
Date: 2025-01-07T11:00:04+01:00
New Revision: 7ce15f3ba76e1780935715cfdd9dd368ebd23163
URL: https://github.com/llvm/llvm-project/commit/7ce15f3ba76e1780935715cfdd9dd368ebd23163
DIFF: https://github.com/llvm/llvm-project/commit/7ce15f3ba76e1780935715cfdd9dd368ebd23163.diff
LOG: [NFC][analyzer][docs] Document MallocChecker's ownership attributes (#121759)
Exactly what it says on the tin! These were written ages ago (2010s),
but are still functional, only the docs are missing.

---------
Co-authored-by: Donát Nagy <donat.nagy at ericsson.com>
Co-authored-by: Balazs Benics <benicsbalazs at gmail.com>
Co-authored-by: isuckatcs <65320245+isuckatcs at users.noreply.github.com>
Added:
Modified:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index bc5f0662adf8e9..6d7f65ab2c6135 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..ba581e02542fc6 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1389,6 +1389,81 @@ 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 :ref:`mismatched deallocation
+<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
+annotated 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.
+* 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 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
diff erence 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 a dynamically 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 = [{
More information about the cfe-commits
mailing list