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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits