summaryrefslogtreecommitdiff
path: root/test/Sema/format-strings-scanf.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/Sema/format-strings-scanf.c')
-rw-r--r--test/Sema/format-strings-scanf.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
index 7a92842b2454..b7cdd7dd4a9a 100644
--- a/test/Sema/format-strings-scanf.c
+++ b/test/Sema/format-strings-scanf.c
@@ -1,10 +1,28 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s
// Test that -Wformat=0 works:
-// RUN: %clang_cc1 -fsyntax-only -Werror -Wformat=0 %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -Werror -Wformat=0 %s
#include <stdarg.h>
-typedef __typeof(sizeof(int)) size_t;
+typedef __SIZE_TYPE__ size_t;
+#define __SSIZE_TYPE__ \
+ __typeof__(_Generic((__SIZE_TYPE__)0, \
+ unsigned long long int : (long long int)0, \
+ unsigned long int : (long int)0, \
+ unsigned int : (int)0, \
+ unsigned short : (short)0, \
+ unsigned char : (signed char)0))
+typedef __SSIZE_TYPE__ ssize_t;
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__ \
+ __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+ long long int : (unsigned long long int)0, \
+ long int : (unsigned long int)0, \
+ int : (unsigned int)0, \
+ short : (unsigned short)0, \
+ signed char : (unsigned char)0))
+
typedef struct _FILE FILE;
typedef __WCHAR_TYPE__ wchar_t;
@@ -172,6 +190,46 @@ void test_qualifiers(const int *cip, volatile int* vip,
scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
}
+void test_size_types() {
+ size_t s = 0;
+ scanf("%zu", &s); // No warning.
+
+ double d1 = 0.;
+ scanf("%zu", &d1); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ssize_t ss = 0;
+ scanf("%zd", &s); // No warning.
+
+ double d2 = 0.;
+ scanf("%zd", &d2); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ssize_t sn = 0;
+ scanf("%zn", &sn); // No warning.
+
+ double d3 = 0.;
+ scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
+void test_ptrdiff_t_types() {
+ __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+ scanf("%tu", &p1); // No warning.
+
+ double d1 = 0.;
+ scanf("%tu", &d1); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ptrdiff_t p2 = 0;
+ scanf("%td", &p2); // No warning.
+
+ double d2 = 0.;
+ scanf("%td", &d2); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+ ptrdiff_t p3 = 0;
+ scanf("%tn", &p3); // No warning.
+
+ double d3 = 0.;
+ scanf("%tn", &d3); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
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 *'}}