llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.1k stars 12.01k forks source link

`-Wshorten-64-to-32` doesn't handle `+=` #32906

Open smeenai opened 7 years ago

smeenai commented 7 years ago
Bugzilla Link 33559
Version trunk
OS All
CC @alexshap,@compnerd,@LebedevRI,@zygoloid,@seanm

Extended Description

% cat reduced.c
void f(int x, long long y) {
    x += y;
}

% clang -fsyntax-only -Wshorten-64-to-32 reduced.c
# no warning

Compare to

% cat reduced.c
void f(int x, long long y) {
    x = x + y;
}

% clang -fsyntax-only -Wshorten-64-to-32 reduced.c
reduced.c:2:11: warning: implicit conversion loses integer precision: 'long long' to 'int' [-Wshorten-64-to-32]
    x = x + y;
      ~ ~~^~~
1 warning generated.
LebedevRI commented 5 years ago

Looks like one need to look into AnalyzeCompoundAssignment() in SemaChecking.cpp While it does call AnalyzeImplicitConversions() for the LHS/RHS, it does not do anything to analyze whether the result is then demoted.

Given that AnalyzeImplicitConversions()/CheckImplicitConversion() explicitly expect the Expr type to be the src type, and passed QualType to be the dst type, and issue warnings based on their mismatch, they won't work, because naturally the type of compound assign operator is the final type, since the casts are hidden..

smeenai commented 5 years ago

@​lebedev.ri https://reviews.llvm.org/D53949 caught my eye (it turns out that's for a sanitizer, but it's a similar example of compound assignment operators not behaving like their decomposed versions). Do you have any insights here?

crazydef commented 3 months ago

I've just been hit with this bug too. With operator |= when accidentally* ORing a bit-64 constant into a 32-bit integer.

*When the code was originally written the constants were also 32-bit.

But without the compiler to tell me otherwise, I have no way of knowing if there are other instances of this in my code without checking each one by hand.