Skip to content

Commit d018ecc

Browse files
authored
Merge pull request #11195 from gottesmm/rvalues_should_have_consistent_ownership
[silgen] Assert that rvalues always have consistent ownership and cle…
2 parents 481715a + 7bad324 commit d018ecc

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/SILGen/RValue.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ RValue::RValue(ArrayRef<ManagedValue> values, CanType type)
429429
return;
430430
}
431431

432+
verifyConsistentOwnership();
432433
}
433434

434435
RValue RValue::withPreExplodedElements(ArrayRef<ManagedValue> values,
@@ -450,6 +451,7 @@ RValue::RValue(SILGenFunction &SGF, SILLocation l, CanType formalType,
450451

451452
ExplodeTupleValue(values, SGF, l).visit(formalType, v);
452453
assert(values.size() == getRValueSize(type));
454+
verifyConsistentOwnership();
453455
}
454456

455457
RValue::RValue(SILGenFunction &SGF, Expr *expr, ManagedValue v)
@@ -464,6 +466,7 @@ RValue::RValue(SILGenFunction &SGF, Expr *expr, ManagedValue v)
464466
assert(v && "creating r-value with consumed value");
465467
ExplodeTupleValue(values, SGF, expr).visit(type, v);
466468
assert(values.size() == getRValueSize(type));
469+
verifyConsistentOwnership();
467470
}
468471

469472
RValue::RValue(CanType type)
@@ -485,6 +488,7 @@ void RValue::addElement(RValue &&element) & {
485488
element.makeUsed();
486489

487490
assert(!isComplete() || values.size() == getRValueSize(type));
491+
verifyConsistentOwnership();
488492
}
489493

490494
void RValue::addElement(SILGenFunction &SGF, ManagedValue element,
@@ -498,6 +502,7 @@ void RValue::addElement(SILGenFunction &SGF, ManagedValue element,
498502
ExplodeTupleValue(values, SGF, l).visit(formalType, element);
499503

500504
assert(!isComplete() || values.size() == getRValueSize(type));
505+
verifyConsistentOwnership();
501506
}
502507

503508
SILValue RValue::forwardAsSingleValue(SILGenFunction &SGF, SILLocation l) && {
@@ -753,3 +758,29 @@ void RValue::dump(raw_ostream &OS, unsigned indent) const {
753758
value.dump(OS, indent + 2);
754759
}
755760
}
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+
}

lib/SILGen/RValue.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ class RValue {
6767
RValue(std::vector<ManagedValue> &&values, CanType type,
6868
unsigned elementsToBeAdded)
6969
: values(std::move(values)), type(type),
70-
elementsToBeAdded(elementsToBeAdded) {}
70+
elementsToBeAdded(elementsToBeAdded) {
71+
verifyConsistentOwnership();
72+
}
7173

7274
/// Construct an RValue from a pre-exploded set of ManagedValues.
7375
///
@@ -278,6 +280,13 @@ class RValue {
278280

279281
void dump() const;
280282
void dump(raw_ostream &OS, unsigned indent = 0) const;
283+
284+
private:
285+
/// Assert that all non-trivial ManagedValues in this RValue either all have a
286+
/// cleanup or all do not have a cleanup.
287+
///
288+
/// *NOTE* This is a no-op in non-assert builds.
289+
void verifyConsistentOwnership() const;
281290
};
282291

283292
} // end namespace Lowering

0 commit comments

Comments
 (0)