[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf

2017-07-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL308662: [clang] Fix handling of "%zd" in scanf (authored by 
alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D35652?vs=107569=107574#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D35652

Files:
  cfe/trunk/lib/Analysis/ScanfFormatString.cpp
  cfe/trunk/test/Sema/format-strings-fixit-ssize_t.c
  cfe/trunk/test/Sema/format-strings-scanf.c

Index: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
===
--- cfe/trunk/lib/Analysis/ScanfFormatString.cpp
+++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp
@@ -251,8 +251,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  // FIXME: ssize_t.
-  return ArgType();
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case LengthModifier::AsLongDouble:
@@ -386,7 +385,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  return ArgType(); // FIXME: ssize_t
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case LengthModifier::AsLongDouble:
Index: cfe/trunk/test/Sema/format-strings-fixit-ssize_t.c
===
--- cfe/trunk/test/Sema/format-strings-fixit-ssize_t.c
+++ cfe/trunk/test/Sema/format-strings-fixit-ssize_t.c
@@ -1,18 +1,22 @@
 // RUN: cp %s %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
warnings will be fixed by -fixit, and the resulting file should
compile cleanly with -Werror -pedantic. */
 
 int printf(char const *, ...);
+int scanf(const char *, ...);
 
 void test() {
   typedef signed long int ssize_t;
   printf("%f", (ssize_t) 42);
+  ssize_t s;
+  scanf("%f",  );
 }
 
 // CHECK: printf("%zd", (ssize_t) 42);
+// CHECK: scanf("%zd", )
Index: cfe/trunk/test/Sema/format-strings-scanf.c
===
--- cfe/trunk/test/Sema/format-strings-scanf.c
+++ cfe/trunk/test/Sema/format-strings-scanf.c
@@ -1,10 +1,18 @@
-// 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 
-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 struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -172,6 +180,26 @@
   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", ); // No warning.
+
+  double d1 = 0.;
+  scanf("%zu", ); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t ss = 0;
+  scanf("%zd", ); // No warning.
+
+  double d2 = 0.;
+  scanf("%zd", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t sn = 0;
+  scanf("%zn", ); // No warning.
+
+  double d3 = 0.;
+  scanf("%zn", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
 

[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf

2017-07-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 107569.
alexshap added a comment.

Address comments


Repository:
  rL LLVM

https://reviews.llvm.org/D35652

Files:
  lib/Analysis/ScanfFormatString.cpp
  test/Sema/format-strings-fixit-ssize_t.c
  test/Sema/format-strings-scanf.c

Index: test/Sema/format-strings-scanf.c
===
--- test/Sema/format-strings-scanf.c
+++ test/Sema/format-strings-scanf.c
@@ -1,10 +1,18 @@
-// 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 
-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 struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -172,6 +180,26 @@
   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", ); // No warning.
+
+  double d1 = 0.;
+  scanf("%zu", ); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t ss = 0;
+  scanf("%zd", ); // No warning.
+
+  double d2 = 0.;
+  scanf("%zd", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t sn = 0;
+  scanf("%zn", ); // No warning.
+
+  double d3 = 0.;
+  scanf("%zn", ); // expected-warning-re{{format specifies type 'ssize_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 *'}}
Index: test/Sema/format-strings-fixit-ssize_t.c
===
--- test/Sema/format-strings-fixit-ssize_t.c
+++ test/Sema/format-strings-fixit-ssize_t.c
@@ -1,18 +1,22 @@
 // RUN: cp %s %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
warnings will be fixed by -fixit, and the resulting file should
compile cleanly with -Werror -pedantic. */
 
 int printf(char const *, ...);
+int scanf(const char *, ...);
 
 void test() {
   typedef signed long int ssize_t;
   printf("%f", (ssize_t) 42);
+  ssize_t s;
+  scanf("%f",  );
 }
 
 // CHECK: printf("%zd", (ssize_t) 42);
+// CHECK: scanf("%zd", )
Index: lib/Analysis/ScanfFormatString.cpp
===
--- lib/Analysis/ScanfFormatString.cpp
+++ lib/Analysis/ScanfFormatString.cpp
@@ -251,8 +251,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  // FIXME: ssize_t.
-  return ArgType();
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case LengthModifier::AsLongDouble:
@@ -386,7 +385,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  return ArgType(); // FIXME: ssize_t
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case LengthModifier::AsLongDouble:
___
cfe-commits mailing list

[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf

2017-07-20 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM with a small testing nit.




Comment at: test/Sema/format-strings-scanf.c:1
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s
 

alexshap wrote:
> c11 is necessary for _Generic below.
> I have not found a more reliable way to define ssize_t
> which doesn't require a large number of #ifdef ...
Ugh, that is pretty nasty, but I cannot think of a better way to define it in a 
generic manner.



Comment at: test/Sema/format-strings-scanf.c:198
+  scanf("%zn", ); // expected-warning-re{{format specifies type 'ssize_t *' 
(aka '{{.+}}') but the argument has type 'double *'}}
+}
+

Can you add a passing test for `%zn`?


Repository:
  rL LLVM

https://reviews.llvm.org/D35652



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf

2017-07-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: test/Sema/format-strings-fixit-ssize_t.c:4
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only 
-pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | 
FileCheck %s
 

c99 is necessary for "zd"



Comment at: test/Sema/format-strings-scanf.c:1
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s
 

c11 is necessary for _Generic below.
I have not found a more reliable way to define ssize_t
which doesn't require a large number of #ifdef ...


Repository:
  rL LLVM

https://reviews.llvm.org/D35652



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf

2017-07-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

This is a follow-up for https://reviews.llvm.org/D35427
ScanfFormatString.cpp has the same issue (incorrect handling of
the specifiers for ssize_t) and this diff fixes it and adds tests.

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D35652

Files:
  lib/Analysis/ScanfFormatString.cpp
  test/Sema/format-strings-fixit-ssize_t.c
  test/Sema/format-strings-scanf.c

Index: test/Sema/format-strings-scanf.c
===
--- test/Sema/format-strings-scanf.c
+++ test/Sema/format-strings-scanf.c
@@ -1,10 +1,18 @@
-// 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 
-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 struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -172,6 +180,23 @@
   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", ); // No warning.
+
+  double d1 = 0.;
+  scanf("%zu", ); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t ss = 0;
+  scanf("%zd", ); // No warning.
+
+  double d2 = 0.;
+  scanf("%zd", ); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  double d3 = 0.;
+  scanf("%zn", ); // expected-warning-re{{format specifies type 'ssize_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 *'}}
Index: test/Sema/format-strings-fixit-ssize_t.c
===
--- test/Sema/format-strings-fixit-ssize_t.c
+++ test/Sema/format-strings-fixit-ssize_t.c
@@ -1,18 +1,22 @@
 // RUN: cp %s %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
warnings will be fixed by -fixit, and the resulting file should
compile cleanly with -Werror -pedantic. */
 
 int printf(char const *, ...);
+int scanf(const char *, ...);
 
 void test() {
   typedef signed long int ssize_t;
   printf("%f", (ssize_t) 42);
+  ssize_t s;
+  scanf("%f",  );
 }
 
 // CHECK: printf("%zd", (ssize_t) 42);
+// CHECK: scanf("%zd", )
Index: lib/Analysis/ScanfFormatString.cpp
===
--- lib/Analysis/ScanfFormatString.cpp
+++ lib/Analysis/ScanfFormatString.cpp
@@ -251,8 +251,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  // FIXME: ssize_t.
-  return ArgType();
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case LengthModifier::AsLongDouble:
@@ -386,7 +385,7 @@
 case LengthModifier::AsIntMax:
   return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
 case LengthModifier::AsSizeT:
-  return ArgType(); // FIXME: ssize_t
+  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
 case LengthModifier::AsPtrDiff:
   return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
 case