Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
75 changes: 75 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 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 = [{
Expand Down
Loading