@@ -3743,6 +3743,103 @@ behavior of the program is undefined.
37433743 }];
37443744}
37453745
3746+ def FormatMatchesDocs : Documentation {
3747+ let Category = DocCatFunction;
3748+ let Content = [{
3749+
3750+ The ``format`` attribute is the basis for the enforcement of diagnostics in the
3751+ ``-Wformat`` family, but it only handles the case where the format string is
3752+ passed along with the arguments it is going to format. It cannot handle the case
3753+ where the format string and the format arguments are passed separately from each
3754+ other. For instance:
3755+
3756+ .. code-block:: c
3757+
3758+ static const char *first_name;
3759+ static double todays_temperature;
3760+ static int wind_speed;
3761+
3762+ void say_hi(const char *fmt) {
3763+ printf(fmt, first_name, todays_temperature); // warning: format string is not a string literal
3764+ printf(fmt, first_name, wind_speed); // warning: format string is not a string literal
3765+ }
3766+
3767+ int main() {
3768+ say_hi("hello %s, it is %g degrees outside");
3769+ say_hi("hello %s, it is %d degrees outside!"); // no diagnostic
3770+ }
3771+
3772+ In this example, ``fmt`` is expected to format a ``const char *`` and a
3773+ ``double``, but these values are not passed to ``say_hi``. Without the
3774+ ``format`` attribute (which cannot apply in this case), the -Wformat-nonliteral
3775+ diagnostic triggers in the body of ``say_hi``, and incorrect ``say_hi`` call
3776+ sites do not trigger a diagnostic.
3777+
3778+ To complement the ``format`` attribute, Clang also defines the
3779+ ``format_matches`` attribute. Its syntax is similar to the ``format``
3780+ attribute's, but instead of taking the index of the first formatted value
3781+ argument, it takes a C string literal with the expected specifiers:
3782+
3783+ .. code-block:: c
3784+
3785+ static const char *first_name;
3786+ static double todays_temperature;
3787+ static int wind_speed;
3788+
3789+ __attribute__((__format_matches__(printf, 1, "%s %g")))
3790+ void say_hi(const char *fmt) {
3791+ printf(fmt, first_name, todays_temperature); // no dignostic
3792+ printf(fmt, first_name, wind_speed); // warning: format specifies type 'int' but the argument has type 'double'
3793+ }
3794+
3795+ int main() {
3796+ say_hi("hello %s, it is %g degrees outside");
3797+ say_hi("it is %g degrees outside, have a good day %s!");
3798+ // warning: format specifies 'double' where 'const char *' is required
3799+ // warning: format specifies 'const char *' where 'double' is required
3800+ }
3801+
3802+ The third argument to ``format_matches`` is expected to evaluate to a **C string
3803+ literal** even when the format string would normally be a different type for the
3804+ given flavor, like a ``CFStringRef`` or a ``NSString *``.
3805+
3806+ In the implementation of a function with the ``format_matches`` attribute,
3807+ format verification works as if the format string was identical to the one
3808+ specified in the attribute.
3809+
3810+ At the call sites of functions with the ``format_matches`` attribute, format
3811+ verification instead compares the two format strings to evaluate their
3812+ equivalence. Each format flavor defines equivalence between format specifiers.
3813+ Generally speaking, two specifiers are equivalent if they format the same type.
3814+ For instance, in the ``printf`` flavor, ``%2i`` and ``%-0.5d`` are compatible.
3815+ When ``-Wformat-signedness`` is disabled, ``%d`` and ``%u`` are compatible. For
3816+ a negative example, ``%ld`` is incompatible with ``%d``.
3817+
3818+ Do note the following un-obvious cases:
3819+
3820+ * Passing ``NULL`` as the format string is accepted without diagnostics.
3821+ * When the format string is not NULL, it cannot _miss_ specifiers, even in
3822+ trailing positions. For instance, ``%d`` is not accepted when the required
3823+ format is ``%d %d %d``.
3824+ * Specifiers for integers as small or smaller than ``int`` (such as ``%hhd``)
3825+ are all mutually compatible because standard argument promotion ensures that
3826+ integers are at least the size of ``int`` when passed as variadic arguments.
3827+ With ``-Wformat-signedness``, mixing specifier for types with a different
3828+ signedness still results in a diagnostic.
3829+ * Format strings expecting a variable modifier (such as ``%*s``) are
3830+ incompatible with format strings that would itemize the variable modifiers
3831+ (such as ``%i %s``), even if the two specify ABI-compatible argument lists.
3832+ * All pointer specifiers, modifiers aside, are mutually incompatible. For
3833+ instance, ``%s`` is not compatible with ``%p``, and ``%p`` is not compatible
3834+ with ``%n``, and ``%hhn`` is incompatible with ``%s``, even if the pointers
3835+ are ABI-compatible or identical on the selected platform. However, ``%0.5s``
3836+ is compatible with ``%s``, since the difference only exists in modifier flags.
3837+ This is not overridable with ``-Wformat-pedantic`` or its inverse, which
3838+ control similar behavior in ``-Wformat``.
3839+
3840+ }];
3841+ }
3842+
37463843def FlagEnumDocs : Documentation {
37473844 let Category = DocCatDecl;
37483845 let Content = [{
0 commit comments