this patch enhances clang check format strings defined in list
initialization expressions. Before this patch clang just thought these
expressions are not string literal.
Example:
constexpr const char *foo() { return "%s %d"; }
struct Bar {
static constexpr char value[] = {'%', 's', '%', 'd', '\0'};
};
constexpr const char *foobar() { return Bar::value; }
constexpr const char *foooobar() { return foobar(); }
int main() {
printf(foo(), "abc", "def");
printf(Bar::value, "abc", "def");
printf(foobar(), "abc", "def");
printf(foooobar(), "abc", "def");
return 0;
}Diagnostics after this patch:
<source>:14:24: warning: format specifies type 'int' but the argument has type 'const char *' [-Wformat]
printf(foo(), "abc", "def");
~~~~~ ^~~~~
<source>:3:42: note: format string is defined here
constexpr const char *foo() { return "%s %d"; }
^~
%s
<source>:15:29: warning: format specifies type 'int' but the argument has type 'const char *' [-Wformat]
printf(Bar::value, "abc", "def");
^~~~~
<source>:16:27: warning: format specifies type 'int' but the argument has type 'const char *' [-Wformat]
printf(foobar(), "abc", "def");
^~~~~
<source>:17:29: warning: format specifies type 'int' but the argument has type 'const char *' [-Wformat]
printf(foooobar(), "abc", "def");
^~~~~
4 warnings generated.
I'd prefer not to add more FIXME comments.