You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix Clang bug that -Wformat-signedness is not reported properly. (#150962)
The goal is to correctly identify diagnostics that are emitted by virtue
of -Wformat-signedness.
Before this change, diagnostic messages triggered by -Wformat-signedness
might look like:
format specifies type 'unsigned int' but the argument has type 'int'
[-Wformat]
signedness of format specifier 'u' is incompatible with 'c' [-Wformat]
With this change:
format specifies type 'unsigned int' but the argument has type 'int',
which differs in signedness [-Wformat-signedness]
signedness of format specifier 'u' is incompatible with 'c'
[-Wformat-signedness]
Fix:
- handleFormatSignedness can now return NoMatchSignedness. Callers
handle this.
- warn_format_conversion_argument_type extends the message it used to
emit by a string that
mentions "signedness".
- warn_format_cmp_specifier_sign_mismatch is now correctly categorized
as a
diagnostic controlled by -Wformat-signedness.
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}}
43
-
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}}
42
+
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int', which differs in signedness}}
43
+
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int', which differs in signedness}}
44
44
}
45
45
46
46
voidtest_printf_unsigned(unsignedx)
47
47
{
48
-
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned int'}}
48
+
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned int', which differs in signedness}}
49
49
printf("%u", x); // no-warning
50
50
printf("%x", x); // no-warning
51
51
}
52
52
53
53
voidtest_printf_long(longx)
54
54
{
55
55
printf("%ld", x); // no-warning
56
-
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}}
57
-
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}}
56
+
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long', which differs in signedness}}
57
+
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long', which differs in signedness}}
58
58
}
59
59
60
60
voidtest_printf_unsigned_long(unsigned longx)
61
61
{
62
-
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned long'}}
62
+
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned long', which differs in signedness}}
63
63
printf("%lu", x); // no-warning
64
64
printf("%lx", x); // no-warning
65
65
}
66
66
67
67
voidtest_printf_long_long(long longx)
68
68
{
69
69
printf("%lld", x); // no-warning
70
-
printf("%llu", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}}
71
-
printf("%llx", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}}
70
+
printf("%llu", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long', which differs in signedness}}
71
+
printf("%llx", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long', which differs in signedness}}
72
72
}
73
73
74
74
voidtest_printf_unsigned_long_long(unsigned long longx)
75
75
{
76
-
printf("%lld", x); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned long long'}}
76
+
printf("%lld", x); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned long long', which differs in signedness}}
77
77
printf("%llu", x); // no-warning
78
78
printf("%llx", x); // no-warning
79
79
}
@@ -85,8 +85,8 @@ enum enum_int {
85
85
voidtest_printf_enum_int(enumenum_intx)
86
86
{
87
87
printf("%d", x); // no-warning
88
-
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}}
89
-
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}}
88
+
printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int', which differs in signedness}}
89
+
printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int', which differs in signedness}}
90
90
}
91
91
92
92
#ifndef_WIN32// Disabled due to enums have different underlying type on _WIN32
@@ -96,7 +96,7 @@ enum enum_unsigned {
96
96
97
97
voidtest_printf_enum_unsigned(enumenum_unsignedx)
98
98
{
99
-
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has underlying type 'unsigned int'}}
99
+
printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has underlying type 'unsigned int', which differs in signedness}}
100
100
printf("%u", x); // no-warning
101
101
printf("%x", x); // no-warning
102
102
}
@@ -110,8 +110,8 @@ enum enum_long {
110
110
voidtest_printf_enum_long(enumenum_longx)
111
111
{
112
112
printf("%ld", x); // no-warning
113
-
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}}
114
-
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}}
113
+
printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long', which differs in signedness}}
114
+
printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long', which differs in signedness}}
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has underlying type 'unsigned long'}}
123
+
printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has underlying type 'unsigned long', which differs in signedness}}
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}}
140
-
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}}
139
+
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *', which differs in signedness}}
140
+
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *', which differs in signedness}}
141
141
}
142
142
143
143
voidtest_scanf_unsigned(unsigned*x) {
144
-
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'unsigned int *'}}
144
+
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'unsigned int *', which differs in signedness}}
145
145
scanf("%u", x); // no-warning
146
146
scanf("%x", x); // no-warning
147
147
}
148
148
149
149
voidtest_scanf_long(long*x) {
150
150
scanf("%ld", x); // no-warning
151
-
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}}
152
-
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}}
151
+
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *', which differs in signedness}}
152
+
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *', which differs in signedness}}
153
153
}
154
154
155
155
voidtest_scanf_unsigned_long(unsigned long*x) {
156
-
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'unsigned long *'}}
156
+
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'unsigned long *', which differs in signedness}}
157
157
scanf("%lu", x); // no-warning
158
158
scanf("%lx", x); // no-warning
159
159
}
160
160
161
161
voidtest_scanf_longlong(long long*x) {
162
162
scanf("%lld", x); // no-warning
163
-
scanf("%llu", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}}
164
-
scanf("%llx", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}}
163
+
scanf("%llu", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *', which differs in signedness}}
164
+
scanf("%llx", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *', which differs in signedness}}
165
165
}
166
166
167
167
voidtest_scanf_unsigned_longlong(unsigned long long*x) {
168
-
scanf("%lld", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'unsigned long long *'}}
168
+
scanf("%lld", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'unsigned long long *', which differs in signedness}}
169
169
scanf("%llu", x); // no-warning
170
170
scanf("%llx", x); // no-warning
171
171
}
172
172
173
173
voidtest_scanf_enum_int(enumenum_int*x) {
174
174
scanf("%d", x); // no-warning
175
-
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}}
176
-
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}}
175
+
scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *', which differs in signedness}}
176
+
scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *', which differs in signedness}}
177
177
}
178
178
179
179
#ifndef_WIN32// Disabled due to enums have different underlying type on _WIN32
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'enum enum_unsigned *'}}
181
+
scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'enum enum_unsigned *', which differs in signedness}}
182
182
scanf("%u", x); // no-warning
183
183
scanf("%x", x); // no-warning
184
184
}
185
185
186
186
voidtest_scanf_enum_long(enumenum_long*x) {
187
187
scanf("%ld", x); // no-warning
188
-
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}}
189
-
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}}
188
+
scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *', which differs in signedness}}
189
+
scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *', which differs in signedness}}
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'enum enum_unsigned_long *'}}
193
+
scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'enum enum_unsigned_long *', which differs in signedness}}
0 commit comments