@@ -3644,6 +3644,132 @@ behavior of the program is undefined.
36443644 }];
36453645}
36463646
3647+ def FormatMatchesDocs : Documentation {
3648+ let Category = DocCatFunction;
3649+ let Content = [{
3650+
3651+ The ``format`` attribute is the basis for the enforcement of diagnostics in the
3652+ ``-Wformat`` family, but it only handles the case where the format string is
3653+ passed along with the arguments it is going to format. It cannot handle the case
3654+ where the format string and the format arguments are passed separately from each
3655+ other. For instance:
3656+
3657+ .. code-block:: c
3658+
3659+ static const char *first_name;
3660+ static double todays_temperature;
3661+ static int wind_speed;
3662+
3663+ void say_hi(const char *fmt) {
3664+ printf(fmt, first_name, todays_temperature);
3665+ // ^ warning: format string is not a string literal
3666+ printf(fmt, first_name, wind_speed);
3667+ // ^ warning: format string is not a string literal
3668+ }
3669+
3670+ int main() {
3671+ say_hi("hello %s, it is %g degrees outside");
3672+ say_hi("hello %s, it is %d degrees outside!");
3673+ // ^ no diagnostic, but %d cannot format doubles
3674+ }
3675+
3676+ In this example, ``fmt`` is expected to format a ``const char *`` and a
3677+ ``double``, but these values are not passed to ``say_hi``. Without the
3678+ ``format`` attribute (which cannot apply in this case), the -Wformat-nonliteral
3679+ diagnostic unnecessarily triggers in the body of ``say_hi``, and incorrect
3680+ ``say_hi`` call sites do not trigger a diagnostic.
3681+
3682+ To complement the ``format`` attribute, Clang also defines the
3683+ ``format_matches`` attribute. Its syntax is similar to the ``format``
3684+ attribute's, but instead of taking the index of the first formatted value
3685+ argument, it takes a C string literal with the expected specifiers:
3686+
3687+ .. code-block:: c
3688+
3689+ static const char *first_name;
3690+ static double todays_temperature;
3691+ static int wind_speed;
3692+
3693+ __attribute__((__format_matches__(printf, 1, "%s %g")))
3694+ void say_hi(const char *fmt) {
3695+ printf(fmt, first_name, todays_temperature); // no dignostic
3696+ printf(fmt, first_name, wind_speed); // warning: format specifies type 'int' but the argument has type 'double'
3697+ }
3698+
3699+ int main() {
3700+ say_hi("hello %s, it is %g degrees outside");
3701+ say_hi("it is %g degrees outside, have a good day %s!");
3702+ // warning: format specifies 'double' where 'const char *' is required
3703+ // warning: format specifies 'const char *' where 'double' is required
3704+ }
3705+
3706+ The third argument to ``format_matches`` is expected to evaluate to a **C string
3707+ literal** even when the format string would normally be a different type for the
3708+ given flavor, like a ``CFStringRef`` or a ``NSString *``.
3709+
3710+ The only requirement on the format string literal is that it has specifiers
3711+ that are compatible with the arguments that will be used. It can contain
3712+ arbitrary non-format characters. For instance, for the purposes of compile-time
3713+ validation, ``"%s scored %g%% on her test"`` and ``"%s%g"`` are interchangeable
3714+ as the format string argument. As a means of self-documentation, users may
3715+ prefer the former when it provides a useful example of an expected format
3716+ string.
3717+
3718+ In the implementation of a function with the ``format_matches`` attribute,
3719+ format verification works as if the format string was identical to the one
3720+ specified in the attribute.
3721+
3722+ .. code-block:: c
3723+
3724+ __attribute__((__format_matches__(printf, 1, "%s %g")))
3725+ void say_hi(const char *fmt) {
3726+ printf(fmt, "person", 546);
3727+ // ^ warning: format specifies type 'double' but the
3728+ // argument has type 'int'
3729+ // note: format string is defined here:
3730+ // __attribute__((__format_matches__(printf, 1, "%s %g")))
3731+ // ^~
3732+ }
3733+
3734+
3735+ At the call sites of functions with the ``format_matches`` attribute, format
3736+ verification instead compares the two format strings to evaluate their
3737+ equivalence. Each format flavor defines equivalence between format specifiers.
3738+ Generally speaking, two specifiers are equivalent if they format the same type.
3739+ For instance, in the ``printf`` flavor, ``%2i`` and ``%-0.5d`` are compatible.
3740+ When ``-Wformat-signedness`` is disabled, ``%d`` and ``%u`` are compatible. For
3741+ a negative example, ``%ld`` is incompatible with ``%d``.
3742+
3743+ Do note the following un-obvious cases:
3744+
3745+ * Passing ``NULL`` as the format string does not trigger format diagnostics.
3746+ * When the format string is not NULL, it cannot _miss_ specifiers, even in
3747+ trailing positions. For instance, ``%d`` is not accepted when the required
3748+ format is ``%d %d %d``.
3749+ * While checks for the ``format`` attribute tolerate sone size mismatches
3750+ that standard argument promotion renders immaterial (such as formatting an
3751+ ``int`` with ``%hhd``, which specifies a ``char``-sized integer), checks for
3752+ ``format_matches`` require specified argument sizes to match exactly.
3753+ * Format strings expecting a variable modifier (such as ``%*s``) are
3754+ incompatible with format strings that would itemize the variable modifiers
3755+ (such as ``%i %s``), even if the two specify ABI-compatible argument lists.
3756+ * All pointer specifiers, modifiers aside, are mutually incompatible. For
3757+ instance, ``%s`` is not compatible with ``%p``, and ``%p`` is not compatible
3758+ with ``%n``, and ``%hhn`` is incompatible with ``%s``, even if the pointers
3759+ are ABI-compatible or identical on the selected platform. However, ``%0.5s``
3760+ is compatible with ``%s``, since the difference only exists in modifier flags.
3761+ This is not overridable with ``-Wformat-pedantic`` or its inverse, which
3762+ control similar behavior in ``-Wformat``.
3763+
3764+ At this time, clang implements ``format_matches`` only for format types in the
3765+ ``printf`` family. This includes variants such as Apple's NSString format and
3766+ the FreeBSD ``kprintf``, but excludes ``scanf``. Using a known but unsupported
3767+ format silently fails in order to be compatible with other implementations that
3768+ would support these formats.
3769+
3770+ }];
3771+ }
3772+
36473773def FlagEnumDocs : Documentation {
36483774 let Category = DocCatDecl;
36493775 let Content = [{
0 commit comments