@@ -545,7 +545,10 @@ enum InvalidCapacity : size_t {
545545 kAboveMaxValidCapacity = ~size_t {} - 100 ,
546546 kReentrance ,
547547 kDestroyed ,
548+
549+ // These two must be last because we use `>= kMovedFrom` to mean moved-from.
548550 kMovedFrom ,
551+ kSelfMovedFrom ,
549552};
550553
551554// Returns a pointer to a control byte group that can be used by empty tables.
@@ -2911,7 +2914,7 @@ class raw_hash_set {
29112914
29122915 ABSL_ATTRIBUTE_REINITIALIZES void clear () {
29132916 if (SwisstableGenerationsEnabled () &&
2914- capacity () = = InvalidCapacity::kMovedFrom ) {
2917+ capacity () > = InvalidCapacity::kMovedFrom ) {
29152918 common ().set_capacity (DefaultCapacity ());
29162919 }
29172920 AssertNotDebugCapacity ();
@@ -3596,7 +3599,7 @@ class raw_hash_set {
35963599
35973600 inline void destructor_impl () {
35983601 if (SwisstableGenerationsEnabled () &&
3599- capacity () = = InvalidCapacity::kMovedFrom ) {
3602+ capacity () > = InvalidCapacity::kMovedFrom ) {
36003603 return ;
36013604 }
36023605 if (capacity () == 0 ) return ;
@@ -3778,7 +3781,8 @@ class raw_hash_set {
37783781 // than using NDEBUG) to avoid issues in which NDEBUG is enabled in some
37793782 // translation units but not in others.
37803783 if (SwisstableGenerationsEnabled ()) {
3781- that.common ().set_capacity (InvalidCapacity::kMovedFrom );
3784+ that.common ().set_capacity (this == &that ? InvalidCapacity::kSelfMovedFrom
3785+ : InvalidCapacity::kMovedFrom );
37823786 }
37833787 if (!SwisstableGenerationsEnabled () || capacity () == DefaultCapacity () ||
37843788 capacity () > kAboveMaxValidCapacity ) {
@@ -3908,7 +3912,12 @@ class raw_hash_set {
39083912 assert (capacity () != InvalidCapacity::kDestroyed &&
39093913 " Use of destroyed hash table." );
39103914 if (SwisstableGenerationsEnabled () &&
3911- ABSL_PREDICT_FALSE (capacity () == InvalidCapacity::kMovedFrom )) {
3915+ ABSL_PREDICT_FALSE (capacity () >= InvalidCapacity::kMovedFrom )) {
3916+ if (capacity () == InvalidCapacity::kSelfMovedFrom ) {
3917+ // If this log triggers, then a hash table was move-assigned to itself
3918+ // and then used again later without being reinitialized.
3919+ ABSL_RAW_LOG (FATAL, " Use of self-move-assigned hash table." );
3920+ }
39123921 ABSL_RAW_LOG (FATAL, " Use of moved-from hash table." );
39133922 }
39143923 }
0 commit comments