aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/BasicValueFactory.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp62
1 files changed, 34 insertions, 28 deletions
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index ec7a7e9e4b1c..db4c1432ccc3 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -1,4 +1,4 @@
-//=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- C++ -*-//
+//===- BasicValueFactory.cpp - Basic values for Path Sens analysis --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,9 +13,18 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/ASTContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/STLExtras.h"
+#include <cassert>
+#include <cstdint>
+#include <utility>
using namespace clang;
using namespace ento;
@@ -40,10 +49,11 @@ void PointerToMemberData::Profile(
ID.AddPointer(L.getInternalPointer());
}
-typedef std::pair<SVal, uintptr_t> SValData;
-typedef std::pair<SVal, SVal> SValPair;
+using SValData = std::pair<SVal, uintptr_t>;
+using SValPair = std::pair<SVal, SVal>;
namespace llvm {
+
template<> struct FoldingSetTrait<SValData> {
static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
X.first.Profile(ID);
@@ -57,20 +67,21 @@ template<> struct FoldingSetTrait<SValPair> {
X.second.Profile(ID);
}
};
-}
-typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
- PersistentSValsTy;
+} // namespace llvm
-typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
- PersistentSValPairsTy;
+using PersistentSValsTy =
+ llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData>>;
+
+using PersistentSValPairsTy =
+ llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair>>;
BasicValueFactory::~BasicValueFactory() {
// Note that the dstor for the contents of APSIntSet will never be called,
// so we iterate over the set and invoke the dstor for each APSInt. This
// frees an aux. memory allocated to represent very large constants.
- for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
- I->getValue().~APSInt();
+ for (const auto &I : APSIntSet)
+ I.getValue().~APSInt();
delete (PersistentSValsTy*) PersistentSVals;
delete (PersistentSValPairsTy*) PersistentSValPairs;
@@ -79,7 +90,8 @@ BasicValueFactory::~BasicValueFactory() {
const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
llvm::FoldingSetNodeID ID;
void *InsertPos;
- typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
+
+ using FoldNodeTy = llvm::FoldingSetNodeWrapper<llvm::APSInt>;
X.Profile(ID);
FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
@@ -107,14 +119,12 @@ const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
}
const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
-
return getValue(getAPSIntType(T).getValue(X));
}
const CompoundValData*
BasicValueFactory::getCompoundValData(QualType T,
llvm::ImmutableList<SVal> Vals) {
-
llvm::FoldingSetNodeID ID;
CompoundValData::Profile(ID, T, Vals);
void *InsertPos;
@@ -150,7 +160,7 @@ BasicValueFactory::getLazyCompoundValData(const StoreRef &store,
}
const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
- const DeclaratorDecl *DD, llvm::ImmutableList<const CXXBaseSpecifier*> L) {
+ const DeclaratorDecl *DD, llvm::ImmutableList<const CXXBaseSpecifier *> L) {
llvm::FoldingSetNodeID ID;
PointerToMemberData::Profile(ID, DD, L);
void *InsertPos;
@@ -167,7 +177,7 @@ const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
return D;
}
-const clang::ento::PointerToMemberData *BasicValueFactory::accumCXXBase(
+const PointerToMemberData *BasicValueFactory::accumCXXBase(
llvm::iterator_range<CastExpr::path_const_iterator> PathRange,
const nonloc::PointerToMember &PTM) {
nonloc::PointerToMember::PTMDataType PTMDT = PTM.getPTMData();
@@ -195,10 +205,9 @@ const clang::ento::PointerToMemberData *BasicValueFactory::accumCXXBase(
const llvm::APSInt*
BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {
-
switch (Op) {
default:
- assert (false && "Invalid Opcode.");
+ assert(false && "Invalid Opcode.");
case BO_Mul:
return &getValue( V1 * V2 );
@@ -220,11 +229,9 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
return &getValue( V1 - V2 );
case BO_Shl: {
-
// FIXME: This logic should probably go higher up, where we can
// test these conditions symbolically.
- // FIXME: Expand these checks to include all undefined behavior.
if (V1.isSigned() && V1.isNegative())
return nullptr;
@@ -236,16 +243,16 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
if (Amt >= V1.getBitWidth())
return nullptr;
+ if (V1.isSigned() && Amt > V1.countLeadingZeros())
+ return nullptr;
+
return &getValue( V1.operator<<( (unsigned) Amt ));
}
case BO_Shr: {
-
// FIXME: This logic should probably go higher up, where we can
// test these conditions symbolically.
- // FIXME: Expand these checks to include all undefined behavior.
-
if (V2.isSigned() && V2.isNegative())
return nullptr;
@@ -288,10 +295,8 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
}
}
-
const std::pair<SVal, uintptr_t>&
BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
-
// Lazily create the folding set.
if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
@@ -302,7 +307,8 @@ BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
- typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
+ using FoldNodeTy = llvm::FoldingSetNodeWrapper<SValData>;
+
FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {
@@ -316,7 +322,6 @@ BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
const std::pair<SVal, SVal>&
BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
-
// Lazily create the folding set.
if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
@@ -327,7 +332,8 @@ BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
- typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
+ using FoldNodeTy = llvm::FoldingSetNodeWrapper<SValPair>;
+
FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {