Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NFC][analyzer][docs] Improve Annotations.rst #122749

Merged
merged 2 commits into from
Jan 31, 2025
Merged
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
52 changes: 44 additions & 8 deletions clang/docs/analyzer/user-docs/Annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ recognized by GCC. Their use can be conditioned using preprocessor macros
.. contents::
:local:

Annotations to Enhance Generic Checks
_____________________________________
General Purpose Annotations
___________________________

Null Pointer Checking
#####################
Expand Down Expand Up @@ -79,15 +79,15 @@ implemented with a macro, with the macro performing a check for the assertion
condition and, when the check fails, calling an assertion handler. For
example, consider the following code fragment:

.. code-block: c
.. code-block:: c

void foo(int *p) {
assert(p != NULL);
}

When this code is preprocessed on Mac OS X it expands to the following:

.. code-block: c
.. code-block:: c

void foo(int *p) {
(__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0);
Expand Down Expand Up @@ -131,7 +131,7 @@ return.
On Mac OS X, the function prototype for ``__assert_rtn`` (declared in
``assert.h``) is specifically annotated with the 'noreturn' attribute:

.. code-block: c
.. code-block:: c

void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));

Expand All @@ -151,7 +151,7 @@ the use of preprocessor macros.

**Example**

.. code-block: c
.. code-block:: c

#ifndef CLANG_ANALYZER_NORETURN
#if __has_feature(attribute_analyzer_noreturn)
Expand All @@ -163,6 +163,43 @@ the use of preprocessor macros.

void my_assert_rtn(const char *, const char *, int, const char *) CLANG_ANALYZER_NORETURN;

Dynamic Memory Modeling Annotations
###################################

If a project uses custom functions for dynamic memory management (that e.g. act as wrappers around ``malloc``/``free`` or ``new``/``delete`` in C++) and the analyzer cannot "see" the _definitions_ of these functions, it's possible to annotate their declarations to let the analyzer model their behavior. (Otherwise the analyzer cannot know that the opaque ``my_free()`` is basically equivalent to a standard ``free()`` call.)

.. note::
**This page only provides a brief list of these annotations.** For a full documentation, see the main `Attributes in Clang <../../AttributeReference.html#ownership-holds-ownership-returns-ownership-takes-clang-static-analyzer>`_ page.

Attribute 'ownership_returns' (Clang-specific)
----------------------------------------------

Use this attribute to mark functions that return dynamically allocated memory. Takes a single argument, the type of the allocation (e.g. ``malloc`` or ``new``).

.. code-block:: c

void __attribute((ownership_returns(malloc))) *my_malloc(size_t);

Attribute 'ownership_takes' (Clang-specific)
--------------------------------------------

Use this attribute to mark functions that deallocate memory. Takes two arguments: the type of the allocation (e.g. ``malloc`` or ``new``) and the index of the parameter that is being deallocated (counting from 1).

.. code-block:: c

void __attribute((ownership_takes(malloc, 1))) my_free(void *);

Attribute 'ownership_holds' (Clang-specific)
--------------------------------------------

Use this attribute to mark functions that take ownership of memory and will deallocate it at some unspecified point in the future. Takes two arguments: the type of the allocation (e.g. ``malloc`` or ``new``) and the index of the parameter that is being held (counting from 1).

.. code-block:: c

void __attribute((ownership_holds(malloc, 2))) store_in_table(int key, record_t *val);

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.

Mac OS X API Annotations
________________________

Expand Down Expand Up @@ -207,7 +244,7 @@ functions allows the analyzer to perform extra checking.

**Example**

.. code-block: objc
.. code-block:: objc

#import <Foundation/Foundation.h>;

Expand Down Expand Up @@ -597,7 +634,6 @@ returned object.
LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter();
}


// Note that the annotation only has to be applied to the function declaration.
OSObject * MyClass::myFieldGetter() {
return f;
Expand Down
Loading