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