Skip to content

Commit d64a24c

Browse files
Merge pull request #62619 from aschwaighofer/dyn_repl_weak
Fix dynamic replacement of weakly linked symbols
2 parents d3bc4f5 + 1e82ef8 commit d64a24c

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,6 +2732,10 @@ static InitializeDynamicReplacementLookup initDynamicReplacements;
27322732
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
27332733

27342734
void DynamicReplacementDescriptor::enableReplacement() const {
2735+
// Weakly linked symbols can be zero.
2736+
if (replacedFunctionKey.get() == nullptr)
2737+
return;
2738+
27352739
auto *chainRoot = const_cast<DynamicReplacementChainEntry *>(
27362740
replacedFunctionKey->root.get());
27372741

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@_weakLinked import LibA
2+
3+
extension A {
4+
@_dynamicReplacement(for: printThis())
5+
func _replacementForPrintThis() {
6+
Swift.print("replacement")
7+
}
8+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
public struct A {
2+
public var x : Int = 0
3+
public var y : Int = 1
4+
public init() {}
5+
#if BEFORE
6+
public func print() {
7+
printThis()
8+
}
9+
10+
public dynamic func printThis() {
11+
Swift.print(x)
12+
Swift.print(y)
13+
}
14+
#else
15+
public func print() {
16+
printThis2()
17+
}
18+
19+
public dynamic func printThis2() {
20+
Swift.print(x)
21+
Swift.print(y)
22+
}
23+
24+
#endif
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift-dylib(%t/%target-library-name(LibA)) -DBEFORE -module-name LibA -emit-module -emit-module-path %t/LibA.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_libA.swift
3+
// RUN: %target-build-swift-dylib(%t/%target-library-name(ReplacementA)) -I%t -L%t -lLibA -module-name ReplacementA -swift-version 5 %S/Inputs/dynamic_replacement_ReplacementA.swift
4+
// RUN: %target-build-swift-dylib(%t/%target-library-name(LibA)) -module-name LibA -emit-module -emit-module-path %t/LibA.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_libA.swift
5+
// RUN: %target-build-swift -I%t -L%t -lLibA -o %t/main %target-rpath(%t) %s -swift-version 5
6+
// RUN: %target-codesign %t/main %t/%target-library-name(LibA) %t/%target-library-name(ReplacementA)
7+
// RUN: %target-run %t/main %t/%target-library-name(LibA) %t/%target-library-name(ReplacementA)
8+
9+
// REQUIRES: executable_test
10+
// REQUIRES: OS=macosx
11+
// REQUIRES: swift_test_mode_optimize_none
12+
13+
import Darwin
14+
15+
import LibA
16+
17+
private func target_library_name(_ name: String) -> String {
18+
return "lib\(name).dylib"
19+
}
20+
21+
var executablePath = CommandLine.arguments[0]
22+
executablePath.removeLast(4)
23+
_ = dlopen(executablePath + target_library_name("ReplacementA"), RTLD_NOW)
24+
25+
A().print()

0 commit comments

Comments
 (0)