@@ -772,10 +772,20 @@ lookupVarDeclForCodingKeysCase(DeclContext *conformanceDC,
772
772
llvm_unreachable (" Should have found at least 1 var decl" );
773
773
}
774
774
775
- static TryExpr *createEncodeCall (ASTContext &C, Type codingKeysType,
776
- EnumElementDecl *codingKey,
777
- Expr *containerExpr, Expr *varExpr,
778
- bool useIfPresentVariant) {
775
+ // / If strict memory safety checking is enabled, wrap the expression in an
776
+ // / implicit "unsafe".
777
+ static Expr *wrapInUnsafeIfNeeded (ASTContext &ctx, Expr *expr) {
778
+ if (ctx.LangOpts .hasFeature (Feature::StrictMemorySafety,
779
+ /* allowMigration=*/ true ))
780
+ return UnsafeExpr::createImplicit (ctx, expr->getStartLoc (), expr);
781
+
782
+ return expr;
783
+ }
784
+
785
+ static Expr *createEncodeCall (ASTContext &C, Type codingKeysType,
786
+ EnumElementDecl *codingKey,
787
+ Expr *containerExpr, Expr *varExpr,
788
+ bool useIfPresentVariant) {
779
789
// CodingKeys.x
780
790
auto *metaTyRef = TypeExpr::createImplicit (codingKeysType, C);
781
791
auto *keyExpr = new (C) MemberRefExpr (metaTyRef, SourceLoc (), codingKey,
@@ -794,7 +804,7 @@ static TryExpr *createEncodeCall(ASTContext &C, Type codingKeysType,
794
804
// try container.encode(x, forKey: CodingKeys.x)
795
805
auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
796
806
/* Implicit=*/ true );
797
- return tryExpr;
807
+ return wrapInUnsafeIfNeeded (C, tryExpr) ;
798
808
}
799
809
800
810
// / Synthesizes the body for `func encode(to encoder: Encoder) throws`.
@@ -929,7 +939,7 @@ deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl, void *) {
929
939
// try super.encode(to: container.superEncoder())
930
940
auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
931
941
/* Implicit=*/ true );
932
- statements.push_back (tryExpr);
942
+ statements.push_back (wrapInUnsafeIfNeeded (C, tryExpr) );
933
943
}
934
944
935
945
auto *body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc (),
@@ -1112,8 +1122,10 @@ deriveBodyEncodable_enum_encode(AbstractFunctionDecl *encodeDecl, void *) {
1112
1122
1113
1123
// generate: switch self { }
1114
1124
auto enumRef =
1115
- new (C) DeclRefExpr (ConcreteDeclRef (selfRef), DeclNameLoc (),
1116
- /* implicit*/ true , AccessSemantics::Ordinary);
1125
+ wrapInUnsafeIfNeeded (
1126
+ C,
1127
+ new (C) DeclRefExpr (ConcreteDeclRef (selfRef), DeclNameLoc (),
1128
+ /* implicit*/ true , AccessSemantics::Ordinary));
1117
1129
auto switchStmt = createEnumSwitch (
1118
1130
C, funcDC, enumRef, enumDecl, codingKeysEnum,
1119
1131
/* createSubpattern*/ true ,
@@ -1276,11 +1288,11 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
1276
1288
return encodeDecl;
1277
1289
}
1278
1290
1279
- static TryExpr *createDecodeCall (ASTContext &C, Type resultType,
1280
- Type codingKeysType,
1281
- EnumElementDecl *codingKey,
1282
- Expr *containerExpr,
1283
- bool useIfPresentVariant) {
1291
+ static Expr *createDecodeCall (ASTContext &C, Type resultType,
1292
+ Type codingKeysType,
1293
+ EnumElementDecl *codingKey,
1294
+ Expr *containerExpr,
1295
+ bool useIfPresentVariant) {
1284
1296
auto methodName = useIfPresentVariant ? C.Id_decodeIfPresent : C.Id_decode ;
1285
1297
1286
1298
// Type.self
@@ -1470,7 +1482,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
1470
1482
varDecl->getName ());
1471
1483
auto *assignExpr = new (C) AssignExpr (varExpr, SourceLoc (), tryExpr,
1472
1484
/* Implicit=*/ true );
1473
- statements.push_back (assignExpr);
1485
+ statements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
1474
1486
}
1475
1487
}
1476
1488
@@ -1506,7 +1518,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
1506
1518
// try super.init(from: container.superDecoder())
1507
1519
auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
1508
1520
/* Implicit=*/ true );
1509
- statements.push_back (tryExpr);
1521
+ statements.push_back (wrapInUnsafeIfNeeded (C, tryExpr) );
1510
1522
} else {
1511
1523
// The explicit constructor name is a compound name taking no arguments.
1512
1524
DeclName initName (C, DeclBaseName::createConstructor (),
@@ -1538,7 +1550,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
1538
1550
callExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
1539
1551
/* Implicit=*/ true );
1540
1552
1541
- statements.push_back (callExpr);
1553
+ statements.push_back (wrapInUnsafeIfNeeded (C, callExpr) );
1542
1554
}
1543
1555
}
1544
1556
}
@@ -1827,7 +1839,7 @@ deriveBodyDecodable_enum_init(AbstractFunctionDecl *initDecl, void *) {
1827
1839
new (C) AssignExpr (selfRef, SourceLoc (), selfCaseExpr,
1828
1840
/* Implicit=*/ true );
1829
1841
1830
- caseStatements.push_back (assignExpr);
1842
+ caseStatements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
1831
1843
} else {
1832
1844
// Foo.bar(x:)
1833
1845
SmallVector<Identifier, 3 > scratch;
@@ -1845,7 +1857,7 @@ deriveBodyDecodable_enum_init(AbstractFunctionDecl *initDecl, void *) {
1845
1857
new (C) AssignExpr (selfRef, SourceLoc (), caseCallExpr,
1846
1858
/* Implicit=*/ true );
1847
1859
1848
- caseStatements.push_back (assignExpr);
1860
+ caseStatements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
1849
1861
}
1850
1862
1851
1863
auto body =
0 commit comments