Skip to content

Commit df756f8

Browse files
authored
Merge pull request #6083 from jckarter/rvalue-constructor-misuse
SILGen: Purge misuses of pre-exploded RValue constructor.
2 parents 68a6975 + 66a2b6a commit df756f8

File tree

9 files changed

+53
-14
lines changed

9 files changed

+53
-14
lines changed

lib/SILGen/RValue.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,24 @@ static void copyOrInitValuesInto(Initialization *init,
363363
init->finishInitialization(gen);
364364
}
365365

366+
static unsigned
367+
expectedExplosionSize(CanType type) {
368+
auto tuple = dyn_cast<TupleType>(type);
369+
if (!tuple)
370+
return 1;
371+
unsigned total = 0;
372+
for (unsigned i = 0; i < tuple->getNumElements(); ++i) {
373+
total += expectedExplosionSize(tuple.getElementType(i));
374+
}
375+
return total;
376+
}
366377

367378
RValue::RValue(ArrayRef<ManagedValue> values, CanType type)
368379
: values(values.begin(), values.end()), type(type), elementsToBeAdded(0) {
380+
381+
assert(values.size() == expectedExplosionSize(type)
382+
&& "creating rvalue with wrong number of pre-exploded elements");
383+
369384
if (values.size() == 1 && values[0].isInContext()) {
370385
values = ArrayRef<ManagedValue>();
371386
type = CanType();
@@ -375,6 +390,11 @@ RValue::RValue(ArrayRef<ManagedValue> values, CanType type)
375390

376391
}
377392

393+
RValue RValue::withPreExplodedElements(ArrayRef<ManagedValue> values,
394+
CanType type) {
395+
return RValue(values, type);
396+
}
397+
378398
RValue::RValue(SILGenFunction &gen, SILLocation l, CanType formalType,
379399
ManagedValue v)
380400
: type(formalType), elementsToBeAdded(0)

lib/SILGen/RValue.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class RValue {
5252
/// Private constructor used by copy().
5353
RValue(const RValue &copied, SILGenFunction &gen, SILLocation l);
5454

55+
/// Construct an RValue from a pre-exploded set of
56+
/// ManagedValues. Used to implement the extractElement* methods.
57+
RValue(ArrayRef<ManagedValue> values, CanType type);
58+
5559
public:
5660
/// Creates an invalid RValue object, in a "used" state.
5761
RValue() : elementsToBeAdded(Used) {}
@@ -90,7 +94,8 @@ class RValue {
9094

9195
/// Construct an RValue from a pre-exploded set of
9296
/// ManagedValues. Used to implement the extractElement* methods.
93-
RValue(ArrayRef<ManagedValue> values, CanType type);
97+
static RValue withPreExplodedElements(ArrayRef<ManagedValue> values,
98+
CanType type);
9499

95100
/// Create an RValue to which values will be subsequently added using
96101
/// addElement(), with the level of tuple expansion in the input specified

lib/SILGen/SILGenApply.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ static Callee prepareArchetypeCallee(SILGenFunction &gen, SILLocation loc,
678678
LValue::forAddress(selfLV, AbstractionPattern(formalTy),
679679
formalTy));
680680
} else {
681-
selfValue = ArgumentSource(loc, RValue(address, formalTy));
681+
selfValue = ArgumentSource(loc, RValue(gen, loc, formalTy, address));
682682
}
683683
};
684684

@@ -989,7 +989,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
989989
auto metatype = std::move(selfValue).getAsSingleValue(SGF);
990990
auto allocated = allocateObjCObject(metatype, loc);
991991
auto allocatedType = allocated.getType().getSwiftRValueType();
992-
selfValue = ArgumentSource(loc, RValue(allocated, allocatedType));
992+
selfValue = ArgumentSource(loc, RValue(SGF, loc,
993+
allocatedType, allocated));
993994
} else {
994995
// For non-Objective-C initializers, we have an allocating
995996
// initializer to call.
@@ -1768,7 +1769,7 @@ static RValue emitStringLiteral(SILGenFunction &SGF, Expr *E, StringRef Str,
17681769

17691770
CanType ty =
17701771
TupleType::get(TypeElts, SGF.getASTContext())->getCanonicalType();
1771-
return RValue(Elts, ty);
1772+
return RValue::withPreExplodedElements(Elts, ty);
17721773
}
17731774

17741775
/// Emit a raw apply operation, performing no additional lowering of
@@ -5222,7 +5223,7 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set,
52225223
SmallVector<ManagedValue, 4> Elts;
52235224
std::move(setValue).getAll(Elts);
52245225
std::move(subscripts).getAll(Elts);
5225-
setValue = RValue(Elts, accessType.getInput());
5226+
setValue = RValue::withPreExplodedElements(Elts, accessType.getInput());
52265227
} else {
52275228
setValue.rewriteType(accessType.getInput());
52285229
}
@@ -5286,7 +5287,7 @@ emitMaterializeForSetAccessor(SILLocation loc, SILDeclRef materializeForSet,
52865287
if (subscripts) {
52875288
std::move(subscripts).getAll(elts);
52885289
}
5289-
return RValue(elts, accessType.getInput());
5290+
return RValue::withPreExplodedElements(elts, accessType.getInput());
52905291
}();
52915292
emission.addCallSite(loc, ArgumentSource(loc, std::move(args)), accessType);
52925293
// (buffer, optionalCallback)

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ static ManagedValue emitBuiltinAssign(SILGenFunction &gen,
262262
/*isStrict*/ true);
263263

264264
// Build the value to be assigned, reconstructing tuples if needed.
265-
RValue src(args.slice(0, args.size() - 1), assignFormalType);
265+
auto src = RValue::withPreExplodedElements(args.slice(0, args.size() - 1),
266+
assignFormalType);
266267

267268
std::move(src).assignInto(gen, loc, addr);
268269

lib/SILGen/SILGenConvert.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ SILGenFunction::emitOptionalToOptional(SILLocation loc,
310310

311311
// Inject that into the result type if the result is address-only.
312312
if (resultTL.isAddressOnly()) {
313-
ArgumentSource resultValueRV(loc, RValue(resultValue, resultValueTy));
313+
ArgumentSource resultValueRV(loc, RValue(*this, loc,
314+
resultValueTy, resultValue));
314315
emitInjectOptionalValueInto(loc, std::move(resultValueRV),
315316
result, resultTL);
316317
} else {

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
409409
Scalar = emitConversionToSemanticRValue(loc, Scalar,
410410
getTypeLowering(refType));
411411
// emitConversionToSemanticRValue always produces a +1 strong result.
412-
return RValue(emitManagedRValueWithCleanup(Scalar), refType);
412+
return RValue(*this, loc,
413+
refType, emitManagedRValueWithCleanup(Scalar));
413414
}
414415

415416
auto Result = ManagedValue::forUnmanaged(Scalar);
@@ -3270,7 +3271,9 @@ class AutoreleasingWritebackComponent : public LogicalPathComponent {
32703271
CanUnmanagedStorageType::get(refType));
32713272
SILValue unowned = gen.B.createRefToUnmanaged(loc, owned, unownedType);
32723273

3273-
return RValue(ManagedValue::forUnmanaged(unowned), refType);
3274+
// A reference type should never be exploded.
3275+
return RValue::withPreExplodedElements(ManagedValue::forUnmanaged(unowned),
3276+
refType);
32743277
}
32753278

32763279
/// Compare 'this' lvalue and the 'rhs' lvalue (which is guaranteed to have

lib/SILGen/SILGenLValue.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,8 @@ namespace {
880880
CanType type = subscripts.getType();
881881
SmallVector<ManagedValue, 4> values;
882882
std::move(subscripts).getAll(values);
883-
subscripts = RValue(values, type);
884-
borrowedSubscripts = RValue(values, type);
883+
subscripts = RValue::withPreExplodedElements(values, type);
884+
borrowedSubscripts = RValue::withPreExplodedElements(values, type);
885885
optSubscripts = &borrowedSubscripts;
886886
}
887887
return new GetterSetterComponent(decl, IsSuper, IsDirectAccessorUse,

lib/SILGen/SILGenPoly.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ RValue Transform::transform(RValue &&input,
253253
auto result = transform(std::move(input).getScalarValue(),
254254
inputOrigType, inputSubstType,
255255
outputOrigType, outputSubstType, ctxt);
256-
return RValue(result, outputSubstType);
256+
return RValue(SGF, Loc, outputSubstType, result);
257257
}
258258

259259
// Okay, we have a tuple. The output type will also be a tuple unless
@@ -317,7 +317,7 @@ RValue Transform::transform(RValue &&input,
317317
return RValue();
318318
}
319319

320-
return RValue(outputExpansion, outputTupleType);
320+
return RValue::withPreExplodedElements(outputExpansion, outputTupleType);
321321
}
322322

323323
// Single @objc protocol value metatypes can be converted to the ObjC
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -emit-silgen -verify %s
2+
3+
protocol P {}
4+
5+
func for_loop_tuple_destructure_reabstraction(_ x: [(P, P.Protocol)]) {
6+
for (a, b) in x { _ = (a, b) }
7+
}
8+

0 commit comments

Comments
 (0)