From: Hans Wennborg Date: Thu, 12 Jan 2012 15:07:16 +0000 (+0000) Subject: scanf analysis: the 'a' length modifier is valid with a scanlist X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=28058d179ae40edc66135458849f1073c841bc74;p=clang scanf analysis: the 'a' length modifier is valid with a scanlist Before r148025 we (accidentally) didn't check whether a length modifier is appropriate for a scanlist, but now we do. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148026 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp index 8e295aa2be..351973529c 100644 --- a/lib/Analysis/FormatString.cpp +++ b/lib/Analysis/FormatString.cpp @@ -550,6 +550,7 @@ bool FormatSpecifier::hasValidLengthModifier() const { switch (CS.getKind()) { case ConversionSpecifier::sArg: case ConversionSpecifier::SArg: + case ConversionSpecifier::ScanListArg: return true; default: return false; diff --git a/test/Sema/format-strings-c90.c b/test/Sema/format-strings-c90.c index 1b00c38c04..74e5fb17cc 100644 --- a/test/Sema/format-strings-c90.c +++ b/test/Sema/format-strings-c90.c @@ -7,6 +7,7 @@ int printf(const char *restrict, ...); void foo(char **sp, float *fp, int *ip) { /* TODO: Warn that the 'a' length modifier is an extension. */ scanf("%as", sp); + scanf("%a[abc]", sp); /* TODO: Warn that the 'a' conversion specifier is a C99 feature. */ scanf("%a", fp); diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c index 2e32a26ac5..7a2f278aeb 100644 --- a/test/Sema/format-strings-scanf.c +++ b/test/Sema/format-strings-scanf.c @@ -68,8 +68,9 @@ void test_variants(int *i, const char *s, ...) { vsscanf(buf, "%[abc", ap); // expected-warning{{no closing ']' for '%[' in scanf format string}} } -void test_scanlist(int *ip) { +void test_scanlist(int *ip, char *sp) { scanf("%[abc]", ip); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int *'}} + scanf("%h[abc]", sp); // expected-warning{{length modifier 'h' results in undefined behavior or no effect with '[' conversion specifier}} } void test_alloc_extension(char **sp, wchar_t **lsp) {