danielmarjamaki updated this revision to Diff 92634. danielmarjamaki added a comment.
I added more testcases. There are several undetected "TODO: loss of precision" right now in the tests that I would like to fix. If this patch to fix FP is accepted I will commit it and continue working on the TODO tests. If it's not accepted I will continue investigating the TODO tests anyway.. Repository: rL LLVM https://reviews.llvm.org/D25596 Files: lib/StaticAnalyzer/Checkers/ConversionChecker.cpp test/Analysis/conversion.c
Index: test/Analysis/conversion.c =================================================================== --- test/Analysis/conversion.c +++ test/Analysis/conversion.c @@ -14,6 +14,64 @@ S8 = U; } +void addAssign() { + unsigned long L = 1000; + int I = -100; + U8 += L; // TODO: Loss of precision + L += I; +} + +void subAssign() { + unsigned long L = 1000; + int I = -100; + U8 -= L; // TODO: Loss of precision + L -= I; +} + +void mulAssign() { + unsigned long L = 1000; + int I = -1; + U8 *= L; // TODO: Loss of precision + L *= I; // expected-warning {{Loss of sign in implicit conversion}} + I = 10; + L *= I; +} + +void divAssign() { + unsigned long L = 1000; + int I = -1; + U8 /= L; + L /= I; // expected-warning {{Loss of sign in implicit conversion}} +} + +void remAssign() { + unsigned long L = 1000; + int I = -1; + U8 %= L; + L %= I; // expected-warning {{Loss of sign in implicit conversion}} +} + +void andAssign() { + unsigned long L = 1000; + int I = -1; + U8 &= L; + L &= I; // expected-warning {{Loss of sign in implicit conversion}} +} + +void orAssign() { + unsigned long L = 1000; + int I = -1; + U8 |= L; // TODO: Loss of precision + L |= I; // expected-warning {{Loss of sign in implicit conversion}} +} + +void xorAssign() { + unsigned long L = 1000; + int I = -1; + U8 ^= L; // TODO: Loss of precision + L ^= I; // expected-warning {{Loss of sign in implicit conversion}} +} + void init1() { long long A = 1LL << 60; short X = A; // expected-warning {{Loss of precision in implicit conversion}} Index: lib/StaticAnalyzer/Checkers/ConversionChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/ConversionChecker.cpp +++ lib/StaticAnalyzer/Checkers/ConversionChecker.cpp @@ -73,8 +73,22 @@ // Loss of sign/precision in binary operation. if (const auto *B = dyn_cast<BinaryOperator>(Parent)) { BinaryOperator::Opcode Opc = B->getOpcode(); - if (Opc == BO_Assign || Opc == BO_AddAssign || Opc == BO_SubAssign || - Opc == BO_MulAssign) { + if (Opc == BO_Assign) { + LossOfSign = isLossOfSign(Cast, C); + LossOfPrecision = isLossOfPrecision(Cast, C); + } else if (Opc == BO_AddAssign || Opc == BO_SubAssign) { + // No loss of sign. + LossOfPrecision = isLossOfPrecision(Cast, C); + } else if (Opc == BO_MulAssign) { + LossOfSign = isLossOfSign(Cast, C); + LossOfPrecision = isLossOfPrecision(Cast, C); + } else if (Opc == BO_DivAssign || Opc == BO_RemAssign) { + LossOfSign = isLossOfSign(Cast, C); + // No loss of precision. + } else if (Opc == BO_AndAssign) { + LossOfSign = isLossOfSign(Cast, C); + // No loss of precision. + } else if (Opc == BO_OrAssign || Opc == BO_XorAssign) { LossOfSign = isLossOfSign(Cast, C); LossOfPrecision = isLossOfPrecision(Cast, C); } else if (B->isRelationalOp() || B->isMultiplicativeOp()) { @@ -153,7 +167,7 @@ } bool ConversionChecker::isLossOfPrecision(const ImplicitCastExpr *Cast, - CheckerContext &C) const { + CheckerContext &C) const { // Don't warn about explicit loss of precision. if (Cast->isEvaluatable(C.getASTContext())) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits