@@ -772,10 +772,20 @@ lookupVarDeclForCodingKeysCase(DeclContext *conformanceDC,
772772 llvm_unreachable (" Should have found at least 1 var decl" );
773773}
774774
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) {
779789 // CodingKeys.x
780790 auto *metaTyRef = TypeExpr::createImplicit (codingKeysType, C);
781791 auto *keyExpr = new (C) MemberRefExpr (metaTyRef, SourceLoc (), codingKey,
@@ -794,7 +804,7 @@ static TryExpr *createEncodeCall(ASTContext &C, Type codingKeysType,
794804 // try container.encode(x, forKey: CodingKeys.x)
795805 auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
796806 /* Implicit=*/ true );
797- return tryExpr;
807+ return wrapInUnsafeIfNeeded (C, tryExpr) ;
798808}
799809
800810// / Synthesizes the body for `func encode(to encoder: Encoder) throws`.
@@ -929,7 +939,7 @@ deriveBodyEncodable_encode(AbstractFunctionDecl *encodeDecl, void *) {
929939 // try super.encode(to: container.superEncoder())
930940 auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
931941 /* Implicit=*/ true );
932- statements.push_back (tryExpr);
942+ statements.push_back (wrapInUnsafeIfNeeded (C, tryExpr) );
933943 }
934944
935945 auto *body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc (),
@@ -1112,8 +1122,10 @@ deriveBodyEncodable_enum_encode(AbstractFunctionDecl *encodeDecl, void *) {
11121122
11131123 // generate: switch self { }
11141124 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));
11171129 auto switchStmt = createEnumSwitch (
11181130 C, funcDC, enumRef, enumDecl, codingKeysEnum,
11191131 /* createSubpattern*/ true ,
@@ -1276,11 +1288,11 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) {
12761288 return encodeDecl;
12771289}
12781290
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) {
12841296 auto methodName = useIfPresentVariant ? C.Id_decodeIfPresent : C.Id_decode ;
12851297
12861298 // Type.self
@@ -1470,7 +1482,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
14701482 varDecl->getName ());
14711483 auto *assignExpr = new (C) AssignExpr (varExpr, SourceLoc (), tryExpr,
14721484 /* Implicit=*/ true );
1473- statements.push_back (assignExpr);
1485+ statements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
14741486 }
14751487 }
14761488
@@ -1506,7 +1518,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
15061518 // try super.init(from: container.superDecoder())
15071519 auto *tryExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
15081520 /* Implicit=*/ true );
1509- statements.push_back (tryExpr);
1521+ statements.push_back (wrapInUnsafeIfNeeded (C, tryExpr) );
15101522 } else {
15111523 // The explicit constructor name is a compound name taking no arguments.
15121524 DeclName initName (C, DeclBaseName::createConstructor (),
@@ -1538,7 +1550,7 @@ deriveBodyDecodable_init(AbstractFunctionDecl *initDecl, void *) {
15381550 callExpr = new (C) TryExpr (SourceLoc (), callExpr, Type (),
15391551 /* Implicit=*/ true );
15401552
1541- statements.push_back (callExpr);
1553+ statements.push_back (wrapInUnsafeIfNeeded (C, callExpr) );
15421554 }
15431555 }
15441556 }
@@ -1827,7 +1839,7 @@ deriveBodyDecodable_enum_init(AbstractFunctionDecl *initDecl, void *) {
18271839 new (C) AssignExpr (selfRef, SourceLoc (), selfCaseExpr,
18281840 /* Implicit=*/ true );
18291841
1830- caseStatements.push_back (assignExpr);
1842+ caseStatements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
18311843 } else {
18321844 // Foo.bar(x:)
18331845 SmallVector<Identifier, 3 > scratch;
@@ -1845,7 +1857,7 @@ deriveBodyDecodable_enum_init(AbstractFunctionDecl *initDecl, void *) {
18451857 new (C) AssignExpr (selfRef, SourceLoc (), caseCallExpr,
18461858 /* Implicit=*/ true );
18471859
1848- caseStatements.push_back (assignExpr);
1860+ caseStatements.push_back (wrapInUnsafeIfNeeded (C, assignExpr) );
18491861 }
18501862
18511863 auto body =
0 commit comments