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?= <dkszelet...@gmail.com> Date: Mon, 6 Jan 2025 13:14:37 +0100 Subject: [PATCH 1/4] [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?= <dkszelet...@gmail.com> Date: Mon, 6 Jan 2025 15:41:39 +0100 Subject: [PATCH 2/4] 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.n...@ericsson.com> Co-authored-by: Balazs Benics <benicsbal...@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?= <dkszelet...@gmail.com> Date: Mon, 6 Jan 2025 17:44:44 +0100 Subject: [PATCH 3/4] 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?= <dkszelet...@gmail.com> Date: Mon, 6 Jan 2025 17:50:53 +0100 Subject: [PATCH 4/4] 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. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits