]> granicus.if.org Git - clang/commitdiff
scanf analysis: the 'a' length modifier is valid with a scanlist
authorHans Wennborg <hans@hanshq.net>
Thu, 12 Jan 2012 15:07:16 +0000 (15:07 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 12 Jan 2012 15:07:16 +0000 (15:07 +0000)
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

lib/Analysis/FormatString.cpp
test/Sema/format-strings-c90.c
test/Sema/format-strings-scanf.c

index 8e295aa2be1c333d9e49078a334b96949c0d6083..351973529ceb0d84ecc5e6ac3341ffa2a6f133f5 100644 (file)
@@ -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;
index 1b00c38c0411d9c9048c35c0ba00fc8b5f0d9d1b..74e5fb17ccf7975b96e6ede5481691f88f9d7ab1 100644 (file)
@@ -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);
index 2e32a26ac5cd0b74ad53cc608b80fb78ca2d1d51..7a2f278aebd24cbe4284dae8c4ffb4e3dba04d44 100644 (file)
@@ -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) {