Inspired by MSVC, which found some occurrences of this expression on our code base.
Fixes PR38950
Differential D52137
Added warning for unary minus used with unsigned type xbolva00 on Sep 15 2018, 10:55 AM. Authored by
Details Inspired by MSVC, which found some occurrences of this expression on our code base. Fixes PR38950
Diff Detail Event TimelineComment Actions /home/xbolva00/LLVM/build/lib/clang/8.0.0/include/bmiintrin.h:312:16: error: unary minus operator applied to type 'unsigned long long', result value is still unsigned return __X & -__X; @RKSimon what do you think? valid? Can we fix that header to return X & -(int)X;? Comment Actions I don't think this makes much sense. https://godbolt.org/z/2n3lQp <- i'm not sure why the second one is better, how how the first one is broken.
Comment Actions That is not correct transformation as far as i can see. Comment Actions The first is not broken, but it is now detected by this new check. I think the second form is more explicit and better. X & - (int)X is not correct Comment Actions
Standard question: what is the SNR of this warning? What value it brings? Comment Actions Cca 6-8 times / 10 000 lines. I checked and first two are bugs, I don't track other warnings yet. Anyway, I think this pattern should be diagnosed, as confusing and potentially buggy. Comment Actions I think we can and should do better about false positives here. If you move this check to SemaChecking, you can produce the warning in a context where you know what the final type is -- I don't think there's any reason to warn if the final type is signed and no wider than the promoted type of the negation. I think we should also not warn when the negation is an operand of a & or | operator whose width is no greater than the promoted type of the negation, because -power_of_2 is an idiomatic way to form a mask. Comment Actions I share your general concern about false positives, but in the specific case you mentioned— void use(int16_t x) uint8_t u8 = 1; use(-u8); —I think it'd be surprising to maybe 50% of average programmers that x's received value wasn't int16_t(255) but rather int16_t(-1). The only cases I'd personally consider "false positives" would be cases where -u32 was being used as a convenient shorthand for ~u32 + 1 a.k.a. (0u - u32)... but maybe in those cases it wouldn't be much of a burden for the programmer to just accept a fixit to (0u - u32) and be done with it. This comment was removed by xbolva00. Comment Actions Hm, isUnsignedIntegerType seems to ignore uintN_t types? int f(void) { uint8_t u8 = 1; uint8_t b = -u8; } No warning now :/ Comment Actions I find this warning confusing. I find a4 to be perfectly expected. IMO this warning should be applied only, if the effective value of the expression is not the same as in the modulo-n arithmetic. This means that if (-x) is explicitly or implicitly cast to a less wide unsigned type, it should not warn. It would consider a warning for the case of using (-x) if integer promotion rules makes it negative though. The question is, how to best patch around the warning though. What options does MSVC have for that? I.e. what equivalent expressions do not trigger this warning? Comment Actions MSVC warns for every case in the test file I uploaded here. https://godbolt.org/z/jiMFp6 Comment Actions You may be right. But 50% is a *far* too high false positive rate for a Clang warning, so the conclusion should be that we do not warn on that case. Compare that to: unsigned int n = //... long m = -n; // almost certainly a bug (if long is wider than int) or if (-n < x && x < n) // almost certainly a bug If 50% of people turn this warning off because it uselessly warns on non-bugs, we are doing our users a disservice. We need to have a clear idea of what classes of bugs we want to catch here. Unary negation applied to an unsigned type does not deserve a warning by itself, but there are certainly some contexts in which we should warn. The interesting part is identifying them.
Comment Actions "High bits are zeros" and "result is always non negative" are good candidatates to be catched here. Thanks for detailed review, Richard. Now I will look on it. Comment Actions Thanks!
|
Why is this an error?