From b4b970f7653ca4936e7401780a5bffa05d2ea1ee Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Sun, 13 Jan 2013 16:37:18 +0000 Subject: [PATCH] Document behavior of -Wformat-nonliteral, it is different from GCC git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172362 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LanguageExtensions.rst | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index f8dbb68519..16af7e3099 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -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 +`_ 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 + } + -- 2.40.0