================ @@ -379,6 +386,111 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, C.addTransition(State, this); } +void DereferenceChecker::checkPreStmt(const BinaryOperator *Op, + CheckerContext &C) const { + if (!Op->isAdditiveOp()) + return; + const Expr *E1 = Op->getLHS(); + const Expr *E2 = Op->getRHS(); + QualType T1 = E1->getType().getCanonicalType(); + QualType T2 = E2->getType().getCanonicalType(); + if (T1->isIntegerType() && T2->isIntegerType()) + return; + if (!T1->isPointerType() && !T1->isIntegerType() && !T2->isPointerType() && + !T2->isIntegerType()) + return; + + ProgramStateRef State = C.getState(); + SVal V1 = State->getSVal(E1, C.getLocationContext()); + SVal V2 = State->getSVal(E2, C.getLocationContext()); + if (V1.isUndef() || V2.isUndef()) + return; + + ConditionTruthVal V1IsNull = State->isNull(V1); + ConditionTruthVal V2IsNull = State->isNull(V2); + bool IsConstrained = true; + + // Check cases 'NULL + x' and 'NULL - x' + if (T1->isPointerType() && T2->isIntegerType()) { + if (!V1IsNull.isConstrainedTrue() || V2IsNull.isConstrainedTrue()) + return; + IsConstrained = V2IsNull.isConstrainedFalse(); + } + + // Check case 'x + NULL' + if (T1->isIntegerType() && T2->isPointerType()) { + if (V1IsNull.isConstrainedTrue() || !V2IsNull.isConstrainedTrue()) + return; + IsConstrained = V1IsNull.isConstrainedFalse(); + } + + // Check case 'NULL - p' or 'p - NULL' + if (T1->isPointerType() && T2->isPointerType()) { + if (!V1IsNull.isConstrainedTrue() && !V2IsNull.isConstrainedTrue()) + return; + if (V1IsNull.isConstrainedTrue() && V2IsNull.isConstrainedTrue()) + return; + IsConstrained = + V1IsNull.isConstrainedFalse() || V2IsNull.isConstrainedFalse(); + } + + SmallString<100> Buf; + llvm::raw_svector_ostream Out(Buf); ---------------- NagyDonat wrote:
This type choice is perhaps motivated by a remark in the [LLVM Programmer's Manual](https://www.llvm.org/docs/ProgrammersManual.html#std-string) which says that > The major disadvantage of `std::string` is that almost every operation that > makes them larger can allocate memory, which is slow. As such, it is better > to use `SmallVector` or `Twine` as a scratch buffer, but then use > `std::string` to persist the result. However the performance of this code is probably irrelevant (it isn't called too often), so I feel that `SmallString` and `std::string` are equally acceptable types for this variable. https://github.com/llvm/llvm-project/pull/157129 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits