@@ -3886,6 +3886,132 @@ behavior of the program is undefined.
38863886 }];
38873887}
38883888
3889+ def FormatMatchesDocs : Documentation {
3890+ let Category = DocCatFunction;
3891+ let Content = [{
3892+
3893+ The ``format`` attribute is the basis for the enforcement of diagnostics in the
3894+ ``-Wformat`` family, but it only handles the case where the format string is
3895+ passed along with the arguments it is going to format. It cannot handle the case
3896+ where the format string and the format arguments are passed separately from each
3897+ other. For instance:
3898+
3899+ .. code-block:: c
3900+
3901+ static const char *first_name;
3902+ static double todays_temperature;
3903+ static int wind_speed;
3904+
3905+ void say_hi(const char *fmt) {
3906+ printf(fmt, first_name, todays_temperature);
3907+ // ^ warning: format string is not a string literal
3908+ printf(fmt, first_name, wind_speed);
3909+ // ^ warning: format string is not a string literal
3910+ }
3911+
3912+ int main() {
3913+ say_hi("hello %s, it is %g degrees outside");
3914+ say_hi("hello %s, it is %d degrees outside!");
3915+ // ^ no diagnostic, but %d cannot format doubles
3916+ }
3917+
3918+ In this example, ``fmt`` is expected to format a ``const char *`` and a
3919+ ``double``, but these values are not passed to ``say_hi``. Without the
3920+ ``format`` attribute (which cannot apply in this case), the -Wformat-nonliteral
3921+ diagnostic unnecessarily triggers in the body of ``say_hi``, and incorrect
3922+ ``say_hi`` call sites do not trigger a diagnostic.
3923+
3924+ To complement the ``format`` attribute, Clang also defines the
3925+ ``format_matches`` attribute. Its syntax is similar to the ``format``
3926+ attribute's, but instead of taking the index of the first formatted value
3927+ argument, it takes a C string literal with the expected specifiers:
3928+
3929+ .. code-block:: c
3930+
3931+ static const char *first_name;
3932+ static double todays_temperature;
3933+ static int wind_speed;
3934+
3935+ __attribute__((__format_matches__(printf, 1, "%s %g")))
3936+ void say_hi(const char *fmt) {
3937+ printf(fmt, first_name, todays_temperature); // no dignostic
3938+ printf(fmt, first_name, wind_speed); // warning: format specifies type 'int' but the argument has type 'double'
3939+ }
3940+
3941+ int main() {
3942+ say_hi("hello %s, it is %g degrees outside");
3943+ say_hi("it is %g degrees outside, have a good day %s!");
3944+ // warning: format specifies 'double' where 'const char *' is required
3945+ // warning: format specifies 'const char *' where 'double' is required
3946+ }
3947+
3948+ The third argument to ``format_matches`` is expected to evaluate to a **C string
3949+ literal** even when the format string would normally be a different type for the
3950+ given flavor, like a ``CFStringRef`` or a ``NSString *``.
3951+
3952+ The only requirement on the format string literal is that it has specifiers
3953+ that are compatible with the arguments that will be used. It can contain
3954+ arbitrary non-format characters. For instance, for the purposes of compile-time
3955+ validation, ``"%s scored %g%% on her test"`` and ``"%s%g"`` are interchangeable
3956+ as the format string argument. As a means of self-documentation, users may
3957+ prefer the former when it provides a useful example of an expected format
3958+ string.
3959+
3960+ In the implementation of a function with the ``format_matches`` attribute,
3961+ format verification works as if the format string was identical to the one
3962+ specified in the attribute.
3963+
3964+ .. code-block:: c
3965+
3966+ __attribute__((__format_matches__(printf, 1, "%s %g")))
3967+ void say_hi(const char *fmt) {
3968+ printf(fmt, "person", 546);
3969+ // ^ warning: format specifies type 'double' but the
3970+ // argument has type 'int'
3971+ // note: format string is defined here:
3972+ // __attribute__((__format_matches__(printf, 1, "%s %g")))
3973+ // ^~
3974+ }
3975+
3976+
3977+ At the call sites of functions with the ``format_matches`` attribute, format
3978+ verification instead compares the two format strings to evaluate their
3979+ equivalence. Each format flavor defines equivalence between format specifiers.
3980+ Generally speaking, two specifiers are equivalent if they format the same type.
3981+ For instance, in the ``printf`` flavor, ``%2i`` and ``%-0.5d`` are compatible.
3982+ When ``-Wformat-signedness`` is disabled, ``%d`` and ``%u`` are compatible. For
3983+ a negative example, ``%ld`` is incompatible with ``%d``.
3984+
3985+ Do note the following un-obvious cases:
3986+
3987+ * Passing ``NULL`` as the format string does not trigger format diagnostics.
3988+ * When the format string is not NULL, it cannot _miss_ specifiers, even in
3989+ trailing positions. For instance, ``%d`` is not accepted when the required
3990+ format is ``%d %d %d``.
3991+ * While checks for the ``format`` attribute tolerate sone size mismatches
3992+ that standard argument promotion renders immaterial (such as formatting an
3993+ ``int`` with ``%hhd``, which specifies a ``char``-sized integer), checks for
3994+ ``format_matches`` require specified argument sizes to match exactly.
3995+ * Format strings expecting a variable modifier (such as ``%*s``) are
3996+ incompatible with format strings that would itemize the variable modifiers
3997+ (such as ``%i %s``), even if the two specify ABI-compatible argument lists.
3998+ * All pointer specifiers, modifiers aside, are mutually incompatible. For
3999+ instance, ``%s`` is not compatible with ``%p``, and ``%p`` is not compatible
4000+ with ``%n``, and ``%hhn`` is incompatible with ``%s``, even if the pointers
4001+ are ABI-compatible or identical on the selected platform. However, ``%0.5s``
4002+ is compatible with ``%s``, since the difference only exists in modifier flags.
4003+ This is not overridable with ``-Wformat-pedantic`` or its inverse, which
4004+ control similar behavior in ``-Wformat``.
4005+
4006+ At this time, clang implements ``format_matches`` only for format types in the
4007+ ``printf`` family. This includes variants such as Apple's NSString format and
4008+ the FreeBSD ``kprintf``, but excludes ``scanf``. Using a known but unsupported
4009+ format silently fails in order to be compatible with other implementations that
4010+ would support these formats.
4011+
4012+ }];
4013+ }
4014+
38894015def FlagEnumDocs : Documentation {
38904016 let Category = DocCatDecl;
38914017 let Content = [{
0 commit comments