aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2012-01-12 15:07:16 +0000
committerHans Wennborg <hans@hanshq.net>2012-01-12 15:07:16 +0000
commit28058d179ae40edc66135458849f1073c841bc74 (patch)
tree66cbdf9cdefc4354ac1fb5d3cf3a9196f1fa3628
parent6de0b48c5531cfe7370e1a9eeaed0566fa65dc9b (diff)
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
-rw-r--r--lib/Analysis/FormatString.cpp1
-rw-r--r--test/Sema/format-strings-c90.c1
-rw-r--r--test/Sema/format-strings-scanf.c3
3 files changed, 4 insertions, 1 deletions
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) {