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 {
332333public:
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
389396private:
390397 SmallVectorImpl<SVal> *EscapedValuesDuringBind; // nonnull
391- unsigned BindingsLeft;
398+ std::optional< unsigned > BindingsLeft;
392399};
393400
394401typedef 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