Reduce false positives in printf/scanf format checker
Summary:
The printf/scanf format checker is a little over-zealous in handling the conditional operator. This patch reduces work by not checking code-paths that are never used and reduces false positives regarding uncovered arguments, for example in the code fragment:
printf(minimal ? "%i\n" : "%i: %s\n", code, msg);
Reviewers: rtrieu
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D15636
llvm-svn: 262025
diff --git a/clang/test/Sema/format-strings-scanf.c b/clang/test/Sema/format-strings-scanf.c
index d3a03ad..7a92842 100644
--- a/clang/test/Sema/format-strings-scanf.c
+++ b/clang/test/Sema/format-strings-scanf.c
@@ -18,7 +18,7 @@
int vsscanf(const char * restrict, const char * restrict, va_list);
void test(const char *s, int *i) {
- scanf(s, i); // expected-warning{{ormat string is not a string literal}}
+ scanf(s, i); // expected-warning{{format string is not a string literal}}
scanf("%0d", i); // expected-warning{{zero field width in scanf format string is unused}}
scanf("%00d", i); // expected-warning{{zero field width in scanf format string is unused}}
scanf("%d%[asdfasdfd", i, s); // expected-warning{{no closing ']' for '%[' in scanf format string}}
@@ -171,3 +171,15 @@
scanf("%d", (ip_t)0); // No warning.
scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
}
+
+void check_conditional_literal(char *s, int *i) {
+ scanf(0 ? "%s" : "%d", i); // no warning
+ scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}}
+ scanf(0 ? "%d %d" : "%d", i); // no warning
+ scanf(1 ? "%d %d" : "%d", i); // expected-warning{{more '%' conversions than data arguments}}
+ scanf(0 ? "%d %d" : "%d", i, s); // expected-warning{{data argument not used}}
+ scanf(1 ? "%d %s" : "%d", i, s); // no warning
+ scanf(i ? "%d %s" : "%d", i, s); // no warning
+ scanf(i ? "%d" : "%d", i, s); // expected-warning{{data argument not used}}
+ scanf(i ? "%s" : "%d", s); // expected-warning{{format specifies type 'int *'}}
+}