@@ -429,6 +429,7 @@ RValue::RValue(ArrayRef<ManagedValue> values, CanType type)
429
429
return ;
430
430
}
431
431
432
+ verifyConsistentOwnership ();
432
433
}
433
434
434
435
RValue RValue::withPreExplodedElements (ArrayRef<ManagedValue> values,
@@ -450,6 +451,7 @@ RValue::RValue(SILGenFunction &SGF, SILLocation l, CanType formalType,
450
451
451
452
ExplodeTupleValue (values, SGF, l).visit (formalType, v);
452
453
assert (values.size () == getRValueSize (type));
454
+ verifyConsistentOwnership ();
453
455
}
454
456
455
457
RValue::RValue (SILGenFunction &SGF, Expr *expr, ManagedValue v)
@@ -464,6 +466,7 @@ RValue::RValue(SILGenFunction &SGF, Expr *expr, ManagedValue v)
464
466
assert (v && " creating r-value with consumed value" );
465
467
ExplodeTupleValue (values, SGF, expr).visit (type, v);
466
468
assert (values.size () == getRValueSize (type));
469
+ verifyConsistentOwnership ();
467
470
}
468
471
469
472
RValue::RValue (CanType type)
@@ -485,6 +488,7 @@ void RValue::addElement(RValue &&element) & {
485
488
element.makeUsed ();
486
489
487
490
assert (!isComplete () || values.size () == getRValueSize (type));
491
+ verifyConsistentOwnership ();
488
492
}
489
493
490
494
void RValue::addElement (SILGenFunction &SGF, ManagedValue element,
@@ -498,6 +502,7 @@ void RValue::addElement(SILGenFunction &SGF, ManagedValue element,
498
502
ExplodeTupleValue (values, SGF, l).visit (formalType, element);
499
503
500
504
assert (!isComplete () || values.size () == getRValueSize (type));
505
+ verifyConsistentOwnership ();
501
506
}
502
507
503
508
SILValue RValue::forwardAsSingleValue (SILGenFunction &SGF, SILLocation l) && {
@@ -753,3 +758,29 @@ void RValue::dump(raw_ostream &OS, unsigned indent) const {
753
758
value.dump (OS, indent + 2 );
754
759
}
755
760
}
761
+
762
+ void RValue::verifyConsistentOwnership () const {
763
+ // This is a no-op in non-assert builds.
764
+ #ifndef NDEBUG
765
+ auto result = Optional<ValueOwnershipKind>(ValueOwnershipKind::Any);
766
+ Optional<bool > sameHaveCleanups;
767
+ for (ManagedValue v : values) {
768
+ ValueOwnershipKind kind = v.getOwnershipKind ();
769
+ if (kind == ValueOwnershipKind::Trivial)
770
+ continue ;
771
+
772
+ // Merge together whether or not the RValue has cleanups.
773
+ if (!sameHaveCleanups.hasValue ()) {
774
+ sameHaveCleanups = v.hasCleanup ();
775
+ } else {
776
+ assert (*sameHaveCleanups == v.hasCleanup ());
777
+ }
778
+
779
+ // This variable is here so that if the assert below fires, the current
780
+ // reduction value is still available.
781
+ auto newResult = result.getValue ().merge (kind);
782
+ assert (newResult.hasValue ());
783
+ result = newResult;
784
+ }
785
+ #endif
786
+ }
0 commit comments