Skip to content

Commit 18eb4e4

Browse files
committed
Serialization: Skip lookup shadowing when resolving cross-references
When a Swift function shadows a clang function of the same name, the assumption was that Swift code would refer only to the Swift one. However, if the Swift function is `@usableFromInline internal` it can be called only from the local module and inlined automatically in other clients. Outside of that module, sources see only the clang function, so their inlinable code calls only the clang function and ignores the Swift one. This configuration passed type checking but it could crash the compiler at inlining the call as the compiler couldn't see the clang function. Let's update the deserialization logic to support inlined calls to the shadowed or the shadower. Typical shadowing is already handled by the custom deserialization cross-reference filtering logic which looks for the defining module, scope and whether it's a Swift or clang decl. We can disable the lookup shadowing logic and rely only on the deserialization filtering. rdar://146320871 #79801
1 parent cc14548 commit 18eb4e4

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
20752075
getIdentifier(privateDiscriminator));
20762076
} else {
20772077
baseModule->lookupQualified(baseModule, DeclNameRef(name),
2078-
SourceLoc(), NL_QualifiedDefault,
2078+
SourceLoc(), NL_RemoveOverridden,
20792079
values);
20802080
}
20812081
filterValues(filterTy, nullptr, nullptr, isType, inProtocolExt,
@@ -2285,8 +2285,8 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
22852285
getIdentifier(privateDiscriminator));
22862286
} else {
22872287
otherModule->lookupQualified(otherModule, DeclNameRef(name),
2288-
SourceLoc(), NL_QualifiedDefault,
2289-
values);
2288+
SourceLoc(), NL_RemoveOverridden,
2289+
values);
22902290
}
22912291

22922292
std::optional<ValueDecl*> matchBeforeFiltering = std::nullopt;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/// Ensure inlined code in swiftmodules differentiates between shadowed Swift
2+
/// and clang decls.
3+
4+
// RUN: %empty-directory(%t)
5+
// RUN: split-file %s %t
6+
// REQUIRES: objc_interop
7+
8+
/// Reference build: Build libs and client for a normal build.
9+
// RUN: %target-swift-frontend -emit-module %t/RootLib.swift -I %t \
10+
// RUN: -emit-module-path %t/RootLib.swiftmodule
11+
// RUN: %target-swift-frontend -emit-module %t/MiddleLib.swift -I %t \
12+
// RUN: -emit-module-path %t/MiddleLib.swiftmodule
13+
// RUN: %target-swift-frontend -emit-sil -O %t/Client.swift -I %t > %t/Client.sil
14+
// RUN: %FileCheck %s --input-file=%t/Client.sil
15+
16+
//--- module.modulemap
17+
module RootLib {
18+
header "RootLib.h"
19+
}
20+
21+
//--- RootLib.h
22+
#include <stdio.h>
23+
void ShadowedFunc() {
24+
printf("Clang\n");
25+
}
26+
27+
//--- RootLib.swift
28+
@_exported import RootLib
29+
30+
@usableFromInline
31+
internal func ShadowedFunc() {
32+
print("Swift")
33+
}
34+
35+
@inlinable
36+
@inline(__always)
37+
public func swiftUser() {
38+
ShadowedFunc() // Swift one
39+
}
40+
41+
//--- MiddleLib.swift
42+
43+
import RootLib
44+
45+
@inlinable
46+
@inline(__always)
47+
public func clangUser() {
48+
ShadowedFunc() // Clang one
49+
}
50+
51+
//--- Client.swift
52+
53+
import RootLib
54+
import MiddleLib
55+
56+
swiftUser()
57+
// CHECK: [[SWIFT_FUNC:%.*]] = function_ref @$s7RootLib12ShadowedFuncyyF : $@convention(thin) () -> ()
58+
// CHECK: apply [[SWIFT_FUNC]]() : $@convention(thin) () -> ()
59+
// CHECK-NOT: apply [[SWIFT_FUNC]]() : $@convention(thin) () -> ()
60+
61+
clangUser()
62+
// CHECK: [[CLANG_FUNC:%.*]] = function_ref @ShadowedFunc : $@convention(c) () -> ()
63+
// CHECK: apply [[CLANG_FUNC]]() : $@convention(c) () -> ()
64+
// CHECK-NOT: apply [[CLANG_FUNC]]() : $@convention(c) () -> ()

0 commit comments

Comments
 (0)