Index: clang/docs/analyzer/user-docs.rst =================================================================== --- clang/docs/analyzer/user-docs.rst +++ clang/docs/analyzer/user-docs.rst @@ -6,4 +6,5 @@ .. toctree:: :maxdepth: 2 + user-docs/Configuration user-docs/CrossTranslationUnit Index: clang/docs/analyzer/user-docs/Configuration.rst =================================================================== --- /dev/null +++ clang/docs/analyzer/user-docs/Configuration.rst @@ -0,0 +1,86 @@ +============= +Configuration +============= + +The analyzer can be configured with a wide variety of options and switches. +One can fine-tune its behavior by passing these options as the +``-analyzer-config`` command line parameter to the analyzer frontend action. +For the complete list of the supported option list run this command: + +.. code-block:: bash + + $ clang -cc1 -analyze -analyzer-config-help + +.. contents:: + :local: + +Flexible array member modeling +______________________________ + +In C struct data types may end with a **flexible array member** with no +specificed size: + +.. code-block:: cpp + + struct vectord { + short len; // there must be at least one other data member + double arr[]; // the flexible array member must be last + // The compiler may reserve extra padding space here, like it can between struct members + }; + + // ... + + struct vectord *vector = malloc(sizeof(struct vectord) + n * sizeof(double)); + vector->len = n; + for (int i = 0; i < vector->len; i++) + vector->arr[i] = ...; + +This pattern is widely used to spare an extra allocation and a pointer +indirection thus gaining better cache locality. +Source: `Wikipedia `_ + +---- + +There are multiple forms of FAMs in the wild: + +- Form 1 - Incomplete array member: + + .. code-block:: cpp + + struct Foo { + char field1; + int my_fam[]; // no size! + }; + +- Form 2 - Constant array member with size 0: + + .. code-block:: cpp + + struct Foo { + char field1; + int my_fam[0]; // zero size! + }; + +- Form 3 - Constant array member with size 1: + + .. code-block:: cpp + + struct Foo { + char field1; + int my_fam[1]; // single element! + }; + +We recommend not using FAMs at all. If you really need them, stick to using +the *first form* mentioned in the list - using an incomplete array member +declaration. It will deliver the intent of the programmer that the size +of the array is indeed unknown. + +*Form 2* is also discouraged, since not all compilers might support it. +*Form 3* is considered harmful! It's highly likely that any use of that form +would result in undefined behavior. The compiler has the right to compile the +binary under the assumption that the array has exactly one element. + +By default, the Clang Static Analyzer will consider only *form 1* and *form 2* +as *flexible array members*. If the project under analysis uses FAMs of +*form 3*, then consider enabling the +``consider-single-element-arrays-as-flexible-array-members=true`` config option.