<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/128746>128746</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
-Wsign-compare false positive with comparison against literal -1
</td>
</tr>
<tr>
<th>Labels</th>
<td>
false-positive
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
alejandro-colomar
</td>
</tr>
</table>
<pre>
In C, comparing an unsigned integer (of rank no less than that of `int`) to a literal `-1` is a common idiom in error-handling code, and is harmless. The -1 is first sign-extended to the width of the unsigned integer, and then is converted into an unsigned value, which is The Right Thing to do.
However, `-Wsign-compare` (in `-Wextra`) diagnoses about it:
```c
alx@debian:~/tmp$ cat f.c
int
main(void)
{
unsigned long i = 3;
if (i == -1)
return 1;
return 0;
}
alx@debian:~/tmp$ clang -Wsign-compare f.c
f.c:6:8: warning: comparison of integers of different signs: 'unsigned long' and 'int' [-Wsign-compare]
6 | if (i == -1)
| ~ ^ ~~
1 warning generated.
```
A user wanting to turn off the diagnostic, may choose to add a cast somewhere in that comparison, and chances are decent that it will put it in the non-literal part (I've seen code like that). And the problem is that such code has a bug, which cannot even be diagnosed (because the cast turns off the diagnostic).
Or maybe it adds a cast in the right place, but the type of the cast is erroneous, which would similarly result in a silent bug.
Another approach that a user might take, to prevent both the diagnostic and a cast, would be to use a suffix in the literal, such as `if (i == -1u)`. This will similarly result in a silent (non-diagnosable) bug. And since we don't have a way to create a suffix for a `time_t`, the programmer has to do a good guess (or write a lot of macros that might get it correctly.
All workarounds result in worse code than a literal `-1`, both in terms of safety, and in terms of readability.
Let's just not warn when comparing an unsigned integer against literal `-1` (with no suffixes), as long as the unsigned integer type has rank no less than `int` (so that the promotions result in an unsigned type, and the -1 is sign-extended).
Here's a bug I opened against GCC: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119011>
Cc: @jwakely , @AaronBallman , @ThePhD
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJx8Vl1v4zoO_TXKC5HAlvP5kIc0vdk7wAK7WAywjxe0xNiaylIgyXGzD_3tC8pOm3bmThC0iS2T5xweksEYTeOI9mL1JFbPM-xT68MeLf1Ap4OfK299h2FWe33bf3NwFPIIyncXDMY1gA56l0NoMC5RQwGE3PozBHQv4DxYihFSi47_JPBnEOvCuCTWhZA7SB4QrEkU0PKdeSnWBZgIyFk678Bo4zswDigEH-YtOm05tfKaGAw6zedbDB3nWgB8bwnmJV88mxATML45vSZymjRnTC3BYHRqGQ5_-crhHje15DiO8u5KIY0H_CfWV7R9xjG0RrV8mNP_xzRtgu8tA00etF-I4iCKw59-oOsYn8n-N0Mb5SQmLuTWuPEWvaaAk0raYON8pAhY-z6BSaI6jBH5vS7GtxLFAe2rWBaaaoNOVIc3IU-puwi5BIUJzgs-w_IXhw6NE3J79UYLueM4m6cccPdOznrXgAFRPUMlqqd7xp05Z6R8g-_NyylAsRPFLlDqg4Py8YHpWjFd2zz_HqlF18BndRg6iOLADKrDWlSHragOMGBwxjX8cXJl9I7LOlUy8mdtzmcK5EYrRD4s5OYTSyE3ueJCblgduQGxevpSnxWjBgBYg9gc4W9EgPziA4-vNxCrPwDe3kRxKO-ooSFHARPpxWMZR9UO0EcKMKBLk4uyhP48WnayRDKKzdThDVTrfaTcUVpz_yB733c0tBSIOyh34IdMd5erFp1ibwUCTYp1yidNgsFYC5fsuDEAgfNufm_YC4bEInwTcnMliEQu9yVY80I5iJC7BcBh7CW4BF9b6rhLcobYq3Z8oEVu-bpvPlpJoXM-AV3JQf1OmLhG25oU9ky2pZEnaxN_Kc5uar1_BVapJqaCWse7QhOtkDv2YlHlbq77lC-n24XuU2I8HvMgcuT7-IF18L3VEE1nLAZ7g0Cxtzk2QjSWJa37ZkJycD61FAAvl-BRtaMWONa7yzgSvmQYycMlsAIJap_aL-Ry9UYaGUoGUWcLsDgIsT-fzeud4lQ1PpqFx5hn8Vcb9-zjdZEHqYmjBX7LTMgtm2LChbUlnlnMNxc-GqcIBgLNltskaPHK4Aa8MVIVCNMD2LMPgAwsmY7-GvfE8e6eJmDXUch2yXMVEBrvNTQ97xlePQGGYHJA6_O-6VAFPxluVLehbGjlQyCV7O1eF2th8OEFg--djg9UBx8ijUbNq-znlZU9wxVirSl0ee5EPFO6vS-phzuBUGNtrEn35P8knjoRfvQxAfueZwQMbe6o361bbNC4mH5eokJuB5NaXsKjtBS5sowmjpOdRfzF9htNzxL_vMTflzeHj35UdSpO55Px7lG3R7wc9GGvThv6027-aNY_KVCWI88E-Ab-QhzkTvYfx2Oe4tWxTenCE13Ik5CnRqlF4_qFD42Qp7pv_mesRSFPsfXDX2xJ1RhRnYwW1XNZ7oqyFNUfY86jyiGXxY8BX8jeIG_pZXHA4N0TWtsx__Ha95b-3T7DTO8rvat2OKN9uVkWq2K53mxn7V6WartU2-1ayXW1xhVWcr2s691yV-tyt97OzF4WclVIuSo3VVmuFqQ2W6LleV3XpS6lFMuCOjR2Ye21Yz4zE2NP-1JuN8v1zGJNNuafbVKe0UaaX3w0yVxJSMk_5cKen5zXfRPFsrAmpvgRK5lkaf91w3IYuIeBbJ6HpfrVaPNy1ge7_1IAk9q-XijfCXnidNO_-SX4H6SSkKfMIwp5mqhc9_L_AQAA__-0xXCb">