summaryrefslogtreecommitdiffstats
path: root/clang/test/Sema/format-strings-scanf.c
diff options
context:
space:
mode:
authorAlexander Shaposhnikov <shal1t712@gmail.com>2017-09-28 23:11:31 +0000
committerAlexander Shaposhnikov <shal1t712@gmail.com>2017-09-28 23:11:31 +0000
commit195b25cf3cbde92e8613465571b5f3511c5cc69d (patch)
tree5e3ab1261aa73902302fe2e178ef81f5b939a099 /clang/test/Sema/format-strings-scanf.c
parentef29a84d4890e00abdf1892f67a431e2624f89ec (diff)
downloadbcm5719-llvm-195b25cf3cbde92e8613465571b5f3511c5cc69d.tar.gz
bcm5719-llvm-195b25cf3cbde92e8613465571b5f3511c5cc69d.zip
[clang] Add getUnsignedPointerDiffType method
C11 standard refers to the unsigned counterpart of the type ptrdiff_t in the paragraph 7.21.6.1p7 where it defines the format specifier %tu. In Clang (in PrintfFormatString.cpp, lines 508-510) there is a FIXME for this case, in particular, Clang didn't diagnose %tu issues at all, i.e. it didn't emit any warnings on the code printf("%tu", 3.14). In this diff we add a method getUnsignedPointerDiffType for getting the corresponding type similarly to how it's already done in the other analogous cases (size_t, ssize_t, ptrdiff_t etc) and fix -Wformat diagnostics for %tu plus the emitted fix-it as well. Test plan: make check-all Differential revision: https://reviews.llvm.org/D38270 llvm-svn: 314470
Diffstat (limited to 'clang/test/Sema/format-strings-scanf.c')
-rw-r--r--clang/test/Sema/format-strings-scanf.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/test/Sema/format-strings-scanf.c b/clang/test/Sema/format-strings-scanf.c
index e700d10618d..b7cdd7dd4a9 100644
--- a/clang/test/Sema/format-strings-scanf.c
+++ b/clang/test/Sema/format-strings-scanf.c
@@ -13,6 +13,16 @@ typedef __SIZE_TYPE__ size_t;
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;
@@ -200,6 +210,26 @@ void test_size_types() {
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 *'}}
OpenPOWER on IntegriCloud