mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Nested calls to importBaseMemberDecl() subvert its cache and compromise its idempotence, causing the semantic checker to spuriously report ambiguous member lookups when multiple ClangRecordMemberLookup requests are made (e.g., because of an unrelated missing member lookup). One such scenario is documented as a test case: test/Interop/Cxx/class/inheritance/inherited-lookup-typechecker.swift fails without this patch because of the expected error from the missing member. Meanwhile, test/Interop/Cxx/class/inheritance/inherited-lookup-executable.swift works because it does not attempt to access a missing member. This patch fixes the issue by only calling importBaseMemberDecl() in the most derived class (where the ClangRecordMemberLookup originated, i.e., not in recursive requests). As a consequence of my patch, synthesized member accessors in the derived class directly invoke the member from the base class where the member is inherited from, rather than incurring an indirection at each level of inheritance. As such, the synthesized symbol names are different (and shorter). I've taken this opportunity to update the relevant tests to // CHECK for more of the mangled symbol, rather than only the synthesized symbol prefix, for more precise testing and slightly better readability. rdar://141069984
34 lines
2.0 KiB
Swift
34 lines
2.0 KiB
Swift
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=swift-6 %s -validate-tbd-against-ir=none | %FileCheck %s
|
|
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=upcoming-swift %s -validate-tbd-against-ir=none | %FileCheck %s
|
|
|
|
import MoveOnlyCxxValueType
|
|
|
|
func testGetX() -> CInt {
|
|
let derived = NonCopyableHolderDerivedDerived(42)
|
|
return derived.x.x
|
|
}
|
|
|
|
let _ = testGetX()
|
|
|
|
func testSetX(_ x: CInt) {
|
|
var derived = NonCopyableHolderDerivedDerived(42)
|
|
derived.x.x = 2
|
|
}
|
|
|
|
testSetX(2)
|
|
|
|
// Beware: this test exhibits a subtle difference between open source Clang and AppleClang:
|
|
// AppleClang runs in an ABI compatibility mode with Clang <= 4, which uses a
|
|
// different criteria to determine whether a C++ type can be passed in
|
|
// registers. This causes Swift to assume that NonCopyableHolderDerivedDerived
|
|
// can be both loadable or address-only, depending on the compiler flavor used.
|
|
// (rdar://128424443)
|
|
|
|
// CHECK: sil shared [transparent] @$sSo024NonCopyableHolderDerivedD0V1xSo0aB0Vvlu : $@convention(method) (@{{(in_)?}}guaranteed NonCopyableHolderDerivedDerived) -> UnsafePointer<NonCopyable>
|
|
// CHECK: {{.*}}(%[[SELF_VAL:.*]] : ${{(\*)?}}NonCopyableHolderDerivedDerived):
|
|
// CHECK: function_ref @{{(.*)(31NonCopyableHolderDerivedDerived33__synthesizedBaseGetterAccessor_x|__synthesizedBaseGetterAccessor_x@NonCopyableHolderDerivedDerived)(.*)}} : $@convention(cxx_method) (@in_guaranteed NonCopyableHolderDerivedDerived) -> UnsafePointer<NonCopyable>
|
|
// CHECK-NEXT: apply %{{.*}}
|
|
|
|
// CHECK: sil shared [transparent] @$sSo024NonCopyableHolderDerivedD0V1xSo0aB0Vvau : $@convention(method) (@inout NonCopyableHolderDerivedDerived) -> UnsafeMutablePointer<NonCopyable>
|
|
// CHECK: function_ref @{{(.*)(31NonCopyableHolderDerivedDerived33__synthesizedBaseSetterAccessor_x|__synthesizedBaseSetterAccessor_x@NonCopyableHolderDerivedDerived)(.*)}} : $@convention(cxx_method) (@inout NonCopyableHolderDerivedDerived) -> UnsafeMutablePointer<NonCopyable>
|