[clang] [analyzer][NFC] Introduce APSIntPtr, a safe wrapper of APSInt (1/4) (PR #120435)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 19 02:11:24 PST 2024
https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/120435
>From 587368ab2930dc9f62eae12edec3e47f68d38135 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Wed, 18 Dec 2024 15:53:32 +0100
Subject: [PATCH] [analyzer][NFC] Introduce APSIntPtr, a safe wrapper of APSInt
(1/4)
---
.../Core/PathSensitive/APSIntPtr.h | 62 ++++++++++++++++++
.../Core/PathSensitive/BasicValueFactory.h | 60 ++++++++---------
.../Core/PathSensitive/ProgramState.h | 1 -
.../Core/PathSensitive/SMTConstraintManager.h | 9 ++-
.../Checkers/CStringChecker.cpp | 4 +-
.../Checkers/StdLibraryFunctionsChecker.cpp | 14 ++--
.../Checkers/VLASizeChecker.cpp | 2 +-
.../StaticAnalyzer/Core/BasicValueFactory.cpp | 64 +++++++++----------
.../StaticAnalyzer/Core/SimpleSValBuilder.cpp | 20 +++---
9 files changed, 146 insertions(+), 90 deletions(-)
create mode 100644 clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h
new file mode 100644
index 00000000000000..c25b442b2a64e8
--- /dev/null
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h
@@ -0,0 +1,62 @@
+//== APSIntPtr.h - Wrapper for APSInt objects owned separately -*- C++ -*--==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
+
+#include "llvm/ADT/APSInt.h"
+
+namespace clang::ento {
+
+/// A safe wrapper around APSInt objects allocated and owned by
+/// \c BasicValueFactory. This just wraps a common llvm::APSInt.
+class APSIntPtr {
+ using APSInt = llvm::APSInt;
+
+public:
+ APSIntPtr() = delete;
+ APSIntPtr(const APSIntPtr &) = default;
+ APSIntPtr &operator=(const APSIntPtr &) & = default;
+ ~APSIntPtr() = default;
+
+ /// You should not use this API.
+ /// If do, ensure that the \p Ptr not going to dangle.
+ /// Prefer using \c BasicValueFactory::getValue() to get an APSIntPtr object.
+ static APSIntPtr unsafeConstructor(const APSInt *Ptr) {
+ return APSIntPtr(Ptr);
+ }
+
+ const APSInt *get() const { return Ptr; }
+ /*implicit*/ operator const APSInt &() const { return *get(); }
+
+ APSInt operator-() const { return -*Ptr; }
+ APSInt operator~() const { return ~*Ptr; }
+
+#define DEFINE_OPERATOR(OP) \
+ bool operator OP(APSIntPtr Other) const { return (*Ptr)OP(*Other.Ptr); }
+ DEFINE_OPERATOR(>)
+ DEFINE_OPERATOR(>=)
+ DEFINE_OPERATOR(<)
+ DEFINE_OPERATOR(<=)
+ DEFINE_OPERATOR(==)
+ DEFINE_OPERATOR(!=)
+#undef DEFINE_OPERATOR
+
+ const APSInt &operator*() const { return *Ptr; }
+ const APSInt *operator->() const { return Ptr; }
+
+private:
+ explicit APSIntPtr(const APSInt *Ptr) : Ptr(Ptr) {}
+
+ /// Owned by \c BasicValueFactory.
+ const APSInt *Ptr;
+};
+
+} // namespace clang::ento
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSIntPtr_H
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index ec503b41b381a5..ef04f9c485e88a 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -18,10 +18,11 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntPtr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -129,7 +130,7 @@ class BasicValueFactory {
// This is private because external clients should use the factory
// method that takes a QualType.
- const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
+ APSIntPtr getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
public:
BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
@@ -140,9 +141,9 @@ class BasicValueFactory {
ASTContext &getContext() const { return Ctx; }
- const llvm::APSInt& getValue(const llvm::APSInt& X);
- const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned);
- const llvm::APSInt& getValue(uint64_t X, QualType T);
+ APSIntPtr getValue(const llvm::APSInt &X);
+ APSIntPtr getValue(const llvm::APInt &X, bool isUnsigned);
+ APSIntPtr getValue(uint64_t X, QualType T);
/// Returns the type of the APSInt used to store values of the given QualType.
APSIntType getAPSIntType(QualType T) const {
@@ -165,79 +166,70 @@ class BasicValueFactory {
/// Convert - Create a new persistent APSInt with the same value as 'From'
/// but with the bitwidth and signedness of 'To'.
- const llvm::APSInt &Convert(const llvm::APSInt& To,
- const llvm::APSInt& From) {
+ APSIntPtr Convert(const llvm::APSInt &To, const llvm::APSInt &From) {
APSIntType TargetType(To);
if (TargetType == APSIntType(From))
- return From;
+ return getValue(From);
return getValue(TargetType.convert(From));
}
- const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+ APSIntPtr Convert(QualType T, const llvm::APSInt &From) {
APSIntType TargetType = getAPSIntType(T);
return Convert(TargetType, From);
}
- const llvm::APSInt &Convert(APSIntType TargetType, const llvm::APSInt &From) {
+ APSIntPtr Convert(APSIntType TargetType, const llvm::APSInt &From) {
if (TargetType == APSIntType(From))
- return From;
+ return getValue(From);
return getValue(TargetType.convert(From));
}
- const llvm::APSInt &getIntValue(uint64_t X, bool isUnsigned) {
+ APSIntPtr getIntValue(uint64_t X, bool isUnsigned) {
QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
return getValue(X, T);
}
- const llvm::APSInt &getMaxValue(const llvm::APSInt &v) {
+ APSIntPtr getMaxValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMaxValue());
}
- const llvm::APSInt &getMinValue(const llvm::APSInt &v) {
+ APSIntPtr getMinValue(const llvm::APSInt &v) {
return getValue(APSIntType(v).getMinValue());
}
- const llvm::APSInt &getMaxValue(QualType T) {
- return getMaxValue(getAPSIntType(T));
- }
+ APSIntPtr getMaxValue(QualType T) { return getMaxValue(getAPSIntType(T)); }
- const llvm::APSInt &getMinValue(QualType T) {
- return getMinValue(getAPSIntType(T));
- }
+ APSIntPtr getMinValue(QualType T) { return getMinValue(getAPSIntType(T)); }
- const llvm::APSInt &getMaxValue(APSIntType T) {
- return getValue(T.getMaxValue());
- }
+ APSIntPtr getMaxValue(APSIntType T) { return getValue(T.getMaxValue()); }
- const llvm::APSInt &getMinValue(APSIntType T) {
- return getValue(T.getMinValue());
- }
+ APSIntPtr getMinValue(APSIntType T) { return getValue(T.getMinValue()); }
- const llvm::APSInt &Add1(const llvm::APSInt &V) {
+ APSIntPtr Add1(const llvm::APSInt &V) {
llvm::APSInt X = V;
++X;
return getValue(X);
}
- const llvm::APSInt &Sub1(const llvm::APSInt &V) {
+ APSIntPtr Sub1(const llvm::APSInt &V) {
llvm::APSInt X = V;
--X;
return getValue(X);
}
- const llvm::APSInt &getZeroWithTypeSize(QualType T) {
+ APSIntPtr getZeroWithTypeSize(QualType T) {
assert(T->isScalarType());
return getValue(0, Ctx.getTypeSize(T), true);
}
- const llvm::APSInt &getTruthValue(bool b, QualType T) {
+ APSIntPtr getTruthValue(bool b, QualType T) {
return getValue(b ? 1 : 0, Ctx.getIntWidth(T),
T->isUnsignedIntegerOrEnumerationType());
}
- const llvm::APSInt &getTruthValue(bool b) {
+ APSIntPtr getTruthValue(bool b) {
return getTruthValue(b, Ctx.getLogicalOperationType());
}
@@ -273,9 +265,9 @@ class BasicValueFactory {
accumCXXBase(llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
const nonloc::PointerToMember &PTM, const clang::CastKind &kind);
- const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1,
- const llvm::APSInt& V2);
+ std::optional<APSIntPtr> evalAPSInt(BinaryOperator::Opcode Op,
+ const llvm::APSInt &V1,
+ const llvm::APSInt &V2);
const std::pair<SVal, uintptr_t>&
getPersistentSValWithData(const SVal& V, uintptr_t Data);
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 29f534eba2a265..a20516b003c7d9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -70,7 +70,6 @@ template <typename T> struct ProgramStateTrait {
/// values will never change.
class ProgramState : public llvm::FoldingSetNode {
public:
- typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
typedef llvm::ImmutableMap<void*, void*> GenericDataMap;
private:
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
index 5766af1fc78a4f..72038b92f8edfe 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -16,6 +16,7 @@
#include "clang/Basic/JsonSupport.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
#include <optional>
@@ -154,7 +155,7 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
return nullptr;
// This is the only solution, store it
- return &BVF.getValue(Value);
+ return BVF.getValue(Value).get();
}
if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
@@ -167,7 +168,7 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
const llvm::APSInt *Value;
if (!(Value = getSymVal(State, CastSym)))
return nullptr;
- return &BVF.Convert(SC->getType(), *Value);
+ return BVF.Convert(SC->getType(), *Value).get();
}
if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
@@ -195,7 +196,9 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
std::tie(ConvertedRHS, RTy) = SMTConv::fixAPSInt(Ctx, *RHS);
SMTConv::doIntTypeConversion<llvm::APSInt, &SMTConv::castAPSInt>(
Solver, Ctx, ConvertedLHS, LTy, ConvertedRHS, RTy);
- return BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+ std::optional<APSIntPtr> Res =
+ BVF.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+ return Res ? Res.value().get() : nullptr;
}
llvm_unreachable("Unsupported expression to get symbol value!");
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 21a2d8828249d1..1a14f38e34f0e1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1025,8 +1025,8 @@ SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
const llvm::APSInt &maxValInt = BVF.getMaxValue(sizeTy);
llvm::APSInt fourInt = APSIntType(maxValInt).getValue(4);
- const llvm::APSInt *maxLengthInt = BVF.evalAPSInt(BO_Div, maxValInt,
- fourInt);
+ std::optional<APSIntPtr> maxLengthInt =
+ BVF.evalAPSInt(BO_Div, maxValInt, fourInt);
NonLoc maxLength = svalBuilder.makeIntVal(*maxLengthInt);
SVal evalLength = svalBuilder.evalBinOpNN(state, BO_LE, *strLn, maxLength,
svalBuilder.getConditionType());
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 4f30b2a0e7e7da..356d63e3e8b80f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -1643,7 +1643,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
public:
GetMaxValue(BasicValueFactory &BVF) : BVF(BVF) {}
std::optional<RangeInt> operator()(QualType Ty) {
- return BVF.getMaxValue(Ty).getLimitedValue();
+ return BVF.getMaxValue(Ty)->getLimitedValue();
}
std::optional<RangeInt> operator()(std::optional<QualType> Ty) {
if (Ty) {
@@ -1687,11 +1687,11 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
const QualType SizePtrTy = getPointerTy(SizeTy);
const QualType SizePtrRestrictTy = getRestrictTy(SizePtrTy);
- const RangeInt IntMax = BVF.getMaxValue(IntTy).getLimitedValue();
+ const RangeInt IntMax = BVF.getMaxValue(IntTy)->getLimitedValue();
const RangeInt UnsignedIntMax =
- BVF.getMaxValue(UnsignedIntTy).getLimitedValue();
- const RangeInt LongMax = BVF.getMaxValue(LongTy).getLimitedValue();
- const RangeInt SizeMax = BVF.getMaxValue(SizeTy).getLimitedValue();
+ BVF.getMaxValue(UnsignedIntTy)->getLimitedValue();
+ const RangeInt LongMax = BVF.getMaxValue(LongTy)->getLimitedValue();
+ const RangeInt SizeMax = BVF.getMaxValue(SizeTy)->getLimitedValue();
// Set UCharRangeMax to min of int or uchar maximum value.
// The C standard states that the arguments of functions like isalpha must
@@ -1700,7 +1700,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
// to be true for commonly used and well tested instruction set
// architectures, but not for others.
const RangeInt UCharRangeMax =
- std::min(BVF.getMaxValue(ACtx.UnsignedCharTy).getLimitedValue(), IntMax);
+ std::min(BVF.getMaxValue(ACtx.UnsignedCharTy)->getLimitedValue(), IntMax);
// Get platform dependent values of some macros.
// Try our best to parse this from the Preprocessor, otherwise fallback to a
@@ -3704,7 +3704,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
// Functions for testing.
if (AddTestFunctions) {
- const RangeInt IntMin = BVF.getMinValue(IntTy).getLimitedValue();
+ const RangeInt IntMin = BVF.getMinValue(IntTy)->getLimitedValue();
addToFunctionSummaryMap(
"__not_null", Signature(ArgTypes{IntPtrTy}, RetType{IntTy}),
diff --git a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index 8d17ba5d690b90..ba91b3632abbfe 100644
--- a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -96,7 +96,7 @@ ProgramStateRef VLASizeChecker::checkVLA(CheckerContext &C,
SValBuilder &SVB = C.getSValBuilder();
CanQualType SizeTy = Ctx.getSizeType();
uint64_t SizeMax =
- SVB.getBasicValueFactory().getMaxValue(SizeTy).getZExtValue();
+ SVB.getBasicValueFactory().getMaxValue(SizeTy)->getZExtValue();
// Get the element size.
CharUnits EleSize = Ctx.getTypeSizeInChars(VLALast->getElementType());
diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 827c04143e6588..02f34bc30f5548 100644
--- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -87,7 +87,7 @@ BasicValueFactory::~BasicValueFactory() {
delete (PersistentSValPairsTy*) PersistentSValPairs;
}
-const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
+APSIntPtr BasicValueFactory::getValue(const llvm::APSInt &X) {
llvm::FoldingSetNodeID ID;
void *InsertPos;
@@ -101,23 +101,23 @@ const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
APSIntSet.InsertNode(P, InsertPos);
}
- return *P;
+ // We own the APSInt object. It's safe here.
+ return APSIntPtr::unsafeConstructor(&P->getValue());
}
-const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
- bool isUnsigned) {
+APSIntPtr BasicValueFactory::getValue(const llvm::APInt &X, bool isUnsigned) {
llvm::APSInt V(X, isUnsigned);
return getValue(V);
}
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
- bool isUnsigned) {
+APSIntPtr BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
+ bool isUnsigned) {
llvm::APSInt V(BitWidth, isUnsigned);
V = X;
return getValue(V);
}
-const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
+APSIntPtr BasicValueFactory::getValue(uint64_t X, QualType T) {
return getValue(getAPSIntType(T).getValue(X));
}
@@ -242,45 +242,45 @@ const PointerToMemberData *BasicValueFactory::accumCXXBase(
return getPointerToMemberData(ND, BaseSpecList);
}
-const llvm::APSInt*
-BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
- const llvm::APSInt& V1, const llvm::APSInt& V2) {
+std::optional<APSIntPtr>
+BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op, const llvm::APSInt &V1,
+ const llvm::APSInt &V2) {
switch (Op) {
default:
llvm_unreachable("Invalid Opcode.");
case BO_Mul:
- return &getValue( V1 * V2 );
+ return getValue(V1 * V2);
case BO_Div:
if (V2 == 0) // Avoid division by zero
- return nullptr;
- return &getValue( V1 / V2 );
+ return std::nullopt;
+ return getValue(V1 / V2);
case BO_Rem:
if (V2 == 0) // Avoid division by zero
- return nullptr;
- return &getValue( V1 % V2 );
+ return std::nullopt;
+ return getValue(V1 % V2);
case BO_Add:
- return &getValue( V1 + V2 );
+ return getValue(V1 + V2);
case BO_Sub:
- return &getValue( V1 - V2 );
+ return getValue(V1 - V2);
case BO_Shl: {
// FIXME: This logic should probably go higher up, where we can
// test these conditions symbolically.
if (V2.isNegative() || V2.getBitWidth() > 64)
- return nullptr;
+ return std::nullopt;
uint64_t Amt = V2.getZExtValue();
if (Amt >= V1.getBitWidth())
- return nullptr;
+ return std::nullopt;
- return &getValue( V1.operator<<( (unsigned) Amt ));
+ return getValue(V1.operator<<((unsigned)Amt));
}
case BO_Shr: {
@@ -288,44 +288,44 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
// test these conditions symbolically.
if (V2.isNegative() || V2.getBitWidth() > 64)
- return nullptr;
+ return std::nullopt;
uint64_t Amt = V2.getZExtValue();
if (Amt >= V1.getBitWidth())
- return nullptr;
+ return std::nullopt;
- return &getValue( V1.operator>>( (unsigned) Amt ));
+ return getValue(V1.operator>>((unsigned)Amt));
}
case BO_LT:
- return &getTruthValue( V1 < V2 );
+ return getTruthValue(V1 < V2);
case BO_GT:
- return &getTruthValue( V1 > V2 );
+ return getTruthValue(V1 > V2);
case BO_LE:
- return &getTruthValue( V1 <= V2 );
+ return getTruthValue(V1 <= V2);
case BO_GE:
- return &getTruthValue( V1 >= V2 );
+ return getTruthValue(V1 >= V2);
case BO_EQ:
- return &getTruthValue( V1 == V2 );
+ return getTruthValue(V1 == V2);
case BO_NE:
- return &getTruthValue( V1 != V2 );
+ return getTruthValue(V1 != V2);
// Note: LAnd, LOr, Comma are handled specially by higher-level logic.
case BO_And:
- return &getValue( V1 & V2 );
+ return getValue(V1 & V2);
case BO_Or:
- return &getValue( V1 | V2 );
+ return getValue(V1 | V2);
case BO_Xor:
- return &getValue( V1 ^ V2 );
+ return getValue(V1 ^ V2);
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index 229169f848e228..7b7fc801ec7f4a 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -193,7 +193,7 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
// If we reach this point, the expression cannot be simplified.
// Make a SymbolVal for the entire expression, after converting the RHS.
- const llvm::APSInt *ConvertedRHS = &RHS;
+ std::optional<APSIntPtr> ConvertedRHS = BasicVals.getValue(RHS);
if (BinaryOperator::isComparisonOp(op)) {
// We're looking for a type big enough to compare the symbolic value
// with the given constant.
@@ -205,13 +205,13 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
if (ValWidth < TypeWidth) {
// If the value is too small, extend it.
- ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
+ ConvertedRHS = BasicVals.Convert(SymbolType, RHS);
} else if (ValWidth == TypeWidth) {
// If the value is signed but the symbol is unsigned, do the comparison
// in unsigned space. [C99 6.3.1.8]
// (For the opposite case, the value is already unsigned.)
if (RHS.isSigned() && !SymbolType->isSignedIntegerOrEnumerationType())
- ConvertedRHS = &BasicVals.Convert(SymbolType, RHS);
+ ConvertedRHS = BasicVals.Convert(SymbolType, RHS);
}
} else if (BinaryOperator::isAdditiveOp(op) && RHS.isNegative()) {
// Change a+(-N) into a-N, and a-(-N) into a+N
@@ -219,13 +219,13 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS,
// subtraction/addition of the negated value.
APSIntType resultIntTy = BasicVals.getAPSIntType(resultTy);
if (isNegationValuePreserving(RHS, resultIntTy)) {
- ConvertedRHS = &BasicVals.getValue(-resultIntTy.convert(RHS));
+ ConvertedRHS = BasicVals.getValue(-resultIntTy.convert(RHS));
op = (op == BO_Add) ? BO_Sub : BO_Add;
} else {
- ConvertedRHS = &BasicVals.Convert(resultTy, RHS);
+ ConvertedRHS = BasicVals.Convert(resultTy, RHS);
}
} else
- ConvertedRHS = &BasicVals.Convert(resultTy, RHS);
+ ConvertedRHS = BasicVals.Convert(resultTy, RHS);
return makeNonLoc(LHS, op, *ConvertedRHS, resultTy);
}
@@ -541,8 +541,8 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
IntType.apply(RHSValue);
}
- const llvm::APSInt *Result =
- BasicVals.evalAPSInt(op, LHSValue, RHSValue);
+ std::optional<APSIntPtr> Result =
+ BasicVals.evalAPSInt(op, LHSValue, RHSValue);
if (!Result) {
if (op == BO_Shl || op == BO_Shr) {
// FIXME: At this point the constant folding claims that the result
@@ -682,7 +682,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
// as consequence x+1U-10 produces x-9U, instead
// of x+4294967287U, that would be produced without this
// additional check.
- const llvm::APSInt *newRHS;
+ std::optional<APSIntPtr> newRHS;
if (lop == op) {
newRHS = BasicVals.evalAPSInt(BO_Add, first, second);
} else if (first >= second) {
@@ -874,7 +874,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
if (std::optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
assert(BinaryOperator::isComparisonOp(op) || op == BO_Sub);
- if (const auto *ResultInt =
+ if (std::optional<APSIntPtr> ResultInt =
BasicVals.evalAPSInt(op, L.getValue(), rInt->getValue()))
return evalCast(nonloc::ConcreteInt(*ResultInt), resultTy, QualType{});
return UnknownVal();
More information about the cfe-commits
mailing list