forked from OSchip/llvm-project
Document behavior of -Wformat-nonliteral, it is different from GCC
llvm-svn: 172362
This commit is contained in:
parent
942ee72aff
commit
dc81f51d37
|
@ -1861,3 +1861,61 @@ expression is compared to the type tag. There are two supported flags:
|
|||
// was specified but buffer
|
||||
// is not a null pointer
|
||||
|
||||
Format String Checking
|
||||
======================
|
||||
|
||||
Clang supports the ``format`` attribute, which indicates that the function
|
||||
accepts a ``printf`` or ``scanf``-like format string and corresponding
|
||||
arguments or a ``va_list`` that contains these arguments.
|
||||
|
||||
Please see `GCC documentation about format attribute
|
||||
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
|
||||
about attribute syntax.
|
||||
|
||||
Clang implements two kinds of checks with this attribute.
|
||||
|
||||
#. Clang checks that the function with the ``format`` attribute is called with
|
||||
a format string that uses format specifiers that are allowed, and that
|
||||
arguments match the format string. This is the ``-Wformat`` warning, it is
|
||||
on by default.
|
||||
|
||||
#. Clang checks that the format string argument is a literal string. This is
|
||||
the ``-Wformat-nonliteral`` warning, it is off by default.
|
||||
|
||||
Clang implements this mostly the same way as GCC, but there is a difference
|
||||
for functions that accept a ``va_list`` argument (for example, ``vprintf``).
|
||||
GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
|
||||
fuctions. Clang does not warn if the format string comes from a function
|
||||
parameter, where function is annotated with a compatible attribute,
|
||||
otherwise it warns. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
__attribute__((__format__ (__scanf__, 1, 3)))
|
||||
void foo(const char* s, char *buf, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, buf);
|
||||
|
||||
vprintf(s, ap); // warning: format string is not a string literal
|
||||
}
|
||||
|
||||
In this case we warn because ``s`` contains a format string for a
|
||||
``scanf``-like function, but it is passed it to a ``printf``-like function.
|
||||
|
||||
If the attribute is removed, clang still warns, because the format string is
|
||||
not a string literal.
|
||||
|
||||
But in this case Clang does not warn because the format string ``s`` and
|
||||
corresponding arguments are annotated. If the arguments are incorrect,
|
||||
caller of ``foo`` will get a warning.
|
||||
|
||||
.. code-block: c
|
||||
|
||||
__attribute__((__format__ (__printf__, 1, 3)))
|
||||
void foo(const char* s, char *buf, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, buf);
|
||||
|
||||
vprintf(s, ap); // warning
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue