aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorDenys Petrov <dpetrov@accesssoftek.com>2022-07-12 23:18:37 +0300
committerDenys Petrov <dpetrov@accesssoftek.com>2022-07-15 19:24:57 +0300
commit82f76c04774fbeb2313b84932afac478f010c8d0 (patch)
tree0a6e78f3ce6f2a91f305f70bbfbd6edb66754797 /clang/lib
parent451e5e2b28e702170aba3c6121f72fb6de55a80c (diff)
downloadllvm-82f76c04774fbeb2313b84932afac478f010c8d0.zip
llvm-82f76c04774fbeb2313b84932afac478f010c8d0.tar.gz
llvm-82f76c04774fbeb2313b84932afac478f010c8d0.tar.bz2
[analyzer][NFC] Tidy up handler-functions in SymbolicRangeInferrer
Summary: Sorted some handler-functions into more appropriate visitor functions of the SymbolicRangeInferrer. - Spread `getRangeForNegatedSub` body over several visitor functions: `VisitSymExpr`, `VisitSymIntExpr`, `VisitSymSymExpr`. - Moved `getRangeForComparisonSymbol` from `infer` to `VisitSymSymExpr`. Differential Revision: https://reviews.llvm.org/D129678
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp124
1 files changed, 71 insertions, 53 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index e788a7a..8f1e3aa 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -1213,13 +1213,21 @@ public:
}
RangeSet VisitSymExpr(SymbolRef Sym) {
- // If we got to this function, the actual type of the symbolic
+ if (Optional<RangeSet> RS = getRangeForNegatedSym(Sym))
+ return *RS;
+ // If we've reached this line, the actual type of the symbolic
// expression is not supported for advanced inference.
// In this case, we simply backoff to the default "let's simply
// infer the range from the expression's type".
return infer(Sym->getType());
}
+ RangeSet VisitUnarySymExpr(const UnarySymExpr *USE) {
+ if (Optional<RangeSet> RS = getRangeForNegatedUnarySym(USE))
+ return *RS;
+ return infer(USE->getType());
+ }
+
RangeSet VisitSymIntExpr(const SymIntExpr *Sym) {
return VisitBinaryOperator(Sym);
}
@@ -1228,14 +1236,25 @@ public:
return VisitBinaryOperator(Sym);
}
- RangeSet VisitSymSymExpr(const SymSymExpr *Sym) {
+ RangeSet VisitSymSymExpr(const SymSymExpr *SSE) {
return intersect(
RangeFactory,
+ // If Sym is a difference of symbols A - B, then maybe we have range
+ // set stored for B - A.
+ //
+ // If we have range set stored for both A - B and B - A then
+ // calculate the effective range set by intersecting the range set
+ // for A - B and the negated range set of B - A.
+ getRangeForNegatedSymSym(SSE),
+ // If Sym is a comparison expression (except <=>),
+ // find any other comparisons with the same operands.
+ // See function description.
+ getRangeForComparisonSymbol(SSE),
// If Sym is (dis)equality, we might have some information
// on that in our equality classes data structure.
- getRangeForEqualities(Sym),
+ getRangeForEqualities(SSE),
// And we should always check what we can get from the operands.
- VisitBinaryOperator(Sym));
+ VisitBinaryOperator(SSE));
}
private:
@@ -1264,25 +1283,13 @@ private:
}
RangeSet infer(SymbolRef Sym) {
- return intersect(
- RangeFactory,
- // Of course, we should take the constraint directly associated with
- // this symbol into consideration.
- getConstraint(State, Sym),
- // If Sym is a difference of symbols A - B, then maybe we have range
- // set stored for B - A.
- //
- // If we have range set stored for both A - B and B - A then
- // calculate the effective range set by intersecting the range set
- // for A - B and the negated range set of B - A.
- getRangeForNegatedSub(Sym),
- // If Sym is a comparison expression (except <=>),
- // find any other comparisons with the same operands.
- // See function description.
- getRangeForComparisonSymbol(Sym),
- // Apart from the Sym itself, we can infer quite a lot if we look
- // into subexpressions of Sym.
- Visit(Sym));
+ return intersect(RangeFactory,
+ // Of course, we should take the constraint directly
+ // associated with this symbol into consideration.
+ getConstraint(State, Sym),
+ // Apart from the Sym itself, we can infer quite a lot if
+ // we look into subexpressions of Sym.
+ Visit(Sym));
}
RangeSet infer(EquivalenceClass Class) {
@@ -1443,38 +1450,53 @@ private:
return RangeFactory.deletePoint(Domain, IntType.getZeroValue());
}
- Optional<RangeSet> getRangeForNegatedSub(SymbolRef Sym) {
+ template <typename ProduceNegatedSymFunc>
+ Optional<RangeSet> getRangeForNegatedExpr(ProduceNegatedSymFunc F,
+ QualType T) {
// Do not negate if the type cannot be meaningfully negated.
- if (!Sym->getType()->isUnsignedIntegerOrEnumerationType() &&
- !Sym->getType()->isSignedIntegerOrEnumerationType())
+ if (!T->isUnsignedIntegerOrEnumerationType() &&
+ !T->isSignedIntegerOrEnumerationType())
return llvm::None;
- const RangeSet *NegatedRange = nullptr;
- SymbolManager &SymMgr = State->getSymbolManager();
- if (const auto *USE = dyn_cast<UnarySymExpr>(Sym)) {
- if (USE->getOpcode() == UO_Minus) {
- // Just get the operand when we negate a symbol that is already negated.
- // -(-a) == a
- NegatedRange = getConstraint(State, USE->getOperand());
- }
- } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
- if (SSE->getOpcode() == BO_Sub) {
- QualType T = Sym->getType();
- SymbolRef NegatedSym =
- SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), T);
- NegatedRange = getConstraint(State, NegatedSym);
- }
- } else {
- SymbolRef NegatedSym =
- SymMgr.getUnarySymExpr(Sym, UO_Minus, Sym->getType());
- NegatedRange = getConstraint(State, NegatedSym);
- }
+ if (SymbolRef NegatedSym = F())
+ if (const RangeSet *NegatedRange = getConstraint(State, NegatedSym))
+ return RangeFactory.negate(*NegatedRange);
- if (NegatedRange)
- return RangeFactory.negate(*NegatedRange);
return llvm::None;
}
+ Optional<RangeSet> getRangeForNegatedUnarySym(const UnarySymExpr *USE) {
+ // Just get the operand when we negate a symbol that is already negated.
+ // -(-a) == a
+ return getRangeForNegatedExpr(
+ [USE]() -> SymbolRef {
+ if (USE->getOpcode() == UO_Minus)
+ return USE->getOperand();
+ return nullptr;
+ },
+ USE->getType());
+ }
+
+ Optional<RangeSet> getRangeForNegatedSymSym(const SymSymExpr *SSE) {
+ return getRangeForNegatedExpr(
+ [SSE, State = this->State]() -> SymbolRef {
+ if (SSE->getOpcode() == BO_Sub)
+ return State->getSymbolManager().getSymSymExpr(
+ SSE->getRHS(), BO_Sub, SSE->getLHS(), SSE->getType());
+ return nullptr;
+ },
+ SSE->getType());
+ }
+
+ Optional<RangeSet> getRangeForNegatedSym(SymbolRef Sym) {
+ return getRangeForNegatedExpr(
+ [Sym, State = this->State]() {
+ return State->getSymbolManager().getUnarySymExpr(Sym, UO_Minus,
+ Sym->getType());
+ },
+ Sym->getType());
+ }
+
// Returns ranges only for binary comparison operators (except <=>)
// when left and right operands are symbolic values.
// Finds any other comparisons with the same operands.
@@ -1485,11 +1507,7 @@ private:
// It covers all possible combinations (see CmpOpTable description).
// Note that `x` and `y` can also stand for subexpressions,
// not only for actual symbols.
- Optional<RangeSet> getRangeForComparisonSymbol(SymbolRef Sym) {
- const auto *SSE = dyn_cast<SymSymExpr>(Sym);
- if (!SSE)
- return llvm::None;
-
+ Optional<RangeSet> getRangeForComparisonSymbol(const SymSymExpr *SSE) {
const BinaryOperatorKind CurrentOP = SSE->getOpcode();
// We currently do not support <=> (C++20).