martong updated this revision to Diff 382581. martong marked 3 inline comments as done. martong added a comment.
- Add new test case - Adapt style changes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D112296/new/ https://reviews.llvm.org/D112296 Files: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp clang/test/Analysis/constraint-assignor.c Index: clang/test/Analysis/constraint-assignor.c =================================================================== --- clang/test/Analysis/constraint-assignor.c +++ clang/test/Analysis/constraint-assignor.c @@ -3,9 +3,8 @@ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -verify -// expected-no-diagnostics - void clang_analyzer_warnIfReached(); +void clang_analyzer_eval(); void rem_constant_rhs_ne_zero(int x, int y) { if (x % 3 == 0) // x % 3 != 0 -> x != 0 @@ -67,3 +66,19 @@ if (d % 2 != 0) return; } + +void remainder_with_adjustment(int x) { + if ((x + 1) % 3 == 0) // (x + 1) % 3 != 0 -> x + 1 != 0 -> x != -1 + return; + clang_analyzer_eval(x + 1 != 0); // expected-warning{{TRUE}} + clang_analyzer_eval(x != -1); // expected-warning{{TRUE}} + (void)x; // keep the constraints alive. +} + +void remainder_with_adjustment_of_composit_lhs(int x, int y) { + if ((x + y + 1) % 3 == 0) // (x + 1) % 3 != 0 -> x + 1 != 0 -> x != -1 + return; + clang_analyzer_eval(x + y + 1 != 0); // expected-warning{{TRUE}} + clang_analyzer_eval(x + y != -1); // expected-warning{{TRUE}} + (void)(x * y); // keep the constraints alive. +} Index: clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp @@ -41,7 +41,12 @@ return assumeSymRel(State, SIE->getLHS(), op, SIE->getRHS()); } - } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) { + // Handle adjustment with non-comparison ops. + const llvm::APSInt &Zero = getBasicVals().getValue(0, SIE->getType()); + return assumeSymRel(State, SIE, (Assumption ? BO_NE : BO_EQ), Zero); + } + + if (const auto *SSE = dyn_cast<SymSymExpr>(Sym)) { BinaryOperator::Opcode Op = SSE->getOpcode(); assert(BinaryOperator::isComparisonOp(Op)); Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -1615,14 +1615,14 @@ bool handleRemainderOp(const SymT *Sym, RangeSet Constraint) { if (Sym->getOpcode() != BO_Rem) return true; - const SymbolRef LHS = Sym->getLHS(); - const llvm::APSInt &Zero = - Builder.getBasicValueFactory().getValue(0, Sym->getType()); // a % b != 0 implies that a != 0. if (!Constraint.containsZero()) { - State = RCM.assumeSymNE(State, LHS, Zero, Zero); - if (!State) - return false; + SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS()); + if (auto NonLocSymSVal = SymSVal.getAs<nonloc::SymbolVal>()) { + State = State->assume(*NonLocSymSVal, true); + if (!State) + return false; + } } return true; }
Index: clang/test/Analysis/constraint-assignor.c =================================================================== --- clang/test/Analysis/constraint-assignor.c +++ clang/test/Analysis/constraint-assignor.c @@ -3,9 +3,8 @@ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -verify -// expected-no-diagnostics - void clang_analyzer_warnIfReached(); +void clang_analyzer_eval(); void rem_constant_rhs_ne_zero(int x, int y) { if (x % 3 == 0) // x % 3 != 0 -> x != 0 @@ -67,3 +66,19 @@ if (d % 2 != 0) return; } + +void remainder_with_adjustment(int x) { + if ((x + 1) % 3 == 0) // (x + 1) % 3 != 0 -> x + 1 != 0 -> x != -1 + return; + clang_analyzer_eval(x + 1 != 0); // expected-warning{{TRUE}} + clang_analyzer_eval(x != -1); // expected-warning{{TRUE}} + (void)x; // keep the constraints alive. +} + +void remainder_with_adjustment_of_composit_lhs(int x, int y) { + if ((x + y + 1) % 3 == 0) // (x + 1) % 3 != 0 -> x + 1 != 0 -> x != -1 + return; + clang_analyzer_eval(x + y + 1 != 0); // expected-warning{{TRUE}} + clang_analyzer_eval(x + y != -1); // expected-warning{{TRUE}} + (void)(x * y); // keep the constraints alive. +} Index: clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp @@ -41,7 +41,12 @@ return assumeSymRel(State, SIE->getLHS(), op, SIE->getRHS()); } - } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) { + // Handle adjustment with non-comparison ops. + const llvm::APSInt &Zero = getBasicVals().getValue(0, SIE->getType()); + return assumeSymRel(State, SIE, (Assumption ? BO_NE : BO_EQ), Zero); + } + + if (const auto *SSE = dyn_cast<SymSymExpr>(Sym)) { BinaryOperator::Opcode Op = SSE->getOpcode(); assert(BinaryOperator::isComparisonOp(Op)); Index: clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -1615,14 +1615,14 @@ bool handleRemainderOp(const SymT *Sym, RangeSet Constraint) { if (Sym->getOpcode() != BO_Rem) return true; - const SymbolRef LHS = Sym->getLHS(); - const llvm::APSInt &Zero = - Builder.getBasicValueFactory().getValue(0, Sym->getType()); // a % b != 0 implies that a != 0. if (!Constraint.containsZero()) { - State = RCM.assumeSymNE(State, LHS, Zero, Zero); - if (!State) - return false; + SVal SymSVal = Builder.makeSymbolVal(Sym->getLHS()); + if (auto NonLocSymSVal = SymSVal.getAs<nonloc::SymbolVal>()) { + State = State->assume(*NonLocSymSVal, true); + if (!State) + return false; + } } return true; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits