@@ -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" );
@@ -1431,10 +1496,19 @@ struct PartitionOpEvaluatorBaseImpl : PartitionOpEvaluator<Subclass> {
1431
1496
const PartitionOp &op, Element elt,
1432
1497
SILDynamicMergedIsolationInfo regionInfo) const {}
1433
1498
1499
+ // / Please see documentation on the CRTP version of this call for information
1500
+ // / about this entrypoint.
1434
1501
void handleTransferNonTransferrable (
1435
1502
const PartitionOp &op, Element elt, Element otherElement,
1436
1503
SILDynamicMergedIsolationInfo isolationRegionInfo) const {}
1437
1504
1505
+ // / Please see documentation on the CRTP version of this call for information
1506
+ // / about this entrypoint.
1507
+ void handleAssignTransferNonTransferrableIntoSendingResult (
1508
+ const PartitionOp &partitionOp, Element destElement,
1509
+ SILFunctionArgument *destValue, Element srcElement, SILValue srcValue,
1510
+ SILDynamicMergedIsolationInfo srcIsolationRegionInfo) const {}
1511
+
1438
1512
// / Used to signify an "unknown code pattern" has occured while performing
1439
1513
// / dataflow.
1440
1514
// /
0 commit comments