[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf
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&id=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", &s); } // CHECK: printf("%zd", (ssize_t) 42); +// CHECK: scanf("%zd", &s) 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", &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
[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf
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", &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 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", &s); } // CHECK: printf("%zd", (ssize_t) 42); +// CHECK: scanf("%zd", &s) 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 cfe-co
[PATCH] D35652: [clang] Fix handling of "%zd" format specifier in scanf
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", &d3); // 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
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
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", &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 *'}} + + double d3 = 0.; + scanf("%zn", &d3); // 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", &s); } // CHECK: printf("%zd", (ssize_t) 42); +// CHECK: scanf("%zd", &s) 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 LengthModif