1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -verify -Wformat -Wformat-signedness %s
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -std=c11 -fsyntax-only -verify -Wformat -Wformat-signedness %s
// Verify that -Wformat-signedness alone (without -Wformat) trigger the
// warnings. Note in gcc this will not trigger the signedness warnings as
// -Wformat is default off in gcc.
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -verify -Wformat-signedness %s
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -std=c11 -fsyntax-only -verify -Wformat-signedness %s
// Verify that -Wformat-signedness warnings are not reported with only -Wformat
// (gcc compat).
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wformat -verify=okay %s
// Verify that -Wformat-signedness with -Wno-format are not reported (gcc compat).
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wformat-signedness -Wno-format -verify=okay %s
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wno-format -Wformat-signedness -verify=okay %s
// okay-no-diagnostics
int printf(const char *restrict format, ...);
int scanf(const char * restrict, ...);
void test_printf_bool(_Bool x)
{
printf("%d", x); // no-warning
printf("%u", x); // no-warning
printf("%x", x); // no-warning
}
void test_printf_char(char x)
{
printf("%c", x); // no-warning
}
void test_printf_unsigned_char(unsigned char x)
{
printf("%c", x); // no-warning
}
void test_printf_int(int x)
{
printf("%d", x); // no-warning
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}}
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}}
}
void test_printf_unsigned(unsigned x)
{
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned int'}}
printf("%u", x); // no-warning
printf("%x", x); // no-warning
}
void test_printf_long(long x)
{
printf("%ld", x); // no-warning
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}}
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}}
}
void test_printf_unsigned_long(unsigned long x)
{
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned long'}}
printf("%lu", x); // no-warning
printf("%lx", x); // no-warning
}
void test_printf_long_long(long long x)
{
printf("%lld", x); // no-warning
printf("%llu", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}}
printf("%llx", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}}
}
void test_printf_unsigned_long_long(unsigned long long x)
{
printf("%lld", x); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned long long'}}
printf("%llu", x); // no-warning
printf("%llx", x); // no-warning
}
enum enum_int {
minus_1 = -1
};
void test_printf_enum_int(enum enum_int x)
{
printf("%d", x); // no-warning
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}}
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}}
}
#ifndef _WIN32 // Disabled due to enums have different underlying type on _WIN32
enum enum_unsigned {
zero = 0
};
void test_printf_enum_unsigned(enum enum_unsigned x)
{
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has underlying type 'unsigned int'}}
printf("%u", x); // no-warning
printf("%x", x); // no-warning
}
enum enum_long {
minus_one = -1,
int_val = __INT_MAX__, // INT_MAX
unsigned_val = (unsigned)(-__INT_MAX__ -1) // (unsigned)INT_MIN
};
void test_printf_enum_long(enum enum_long x)
{
printf("%ld", x); // no-warning
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}}
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}}
}
enum enum_unsigned_long {
uint_max_plus = (unsigned long)(__INT_MAX__ *2U +1U)+1, // (unsigned long)UINT_MAX+1
};
void test_printf_enum_unsigned_long(enum enum_unsigned_long x)
{
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has underlying type 'unsigned long'}}
printf("%lu", x); // no-warning
printf("%lx", x); // no-warning
}
#endif
void test_scanf_char(char *y) {
scanf("%c", y); // no-warning
}
void test_scanf_unsigned_char(unsigned char *y) {
scanf("%c", y); // no-warning
}
void test_scanf_int(int *x) {
scanf("%d", x); // no-warning
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}}
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}}
}
void test_scanf_unsigned(unsigned *x) {
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'unsigned int *'}}
scanf("%u", x); // no-warning
scanf("%x", x); // no-warning
}
void test_scanf_long(long *x) {
scanf("%ld", x); // no-warning
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}}
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}}
}
void test_scanf_unsigned_long(unsigned long *x) {
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'unsigned long *'}}
scanf("%lu", x); // no-warning
scanf("%lx", x); // no-warning
}
void test_scanf_longlong(long long *x) {
scanf("%lld", x); // no-warning
scanf("%llu", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}}
scanf("%llx", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}}
}
void test_scanf_unsigned_longlong(unsigned long long *x) {
scanf("%lld", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'unsigned long long *'}}
scanf("%llu", x); // no-warning
scanf("%llx", x); // no-warning
}
void test_scanf_enum_int(enum enum_int *x) {
scanf("%d", x); // no-warning
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}}
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}}
}
#ifndef _WIN32 // Disabled due to enums have different underlying type on _WIN32
void test_scanf_enum_unsigned(enum enum_unsigned *x) {
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'enum enum_unsigned *'}}
scanf("%u", x); // no-warning
scanf("%x", x); // no-warning
}
void test_scanf_enum_long(enum enum_long *x) {
scanf("%ld", x); // no-warning
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}}
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}}
}
void test_scanf_enum_unsigned_long(enum enum_unsigned_long *x) {
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'enum enum_unsigned_long *'}}
scanf("%lu", x); // no-warning
scanf("%lx", x); // no-warning
}
#endif
// Verify that we get no warnings from <inttypes.h>
typedef short int int16_t;
typedef unsigned short int uint16_t;
void test_printf_priX16(int16_t x) {
printf("PRId16: %" "d" /*PRId16*/ "\n", x); // no-warning
printf("PRIi16: %" "i" /*PRIi16*/ "\n", x); // no-warning
}
void test_printf_unsigned_priX16(uint16_t x) {
printf("PRIo16: %" "o" /*PRIo16*/ "\n", x); // no-warning
printf("PRIu16: %" "u" /*PRIu16*/ "\n", x); // no-warning
printf("PRIx16: %" "x" /*PRIx16*/ "\n", x); // no-warning
printf("PRIX16: %" "X" /*PRIX16*/ "\n", x); // no-warning
}
// Verify that we can suppress a -Wformat-signedness warning by ignoring
// -Wformat (gcc compat).
void test_suppress(int x)
{
#pragma GCC diagnostic ignored "-Wformat"
printf("%u", x);
}
|