Frontend: Ignore lazy typechecking flags when emitting non-resilient modules.

The `-experimental-lazy-typecheck` and `-experimental-skip-non-exportable-decls`
flags are not safe to use when emitting a non-resilient module because the
clients of non-resilient modules expect to have access to all the members of a
type in order to e.g. compute the size the type. The
`-experimental-skip-non-exportable-decls` flag skips serialization of
non-public members and would therefore cause mis-compilation. The
`-experimental-lazy-typecheck` is theoretically safe for non-resilient modules
but more requestification work is needed before it can be used successfully.

Resolves rdar://122272758
This commit is contained in:
Allan Shortlidge
2024-02-04 08:12:25 -08:00
parent 2fa1022a91
commit 67661ccf93
8 changed files with 71 additions and 42 deletions

View File

@@ -166,6 +166,9 @@ ERROR(cannot_emit_ir_skipping_function_bodies,none,
WARNING(emit_reference_dependencies_without_primary_file,none,
"ignoring -emit-reference-dependencies (requires -primary-file)", ())
WARNING(ignoring_option_requires_option,none,
"ignoring %0 (requires %1)", (StringRef, StringRef))
WARNING(warn_implicit_concurrency_import_failed,none,
"unable to perform implicit import of \"_Concurrency\" module: no such module found", ())
REMARK(warn_implicit_string_processing_import_failed,none,

View File

@@ -318,11 +318,21 @@ bool ArgsToFrontendOptionsConverter::convert(
A->getOption().matches(OPT_serialize_debugging_options);
}
Opts.SkipNonExportableDecls |=
Args.hasArg(OPT_experimental_skip_non_exportable_decls);
Opts.SkipNonExportableDecls |=
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) &&
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies_is_lazy);
if (Args.hasArg(OPT_enable_library_evolution)) {
Opts.SkipNonExportableDecls |=
Args.hasArg(OPT_experimental_skip_non_exportable_decls);
Opts.SkipNonExportableDecls |=
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) &&
Args.hasArg(
OPT_experimental_skip_non_inlinable_function_bodies_is_lazy);
} else {
if (Args.hasArg(OPT_experimental_skip_non_exportable_decls))
Diags.diagnose(SourceLoc(), diag::ignoring_option_requires_option,
"-experimental-skip-non-exportable-decls",
"-enable-library-evolution");
}
// HACK: The driver currently erroneously passes all flags to module interface
// verification jobs. -experimental-skip-non-exportable-decls is not
// appropriate for verification tasks and should be ignored, though.

View File

@@ -1523,10 +1523,25 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args,
Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures);
Opts.DebugInverseRequirements |= Args.hasArg(OPT_debug_inverse_requirements);
Opts.EnableLazyTypecheck |= Args.hasArg(OPT_experimental_lazy_typecheck);
Opts.EnableLazyTypecheck |=
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) &&
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies_is_lazy);
if (Args.hasArg(OPT_enable_library_evolution)) {
Opts.EnableLazyTypecheck |= Args.hasArg(OPT_experimental_lazy_typecheck);
Opts.EnableLazyTypecheck |=
Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) &&
Args.hasArg(
OPT_experimental_skip_non_inlinable_function_bodies_is_lazy);
} else {
if (Args.hasArg(OPT_experimental_lazy_typecheck))
Diags.diagnose(SourceLoc(), diag::ignoring_option_requires_option,
"-experimental-lazy-typecheck",
"-enable-library-evolution");
if (Args.hasArg(
OPT_experimental_skip_non_inlinable_function_bodies_is_lazy))
Diags.diagnose(SourceLoc(), diag::ignoring_option_requires_option,
"-experimental-skip-non-inlinable-function-bodies-is-lazy",
"-enable-library-evolution");
}
// HACK: The driver currently erroneously passes all flags to module interface
// verification jobs. -experimental-skip-non-exportable-decls is not
// appropriate for verification tasks and should be ignored, though.

View File

@@ -5,7 +5,7 @@
// RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library.swiftmodule %S/Inputs/freestanding_macro_library.swift -module-name freestanding_macro_library -load-plugin-library %t/%target-library-name(MacroDefinition)
// RUN: %target-swift-frontend -parse-as-library -emit-sil -load-plugin-library %t/%target-library-name(MacroDefinition) %s -module-name MacroUser -experimental-skip-non-exportable-decls | %FileCheck %s
// RUN: %target-swift-frontend -parse-as-library -enable-library-evolution -emit-sil -load-plugin-library %t/%target-library-name(MacroDefinition) %s -module-name MacroUser -experimental-skip-non-exportable-decls | %FileCheck %s
@freestanding(declaration)
macro anonymousTypes(public: Bool = false, causeErrors: Bool = false, _: () -> String) = #externalMacro(module: "MacroDefinition", type: "DefineAnonymousTypesMacro")

View File

@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NON-LAZY
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test -experimental-lazy-typecheck | %FileCheck %s --check-prefixes=CHECK,CHECK-LAZY
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -enable-library-evolution -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NON-LAZY
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -enable-library-evolution -module-name Test -experimental-lazy-typecheck | %FileCheck %s --check-prefixes=CHECK,CHECK-LAZY
enum E {
case a, b
@@ -16,25 +16,25 @@ func internalFunc(_ e: E = .a) -> Int {
public var globalVar = internalFunc()
public struct S {
// CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV11instanceVarSivpfi : $@convention(thin) () -> Int {
// CHECK-LABEL: sil hidden [transparent]{{.*}} @$s4Test1SV11instanceVarSivpfi : $@convention(thin) () -> Int {
public var instanceVar = internalFunc()
// CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV12instanceVar2Sivpfi : $@convention(thin) () -> Int {
// CHECK-LABEL: sil hidden [transparent]{{.*}} @$s4Test1SV12instanceVar2Sivpfi : $@convention(thin) () -> Int {
public var instanceVar2 = internalFunc(.b)
// CHECK-NOT: s4Test1SV15lazyInstanceVarSivpfi
// CHECK-LABEL: sil [transparent]{{.*}} @$s4Test1SV018$__lazy_storage_$_B11InstanceVar33_0E4F053AA3AB7D4CDE3A37DBA8EF0430LLSiSgvpfi : $@convention(thin) () -> Optional<Int> {
// CHECK-LABEL: sil hidden [transparent]{{.*}} @$s4Test1SV018$__lazy_storage_$_B11InstanceVar33_0E4F053AA3AB7D4CDE3A37DBA8EF0430LLSiSgvpfi : $@convention(thin) () -> Optional<Int> {
public lazy var lazyInstanceVar = internalFunc()
// CHECK-LABEL: sil private [global_init_once_fn]{{.*}} @$s4Test1SV9staticVar_WZ : $@convention(c) (Builtin.RawPointer) -> () {
public static var staticVar = internalFunc()
// FIXME: This initializer should be subsumed.
// CHECK-LAZY: sil [transparent] [ossa] @$s4Test1SV15subsumedInitVarSivpfi : $@convention(thin) () -> Int {
// CHECK-NON-LAZY-NOT: sil [transparent] [ossa] @$s4Test1SV15subsumedInitVarSivpfi : $@convention(thin) () -> Int {
// CHECK-LAZY: sil hidden [transparent]{{.*}} @$s4Test1SV15subsumedInitVarSivpfi : $@convention(thin) () -> Int {
// CHECK-NON-LAZY-NOT: sil hidden [transparent]{{.*}} @$s4Test1SV15subsumedInitVarSivpfi : $@convention(thin) () -> Int {
public var subsumedInitVar = internalFunc()
// CHECK-LABEL: sil [transparent] [ossa] @$s4Test1SV19varWithInitAccessorSivpfi : $@convention(thin) () -> Int {
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s4Test1SV19varWithInitAccessorSivpfi : $@convention(thin) () -> Int {
public var varWithInitAccessor: Int = internalFunc() {
@storageRestrictions(initializes: subsumedInitVar)
init {
@@ -51,8 +51,9 @@ extension S {
public static var staticVarInExtension = internalFunc()
}
// CHECK-LABEL: sil{{.*}} @$s4Test8returnsSAA1SVyF : $@convention(thin) () -> @out S
public func returnsS() -> S {
// Force the synthesized initializer for S to be emitted.
// CHECK: function_ref @$s4Test1SVACycfC : $@convention(method) (@thin S.Type) -> S
// CHECK: function_ref @$s4Test1SVACycfC : $@convention(method) (@thin S.Type) -> @out S
return S()
}

View File

@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-SKIP
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -module-name Test -experimental-skip-non-exportable-decls | %FileCheck %s --check-prefixes=CHECK,CHECK-SKIP
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -enable-library-evolution -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-SKIP
// RUN: %target-swift-frontend -emit-silgen %s -parse-as-library -enable-library-evolution -module-name Test -experimental-skip-non-exportable-decls | %FileCheck %s --check-prefixes=CHECK,CHECK-SKIP
import Swift
@@ -15,7 +15,7 @@ import Swift
// CHECK-NO-SKIP: sil_global private @$s4Test15publicGlobalVar_Wz : $Builtin.Word
// CHECK-SKIP-NOT: s4Test15publicGlobalVar_Wz
// CHECK: sil_global @$s4Test15publicGlobalVarSivp : $Int
// CHECK: sil_global private @$s4Test15publicGlobalVarSivp : $Int
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF : $@convention(thin) () -> () {
// CHECK-SKIP-NOT: s4Test11privateFunc33_CFB3F9DC47F5EF9E1D08B58758351A08LLyyF
@@ -46,7 +46,7 @@ internal func internalFuncWithNestedFunc() {
// CHECK-SKIP-NOT: s4Test022internalFuncWithNestedC0yyFyycyXEfU_
// CHECK-NO-SKIP: sil private{{.*}} @$s4Test022internalFuncWithNestedC0yyFyycyXEfU_6$deferL_yyF : $@convention(thin) () -> () {
// CHECK-SKIP-NOT: @$s4Test022internalFuncWithNestedC0yyFyycyXEfU_6$deferL_yyF
// CHECK-SKIP-NOT: sil{{.*}} @$s4Test022internalFuncWithNestedC0yyFyycyXEfU_6$deferL_yyF
// CHECK: sil{{.*}} @$s4Test10publicFuncyyF : $@convention(thin) () -> () {
public func publicFunc() {}
@@ -73,8 +73,8 @@ internal var internalGlobalVar = 1
// CHECK-NO-SKIP: sil private [global_init_once_fn]{{.*}} @$s4Test15publicGlobalVar_WZ : $@convention(c) (Builtin.RawPointer) -> () {
// CHECK-SKIP-NOT: s4Test15publicGlobalVar_WZ
// CHECK-NO-SKIP: sil [global_init]{{.*}} @$s4Test15publicGlobalVarSivau : $@convention(thin) () -> Builtin.RawPointer {
// CHECK-SKIP-NOT: s4Test15publicGlobalVarSivau
// CHECK-NO-SKIP: sil hidden [global_init]{{.*}} @$s4Test15publicGlobalVarSivau : $@convention(thin) () -> Builtin.RawPointer {
// CHECK-SKIP-NOT: sil{{.*}} s4Test15publicGlobalVarSivau
public var publicGlobalVar = 1
// CHECK: sil [serialized]{{.*}} @$s4Test023inlinableFuncWithNestedC0yyF : $@convention(thin) () -> () {
@@ -94,9 +94,9 @@ public var publicGlobalVar = 1
@propertyWrapper
public struct PublicWrapper<T> {
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvg : $@convention(method) <T> (@in_guaranteed PublicWrapper<T>) -> @out T {
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvs : $@convention(method) <T> (@in T, @inout PublicWrapper<T>) -> () {
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvM : $@yield_once @convention(method) <T> (@inout PublicWrapper<T>) -> @yields @inout T {
// CHECK: sil{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvg : $@convention(method) <T> (@in_guaranteed PublicWrapper<T>) -> @out T {
// CHECK: sil{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvs : $@convention(method) <T> (@in T, @inout PublicWrapper<T>) -> () {
// CHECK: sil{{.*}} @$s4Test13PublicWrapperV12wrappedValuexvM : $@yield_once @convention(method) <T> (@inout PublicWrapper<T>) -> @yields @inout T {
public var wrappedValue: T
// CHECK: sil{{.*}} @$s4Test13PublicWrapperV12wrappedValueACyxGx_tcfC : $@convention(method) <T> (@in T, @thin PublicWrapper<T>.Type) -> @out PublicWrapper<T> {
@@ -118,24 +118,24 @@ private class PrivateClass {
}
public class PublicClass {
// CHECK-NO-SKIP: sil [transparent]{{.*}} @$s4Test11PublicClassC11internalVarSivpfi : $@convention(thin) () -> Int {
// CHECK-NO-SKIP: sil{{.*}} @$s4Test11PublicClassC11internalVarSivpfi : $@convention(thin) () -> Int {
// CHECK-SKIP-NOT: s4Test11PublicClassC11internalVarSivpfi
// CHECK-NO-SKIP: sil hidden [transparent]{{.*}} @$s4Test11PublicClassC11internalVarSivg : $@convention(method) (@guaranteed PublicClass) -> Int {
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassC11internalVarSivg : $@convention(method) (@guaranteed PublicClass) -> Int {
// CHECK-SKIP-NOT: s4Test11PublicClassC11internalVarSivg
// CHECK-NO-SKIP: sil hidden [transparent]{{.*}} @$s4Test11PublicClassC11internalVarSivs : $@convention(method) (Int, @guaranteed PublicClass) -> () {
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassC11internalVarSivs : $@convention(method) (Int, @guaranteed PublicClass) -> () {
// CHECK-SKIP-NOT: s4Test11PublicClassC11internalVarSivs
// CHECK-NO-SKIP: sil hidden [transparent]{{.*}} @$s4Test11PublicClassC11internalVarSivM : $@yield_once @convention(method) (@guaranteed PublicClass) -> @yields @inout Int {
// CHECK-NO-SKIP: sil hidden{{.*}} @$s4Test11PublicClassC11internalVarSivM : $@yield_once @convention(method) (@guaranteed PublicClass) -> @yields @inout Int {
// CHECK-SKIP-NOT: s4Test11PublicClassC11internalVarSivM
var internalVar = 1
// CHECK-NO-SKIP: sil [transparent]{{.*}} @$s4Test11PublicClassC9publicVarSivpfi : $@convention(thin) () -> Int {
// CHECK-NO-SKIP: sil{{.*}} @$s4Test11PublicClassC9publicVarSivpfi : $@convention(thin) () -> Int {
// CHECK-SKIP-NOT: s4Test11PublicClassC9publicVarSivpfi
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test11PublicClassC9publicVarSivg : $@convention(method) (@guaranteed PublicClass) -> Int {
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test11PublicClassC9publicVarSivs : $@convention(method) (Int, @guaranteed PublicClass) -> () {
// CHECK: sil [transparent] [serialized]{{.*}} @$s4Test11PublicClassC9publicVarSivM : $@yield_once @convention(method) (@guaranteed PublicClass) -> @yields @inout Int {
// CHECK: sil{{.*}} @$s4Test11PublicClassC9publicVarSivg : $@convention(method) (@guaranteed PublicClass) -> Int {
// CHECK: sil{{.*}} @$s4Test11PublicClassC9publicVarSivs : $@convention(method) (Int, @guaranteed PublicClass) -> () {
// CHECK: sil{{.*}} @$s4Test11PublicClassC9publicVarSivM : $@yield_once @convention(method) (@guaranteed PublicClass) -> @yields @inout Int {
public var publicVar = 1
// CHECK-NO-SKIP: sil{{.*}} @$s4Test11PublicClassC16publicWrappedVarSivpfP : $@convention(thin) (Int) -> PublicWrapper<Int> {
// CHECK-NO-SKIP: sil{{.*}} @$s4Test11PublicClassC16publicWrappedVarSivpfP : $@convention(thin) (Int) -> @out PublicWrapper<Int> {
// CHECK-SKIP-NOT: s4Test11PublicClassC16publicWrappedVarSivpfP
// CHECK: sil{{.*}} @$s4Test11PublicClassC16publicWrappedVarSivg : $@convention(method) (@guaranteed PublicClass) -> Int {
// CHECK: sil{{.*}} @$s4Test11PublicClassC16publicWrappedVarSivs : $@convention(method) (Int, @guaranteed PublicClass) -> () {
@@ -174,7 +174,7 @@ extension PublicClass {
// CHECK-NO-SKIP-NEXT: }
// CHECK-SKIP-NOT: sil_vtable PrivateClass
// CHECK-LABEL: sil_vtable [serialized] PublicClass {
// CHECK-LABEL: sil_vtable PublicClass {
// CHECK-NO-SKIP-NEXT: #PublicClass.internalVar!getter
// CHECK-SKIP-NOT: #PublicClass.internalVar!getter
// CHECK-NO-SKIP-NEXT: #PublicClass.internalVar!setter
@@ -194,4 +194,4 @@ extension PublicClass {
// CHECK-NEXT: #PublicClass.deinit!deallocator
// CHECK-NEXT: }
// CHECK: sil_property #PublicClass.publicVar ()
// CHECK: sil_property #PublicClass.publicVar

View File

@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-silgen %s -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-SKIP
// RUN: %target-swift-frontend -emit-silgen %s -module-name Test -experimental-skip-non-exportable-decls | %FileCheck %s --check-prefixes=CHECK,CHECK-SKIP
// RUN: %target-swift-frontend -enable-library-evolution -emit-silgen %s -module-name Test | %FileCheck %s --check-prefixes=CHECK,CHECK-NO-SKIP
// RUN: %target-swift-frontend -enable-library-evolution -emit-silgen %s -module-name Test -experimental-skip-non-exportable-decls | %FileCheck %s --check-prefixes=CHECK,CHECK-SKIP
// CHECK-NO-SKIP: sil_global hidden @$s4Test1xSivp : $Int
// CHECK-SKIP: sil_global hidden_external @$s4Test1xSivp : $Int

View File

@@ -1,5 +1,5 @@
// RUN: not %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -experimental-lazy-typecheck
// RUN: %target-typecheck-verify-swift -enable-library-evolution -experimental-lazy-typecheck
// With lazy typechecking enabled and no compiler outputs specified, no errors
// should be emitted for this semantically invalid code.