manas updated this revision to Diff 481560. manas added a comment. Rebase
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112621/new/ https://reviews.llvm.org/D112621 Files: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp clang/test/Analysis/constant-folding.c Index: clang/test/Analysis/constant-folding.c =================================================================== --- clang/test/Analysis/constant-folding.c +++ clang/test/Analysis/constant-folding.c @@ -293,13 +293,6 @@ clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} } - if (u1 > INT_MAX && u1 <= UINT_MAX / 2 + 4 && u1 != UINT_MAX / 2 + 2 && - u1 != UINT_MAX / 2 + 3 && s1 >= INT_MIN + 1 && s1 <= INT_MIN + 2) { - // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4], - // s1: [INT_MIN+1, INT_MIN+2] - clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} - } - if (u1 >= INT_MIN && u1 <= INT_MIN + 2 && s1 > INT_MIN + 2 && s1 < INT_MIN + 4) { // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4], @@ -309,7 +302,7 @@ if (s1 < 0 && s1 > -4 && u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) { // s1: [-3, -1], u1: [UINT_MAX - 3, UINT_MAX - 2] - clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} + clang_analyzer_eval(u1 != s1); // expected-warning{{UNKNOWN}} } if (s1 < 1 && s1 > -6 && s1 != -4 && s1 != -3 && @@ -324,6 +317,11 @@ clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} } + if (s1 > 4 && u1 < 4) { + // s1: [4, INT_MAX], u1: [0, 3] + clang_analyzer_eval(s1 != u1); // expected-warning{{TRUE}} + } + // Check when RHS is in between two Ranges in LHS if (((u1 >= 1 && u1 <= 2) || (u1 >= 8 && u1 <= 9)) && u2 >= 5 && u2 <= 6) { @@ -401,9 +399,12 @@ clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}} } + // FIXME: Casting smaller signed types to unsigned one may leave us with + // overlapping values, falsely indicating UNKNOWN, where it is possible to + // assert TRUE. if (uch > 1 && sch < 1) { - // uch: [2, CHAR_MAX], sch: [SCHAR_MIN, 0] - clang_analyzer_eval(uch != sch); // expected-warning{{TRUE}} + // uch: [2, UCHAR_MAX], sch: [SCHAR_MIN, 0] + clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}} } if (uch <= 1 && uch >= 1 && sch <= 1 && sch >= 1) { @@ -417,9 +418,10 @@ clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}} } + // FIXME: Casting leave us with overlapping values. Should be TRUE. if (ush > 1 && ssh < 1) { // ush: [2, USHRT_MAX], ssh: [SHRT_MIN, 0] - clang_analyzer_eval(ush != ssh); // expected-warning{{TRUE}} + clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}} } if (ush <= 1 && ush >= 1 && ssh <= 1 && ssh >= 1) { Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -1619,13 +1619,10 @@ RangeSet RHS, QualType T) { - // We must check for empty RangeSets. This gets done via VisitBinaryOperator - // for other operators, but BO_NE is handled specifically. - if (LHS.isEmpty() || RHS.isEmpty()) - return RangeFactory.getEmptySet(); + assert(!LHS.isEmpty() && !RHS.isEmpty() && "Both ranges should be non-empty"); if (LHS.getAPSIntType() == RHS.getAPSIntType()) { - if (intersect(RangeFactory, LHS, RHS) == RangeFactory.getEmptySet()) + if (intersect(RangeFactory, LHS, RHS).isEmpty()) return getTrueRange(T); } else { @@ -1636,8 +1633,7 @@ RangeSet CastedLHS = RangeFactory.castTo(LHS, CastingType); RangeSet CastedRHS = RangeFactory.castTo(RHS, CastingType); - if (intersect(RangeFactory, CastedLHS, CastedRHS) == - RangeFactory.getEmptySet()) + if (intersect(RangeFactory, CastedLHS, CastedRHS).isEmpty()) return getTrueRange(T); }
Index: clang/test/Analysis/constant-folding.c =================================================================== --- clang/test/Analysis/constant-folding.c +++ clang/test/Analysis/constant-folding.c @@ -293,13 +293,6 @@ clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} } - if (u1 > INT_MAX && u1 <= UINT_MAX / 2 + 4 && u1 != UINT_MAX / 2 + 2 && - u1 != UINT_MAX / 2 + 3 && s1 >= INT_MIN + 1 && s1 <= INT_MIN + 2) { - // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4], - // s1: [INT_MIN+1, INT_MIN+2] - clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} - } - if (u1 >= INT_MIN && u1 <= INT_MIN + 2 && s1 > INT_MIN + 2 && s1 < INT_MIN + 4) { // u1: [INT_MAX+1, INT_MAX+1]U[INT_MAX+4, INT_MAX+4], @@ -309,7 +302,7 @@ if (s1 < 0 && s1 > -4 && u1 > UINT_MAX - 4 && u1 < UINT_MAX - 1) { // s1: [-3, -1], u1: [UINT_MAX - 3, UINT_MAX - 2] - clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} + clang_analyzer_eval(u1 != s1); // expected-warning{{UNKNOWN}} } if (s1 < 1 && s1 > -6 && s1 != -4 && s1 != -3 && @@ -324,6 +317,11 @@ clang_analyzer_eval(u1 != s1); // expected-warning{{TRUE}} } + if (s1 > 4 && u1 < 4) { + // s1: [4, INT_MAX], u1: [0, 3] + clang_analyzer_eval(s1 != u1); // expected-warning{{TRUE}} + } + // Check when RHS is in between two Ranges in LHS if (((u1 >= 1 && u1 <= 2) || (u1 >= 8 && u1 <= 9)) && u2 >= 5 && u2 <= 6) { @@ -401,9 +399,12 @@ clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}} } + // FIXME: Casting smaller signed types to unsigned one may leave us with + // overlapping values, falsely indicating UNKNOWN, where it is possible to + // assert TRUE. if (uch > 1 && sch < 1) { - // uch: [2, CHAR_MAX], sch: [SCHAR_MIN, 0] - clang_analyzer_eval(uch != sch); // expected-warning{{TRUE}} + // uch: [2, UCHAR_MAX], sch: [SCHAR_MIN, 0] + clang_analyzer_eval(uch != sch); // expected-warning{{UNKNOWN}} } if (uch <= 1 && uch >= 1 && sch <= 1 && sch >= 1) { @@ -417,9 +418,10 @@ clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}} } + // FIXME: Casting leave us with overlapping values. Should be TRUE. if (ush > 1 && ssh < 1) { // ush: [2, USHRT_MAX], ssh: [SHRT_MIN, 0] - clang_analyzer_eval(ush != ssh); // expected-warning{{TRUE}} + clang_analyzer_eval(ush != ssh); // expected-warning{{UNKNOWN}} } if (ush <= 1 && ush >= 1 && ssh <= 1 && ssh >= 1) { Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -1619,13 +1619,10 @@ RangeSet RHS, QualType T) { - // We must check for empty RangeSets. This gets done via VisitBinaryOperator - // for other operators, but BO_NE is handled specifically. - if (LHS.isEmpty() || RHS.isEmpty()) - return RangeFactory.getEmptySet(); + assert(!LHS.isEmpty() && !RHS.isEmpty() && "Both ranges should be non-empty"); if (LHS.getAPSIntType() == RHS.getAPSIntType()) { - if (intersect(RangeFactory, LHS, RHS) == RangeFactory.getEmptySet()) + if (intersect(RangeFactory, LHS, RHS).isEmpty()) return getTrueRange(T); } else { @@ -1636,8 +1633,7 @@ RangeSet CastedLHS = RangeFactory.castTo(LHS, CastingType); RangeSet CastedRHS = RangeFactory.castTo(RHS, CastingType); - if (intersect(RangeFactory, CastedLHS, CastedRHS) == - RangeFactory.getEmptySet()) + if (intersect(RangeFactory, CastedLHS, CastedRHS).isEmpty()) return getTrueRange(T); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits