mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Swift allows a method override to be more visible than the base method. In practice, this means that since it might be possible for client code to see the override but not the base method, we have to take extra care when emitting the override. Specifically, the override always receives a new vtable entry, and a vtable thunk is emitted in place of the base method's vtable entry which re-dispatches via the override's vtable entry. This allows client code to further override the method without any knowledge of the base method's vtable entry, which may be inaccessible to the client. In order for the above to work, three places in the code perform co-ordinated checks: - needsNewVTableEntry() determines whether the override is more visible than the base, in which case it receives a new vtable entry - SILGenModule::emitVTableMethod() performs the same check in order to emit the re-dispatching vtable thunk in place of the base method's entry - in the client, SILVTableVisitor then skips the base method's vtable entry entirely when emitting the derived class, since no thunk is to be emitted. The problem was that the first two used effective access (where internal declarations become public with -enable-testing), while the last check used formal access. As a result, it was possible for the method override vtable entry to never be emitted in the client. Consistently using either effective access or formal access would fix the problem. I fixed the first two to rely on formal access; the reason is that using effective access makes vtable layout depend on whether the library was built with -enable-testing or not, which is undesirable since we do not want -enable-testing to impact the ABI, even for non-resilient frameworks. Fixes rdar://problem/74108928.
116 lines
4.9 KiB
Swift
116 lines
4.9 KiB
Swift
// We test various combinations to make sure that -enable-testing does not
|
|
// break ABI with or without -enable-library-evolution.
|
|
|
|
////
|
|
|
|
// RUN: %empty-directory(%t)
|
|
|
|
// 1) -enable-testing OFF / -enable-library-evolution OFF
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -emit-module -emit-module-path %t/vtables_multifile_testable_helper.swiftmodule
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// 2) -enable-testing ON / -enable-library-evolution OFF
|
|
|
|
// ... first without rebuilding the client:
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -enable-testing -emit-module -emit-module-path %t/vtables_multifile_testable_helper.swiftmodule
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// ... now try to rebuild the client:
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
////
|
|
|
|
// Delete build artifacts
|
|
// RUN: %empty-directory(%t)
|
|
|
|
// 3) -enable-testing OFF / -enable-library-evolution ON
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -enable-library-evolution -emit-module -emit-module-path %t/vtables_multifile_testable_helper.swiftmodule
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// 4) -enable-testing ON / -enable-library-evolution ON
|
|
|
|
// ... first without rebuilding the client:
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -enable-testing -enable-library-evolution -emit-module -emit-module-path %t/vtables_multifile_testable_helper.swiftmodule
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// ... now try to rebuild the client:
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
////
|
|
|
|
// Delete build artifacts
|
|
// RUN: %empty-directory(%t)
|
|
|
|
// 5) -enable-testing OFF / -enable-library-evolution ON / textual interfaces
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -enable-library-evolution -emit-module-interface -emit-module-interface-path %t/vtables_multifile_testable_helper.swiftinterface
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// 6) -enable-testing ON / -enable-library-evolution ON / textual interfaces
|
|
|
|
// ... first without rebuilding the client:
|
|
|
|
// RUN: %target-build-swift-dylib(%t/%target-library-name(vtables_multifile_testable_helper)) %S/Inputs/vtables_multifile_testable_helper.swift -enable-testing -enable-library-evolution -emit-module-interface -emit-module-interface-path %t/vtables_multifile_testable_helper.swiftinterface
|
|
// RUN: %target-codesign %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
// ... now try to rebuild the client:
|
|
|
|
// RUN: %target-build-swift %s -L %t -I %t -lvtables_multifile_testable_helper -o %t/main %target-rpath(%t)
|
|
// RUN: %target-codesign %t/main
|
|
|
|
// RUN: %target-run %t/main %t/%target-library-name(vtables_multifile_testable_helper)
|
|
|
|
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
import vtables_multifile_testable_helper
|
|
|
|
var VTableTestSuite = TestSuite("VTable")
|
|
|
|
public class Derived : Middle {
|
|
public override func method() -> Int {
|
|
return super.method() + 1
|
|
}
|
|
}
|
|
|
|
VTableTestSuite.test("Derived") {
|
|
expectEqual(3, callBaseMethod(Derived()))
|
|
expectEqual(3, callMiddleMethod(Derived()))
|
|
}
|
|
|
|
runAllTests()
|