I recently ran into a case where I didn’t get a conversion warning when compiling with
-Wconversion but expected to. The simplest I have been able to get it to reproduce is with:
int warn(int i, unsigned s)
i = i + s;
int nowarn(int i, unsigned s)
i += s;
Where the result with clang 15 can be seen here: Compiler Explorer
Is there some technical reason there is no warning in this case or just a missed case?
I think this is a missed case. The way compound operators work is that both the LHS and RHS are promoted, the computation is performed, then an implicit conversion back to the LHS type is performed, and finally the assignment happens.
I think we’re missing the check for the implicit conversion back to the LHS type, roughly around here: llvm-project/SemaChecking.cpp at main · llvm/llvm-project · GitHub
I have a sneaking suspicion that the reason this check is missing is because we don’t have an
Expr * to represent the notional
i + s for the compound assignment, so we have no way to call
CheckImplicitConversion() (that checks the conversion from a source expression to a target type, but in this case we have a source type and not a source expression).
I think it’s worth filing an issue about. You can see in https://godbolt.org/z/8EEd89G5v:
-CompoundAssignOperator <line:3:5, col:10> 'int' lvalue '+=' ComputeLHSTy='unsigned int' ComputeResultTy='unsigned int'
which says that the type of the expression is
int but the computation for the result happens in
unsigned int and that’s the conversion you’re looking to be warned about.