Skip to content

Commit e944429

Browse files
Use optional unsigned for BindLimit
1 parent 87f27a6 commit e944429

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

clang/lib/StaticAnalyzer/Core/RegionStore.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/ADT/STLExtras.h"
3232
#include "llvm/Support/TimeProfiler.h"
3333
#include "llvm/Support/raw_ostream.h"
34+
#include <limits>
3435
#include <optional>
3536
#include <utility>
3637

@@ -332,17 +333,16 @@ class BoundedRegionBindingsRef : public RegionBindingsRef {
332333
public:
333334
BoundedRegionBindingsRef(RegionBindingsRef Base,
334335
SmallVectorImpl<SVal> &EscapedValuesDuringBind,
335-
unsigned BindingsLeft)
336+
std::optional<unsigned> BindingsLeft)
336337
: RegionBindingsRef(Base),
337338
EscapedValuesDuringBind(&EscapedValuesDuringBind),
338339
BindingsLeft(BindingsLeft) {}
339340

340-
unsigned bindingsLeft() const { return BindingsLeft; }
341-
342-
bool hasExhaustedBindingLimit() const { return BindingsLeft == 0; }
341+
bool hasExhaustedBindingLimit() const {
342+
return BindingsLeft.has_value() && BindingsLeft.value() == 0;
343+
}
343344

344345
BoundedRegionBindingsRef withValuesEscaped(SVal V) const {
345-
assert(EscapedValuesDuringBind);
346346
EscapedValuesDuringBind->push_back(V);
347347
return *this;
348348
}
@@ -370,15 +370,22 @@ class BoundedRegionBindingsRef : public RegionBindingsRef {
370370
}
371371

372372
BoundedRegionBindingsRef addBinding(BindingKey K, SVal V) const {
373-
// If we are about to exhaust the binding limit, highjack this bind call for
374-
// the default binding.
375-
if (BindingsLeft == 1) {
376-
withValuesEscaped(V);
377-
K = BindingKey::Make(K.getRegion(), BindingKey::Default);
378-
V = UnknownVal();
373+
std::optional<unsigned> NewBindingsLeft = BindingsLeft;
374+
if (NewBindingsLeft.has_value()) {
375+
assert(NewBindingsLeft.value() != 0);
376+
NewBindingsLeft.value() -= 1;
377+
378+
// If we just exhausted the binding limit, highjack
379+
// this bind call for the default binding.
380+
if (NewBindingsLeft.value() == 0) {
381+
withValuesEscaped(V);
382+
K = BindingKey::Make(K.getRegion(), BindingKey::Default);
383+
V = UnknownVal();
384+
}
379385
}
386+
380387
return BoundedRegionBindingsRef{RegionBindingsRef::addBinding(K, V),
381-
*EscapedValuesDuringBind, BindingsLeft - 1};
388+
*EscapedValuesDuringBind, NewBindingsLeft};
382389
}
383390

384391
BoundedRegionBindingsRef addBinding(const MemRegion *R, BindingKey::Kind k,
@@ -388,7 +395,7 @@ class BoundedRegionBindingsRef : public RegionBindingsRef {
388395

389396
private:
390397
SmallVectorImpl<SVal> *EscapedValuesDuringBind; // nonnull
391-
unsigned BindingsLeft;
398+
std::optional<unsigned> BindingsLeft;
392399
};
393400

394401
typedef const RegionBindingsRef& RegionBindingsConstRef;
@@ -498,8 +505,8 @@ class RegionStoreManager : public StoreManager {
498505
/// The number of bindings a single bind operation can scatter into.
499506
/// For example, binding the initializer-list of an array would recurse and
500507
/// bind all the individual array elements, potentially causing scalability
501-
/// issues.
502-
const unsigned RegionStoreMaxBindingFanOut;
508+
/// issues. Nullopt if the limit is disabled.
509+
const std::optional<unsigned> RegionStoreMaxBindingFanOutPlusOne;
503510

504511
/// A helper used to populate the work list with the given set of
505512
/// regions.
@@ -517,11 +524,13 @@ class RegionStoreManager : public StoreManager {
517524
CBFactory(mgr.getAllocator()),
518525
SmallStructLimit(getOptions().RegionStoreSmallStructLimit),
519526
SmallArrayLimit(getOptions().RegionStoreSmallArrayLimit),
520-
RegionStoreMaxBindingFanOut(
521-
getOptions().RegionStoreMaxBindingFanOut == 0
522-
? -1U
523-
: getOptions().RegionStoreMaxBindingFanOut +
524-
/*for the default binding*/ 1) {}
527+
RegionStoreMaxBindingFanOutPlusOne([&]() -> std::optional<unsigned> {
528+
unsigned FanOut = getOptions().RegionStoreMaxBindingFanOut;
529+
assert(FanOut != std::numeric_limits<unsigned>::max());
530+
if (FanOut == 0)
531+
return std::nullopt;
532+
return FanOut + 1 /*for the default binding*/;
533+
}()) {}
525534

526535
/// setImplicitDefaultValue - Set the default binding for the provided
527536
/// MemRegion to the value implicitly defined for compound literals when
@@ -804,7 +813,7 @@ class RegionStoreManager : public StoreManager {
804813
SmallVectorImpl<SVal> &EscapedValuesDuringBind) const {
805814
return BoundedRegionBindingsRef(
806815
getRegionBindings(store), EscapedValuesDuringBind,
807-
/*BindingsLeft=*/RegionStoreMaxBindingFanOut);
816+
/*BindingsLeft=*/RegionStoreMaxBindingFanOutPlusOne);
808817
}
809818

810819
void printJson(raw_ostream &Out, Store S, const char *NL = "\n",

0 commit comments

Comments
 (0)