Skip to content

Commit

Permalink
[NFC][analyzer][docs] Improve Annotations.rst
Browse files Browse the repository at this point in the history
This commit fixes three issues within the documentation file
`Annotations.rst` which was recently created by my earlier commit
llvm#122246 .

(1) The section title "Annotations to Enhance Generic Checks" is
changed to "General Purpose Annotations" because it was a bit too
verbose and it used the obsolete name "checks" for what we now call
"checkers" in the static analyzer.

(2) Several code blocks were missing from the generated html because I
accidentally used `.. code-block: c` instead of `.. code-block:: c` and
so Sphinx parsed them as comment blocks. (Without printing any error or
warning...)

(3) The `ownership_*` attributes (which are used by `MallocChecker`)
were missing from this document, so I wrote a section that briefly
describes them and links to their full documentation.
  • Loading branch information
NagyDonat committed Jan 13, 2025
1 parent 99612a3 commit 098e884
Showing 1 changed file with 43 additions and 8 deletions.
51 changes: 43 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,42 @@ 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.)

**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 +243,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 +633,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

0 comments on commit 098e884

Please sign in to comment.