@@ -996,6 +996,16 @@ struct PartitionOpEvaluator {
996
996
isolationRegionInfo);
997
997
}
998
998
999
+ // / Just call our CRTP subclass.
1000
+ void handleAssignTransferNonTransferrableIntoSendingResult (
1001
+ const PartitionOp &op, Element destElement,
1002
+ SILFunctionArgument *destValue, Element srcElement, SILValue srcValue,
1003
+ SILDynamicMergedIsolationInfo srcIsolationRegionInfo) const {
1004
+ return asImpl ().handleAssignTransferNonTransferrableIntoSendingResult (
1005
+ op, destElement, destValue, srcElement, srcValue,
1006
+ srcIsolationRegionInfo);
1007
+ }
1008
+
999
1009
// / Call our CRTP subclass.
1000
1010
void handleInOutSendingNotInitializedAtExitError (
1001
1011
const PartitionOp &op, Element elt, Operand *transferringOp) const {
@@ -1112,13 +1122,41 @@ struct PartitionOpEvaluator {
1112
1122
p.pushHistorySequenceBoundary (loc);
1113
1123
1114
1124
switch (op.getKind ()) {
1115
- case PartitionOpKind::Assign:
1125
+ case PartitionOpKind::Assign: {
1116
1126
assert (op.getOpArgs ().size () == 2 &&
1117
1127
" Assign PartitionOp should be passed 2 arguments" );
1118
1128
assert (p.isTrackingElement (op.getOpArgs ()[1 ]) &&
1119
1129
" Assign PartitionOp's source argument should be already tracked" );
1130
+
1131
+ // See if we are assigning an a non-disconnected value into a 'out
1132
+ // sending' parameter. In such a case, we emit a diagnostic.
1133
+ if (op.getSourceInst ()
1134
+ ->getFunction ()
1135
+ ->getLoweredFunctionType ()
1136
+ ->hasSendingResult ()) {
1137
+ if (auto instance = getRepresentativeValue (op.getOpArgs ()[0 ])) {
1138
+ if (auto value = instance.maybeGetValue ()) {
1139
+ if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1140
+ if (fArg ->getArgumentConvention ().isIndirectOutParameter ()) {
1141
+ Region srcRegion = p.getRegion (op.getOpArgs ()[1 ]);
1142
+ auto dynamicRegionIsolation = getIsolationRegionInfo (srcRegion);
1143
+ // We can unconditionally getValue here since we can never
1144
+ // assign an actor introducing inst.
1145
+ auto rep = getRepresentativeValue (op.getOpArgs ()[1 ]).getValue ();
1146
+ if (!dynamicRegionIsolation.isDisconnected ()) {
1147
+ handleAssignTransferNonTransferrableIntoSendingResult (
1148
+ op, op.getOpArgs ()[0 ], fArg , op.getOpArgs ()[1 ], rep,
1149
+ dynamicRegionIsolation);
1150
+ }
1151
+ }
1152
+ }
1153
+ }
1154
+ }
1155
+ }
1156
+
1120
1157
p.assignElement (op.getOpArgs ()[0 ], op.getOpArgs ()[1 ]);
1121
1158
return ;
1159
+ }
1122
1160
case PartitionOpKind::AssignFresh:
1123
1161
assert (op.getOpArgs ().size () == 1 &&
1124
1162
" AssignFresh PartitionOp should be passed 1 argument" );
@@ -1199,15 +1237,42 @@ struct PartitionOpEvaluator {
1199
1237
p.undoTransfer (op.getOpArgs ()[0 ]);
1200
1238
return ;
1201
1239
}
1202
- case PartitionOpKind::Merge:
1240
+ case PartitionOpKind::Merge: {
1203
1241
assert (op.getOpArgs ().size () == 2 &&
1204
1242
" Merge PartitionOp should be passed 2 arguments" );
1205
1243
assert (p.isTrackingElement (op.getOpArgs ()[0 ]) &&
1206
1244
p.isTrackingElement (op.getOpArgs ()[1 ]) &&
1207
1245
" Merge PartitionOp's arguments should already be tracked" );
1208
1246
1247
+ // See if we are assigning an a non-disconnected value into a 'out
1248
+ // sending' parameter. In such a case, we emit a diagnostic.
1249
+ if (op.getSourceInst ()
1250
+ ->getFunction ()
1251
+ ->getLoweredFunctionType ()
1252
+ ->hasSendingResult ()) {
1253
+ if (auto instance = getRepresentativeValue (op.getOpArgs ()[0 ])) {
1254
+ if (auto value = instance.maybeGetValue ()) {
1255
+ if (auto *fArg = dyn_cast<SILFunctionArgument>(value)) {
1256
+ if (fArg ->getArgumentConvention ().isIndirectOutParameter ()) {
1257
+ Region srcRegion = p.getRegion (op.getOpArgs ()[1 ]);
1258
+ auto dynamicRegionIsolation = getIsolationRegionInfo (srcRegion);
1259
+ // We can unconditionally getValue here since we can never
1260
+ // assign an actor introducing inst.
1261
+ auto rep = getRepresentativeValue (op.getOpArgs ()[1 ]).getValue ();
1262
+ if (!dynamicRegionIsolation.isDisconnected ()) {
1263
+ handleAssignTransferNonTransferrableIntoSendingResult (
1264
+ op, op.getOpArgs ()[0 ], fArg , op.getOpArgs ()[1 ], rep,
1265
+ dynamicRegionIsolation);
1266
+ }
1267
+ }
1268
+ }
1269
+ }
1270
+ }
1271
+ }
1272
+
1209
1273
p.merge (op.getOpArgs ()[0 ], op.getOpArgs ()[1 ]);
1210
1274
return ;
1275
+ }
1211
1276
case PartitionOpKind::Require:
1212
1277
assert (op.getOpArgs ().size () == 1 &&
1213
1278
" Require PartitionOp should be passed 1 argument" );
@@ -1424,10 +1489,19 @@ struct PartitionOpEvaluatorBaseImpl : PartitionOpEvaluator<Subclass> {
1424
1489
const PartitionOp &op, Element elt,
1425
1490
SILDynamicMergedIsolationInfo regionInfo) const {}
1426
1491
1492
+ // / Please see documentation on the CRTP version of this call for information
1493
+ // / about this entrypoint.
1427
1494
void handleTransferNonTransferrable (
1428
1495
const PartitionOp &op, Element elt, Element otherElement,
1429
1496
SILDynamicMergedIsolationInfo isolationRegionInfo) const {}
1430
1497
1498
+ // / Please see documentation on the CRTP version of this call for information
1499
+ // / about this entrypoint.
1500
+ void handleAssignTransferNonTransferrableIntoSendingResult (
1501
+ const PartitionOp &partitionOp, Element destElement,
1502
+ SILFunctionArgument *destValue, Element srcElement, SILValue srcValue,
1503
+ SILDynamicMergedIsolationInfo srcIsolationRegionInfo) const {}
1504
+
1431
1505
// / Used to signify an "unknown code pattern" has occured while performing
1432
1506
// / dataflow.
1433
1507
// /
0 commit comments