[PackageCMO] Don't allow modifying AST.

Currently not all types are visited in canSerialize* calls, sometimes
 resulting in an internal type getting @usableFromInline, which is
 incorrect.

 For example, for `let q = P() as? Q`, where Q is an internal class
 inherting a public class P, Q is not visited in the canSerialize*
 checks, thus resulting in `@usableFromInline class Q`; this is not
 the intended behavior in the conservative mode used by PackageCMO
 as it modifies AST.

 To properly fix, instruction visitor needs to be refactored to do
 both the "canSerialize" check (that visits all types) and serialize
 or update visibility (modify AST in non-conservative modes).

 This PR provides a short-term fix that prevents modifying AST, and
 also ensures that the generated interfaces with PackageCMO flags
 are not affected by the optimization or contain modified AST.

rdar://130292190
This commit is contained in:
Ellie Shin
2024-06-25 17:21:17 -07:00
parent f6cfa083af
commit 1e5266e7b6
2 changed files with 81 additions and 0 deletions

View File

@@ -829,6 +829,21 @@ void CrossModuleOptimization::makeDeclUsableFromInline(ValueDecl *decl) {
if (decl->getEffectiveAccess() >= AccessLevel::Package)
return;
// FIXME: rdar://130456707
// Currently not all types are visited in canSerialize* calls, sometimes
// resulting in an internal type getting @usableFromInline, which is
// incorrect.
// For example, for `let q = P() as? Q`, where Q is an internal class
// inherting a public class P, Q is not visited in the canSerialize*
// checks, thus resulting in `@usableFromInline class Q`; this is not
// the intended behavior in the conservative mode as it modifies AST.
//
// To properly fix, instruction visitor needs to be refactored to do
// both the "canSerialize" check (that visits all types) and serialize
// or update visibility (modify AST in non-conservative modes).
if (isPackageCMOEnabled(M.getSwiftModule()))
return;
// We must not modify decls which are defined in other modules.
if (M.getSwiftModule() != decl->getDeclContext()->getParentModule())
return;