Skip to content

Commit 9966e01

Browse files
authored
Merge pull request #78941 from eeckstein/fix-deinit-devirtualizer
DeinitDevirtualizer: bail out for C++ move-only types
2 parents e8fe5c3 + 1f534e1 commit 9966e01

File tree

6 files changed

+37
-1
lines changed

6 files changed

+37
-1
lines changed

SwiftCompilerSources/Sources/AST/Declarations.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ public class Decl: CustomStringConvertible, Hashable {
2020

2121
public var description: String { String(taking: bridged.getDebugDescription()) }
2222

23+
// True if this declaration is imported from C/C++/ObjC.
24+
public var hasClangNode: Bool { bridged.hasClangNode() }
25+
2326
public static func ==(lhs: Decl, rhs: Decl) -> Bool { lhs === rhs }
2427

2528
public func hash(into hasher: inout Hasher) {

SwiftCompilerSources/Sources/Optimizer/Utilities/Devirtualization.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ private func devirtualize(destroy: some DevirtualizableDestroy, _ context: some
3939
return true
4040
}
4141

42+
// We cannot de-virtualize C++ destructor calls of C++ move-only types because we cannot get
43+
// its destructor (`nominal.valueTypeDestructor` is nil).
44+
if nominal.hasClangNode {
45+
return false
46+
}
47+
4248
if nominal.valueTypeDestructor != nil && !destroy.shouldDropDeinit {
4349
guard let deinitFunc = context.lookupDeinit(ofNominal: nominal) else {
4450
return false

include/swift/AST/ASTBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ struct BridgedDeclObj {
333333
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef Type_getName() const;
334334
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef Value_getUserFacingName() const;
335335
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedSourceLoc Value_getNameLoc() const;
336+
BRIDGED_INLINE bool hasClangNode() const;
336337
BRIDGED_INLINE bool Value_isObjC() const;
337338
BRIDGED_INLINE bool GenericType_isGenericAtAnyLevel() const;
338339
BRIDGED_INLINE bool NominalType_isGlobalActor() const;

include/swift/AST/ASTBridgingImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ BridgedSourceLoc BridgedDeclObj::Value_getNameLoc() const {
158158
return BridgedSourceLoc(getAs<swift::ValueDecl>()->getNameLoc().getOpaquePointerValue());
159159
}
160160

161+
bool BridgedDeclObj::hasClangNode() const {
162+
return unbridged()->hasClangNode();
163+
}
164+
161165
bool BridgedDeclObj::Value_isObjC() const {
162166
return getAs<swift::ValueDecl>()->isObjC();
163167
}

test/SILOptimizer/Inputs/CXXTypesWithUserProvidedDestructor.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,15 @@ struct HasMemberWithUserProvidedDestructor {
1919
~HasMemberWithUserProvidedDestructor() {}
2020
};
2121

22+
void foo();
23+
24+
struct NonCopyable {
25+
NonCopyable(int x) : x(x) {}
26+
NonCopyable(const NonCopyable &) = delete;
27+
NonCopyable(NonCopyable &&other) : x(other.x) { other.x = -123; }
28+
~NonCopyable() { foo(); }
29+
30+
int x;
31+
};
32+
2233
#endif // TEST_SIL_OPTIMIZER_CXX_WITH_CUSTOM_DESTRUCTOR_H

test/SILOptimizer/devirt_deinits.sil

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-sil-opt -sil-print-types %s -deinit-devirtualizer -module-name=test | %FileCheck %s
1+
// RUN: %target-sil-opt -sil-print-types %s -deinit-devirtualizer -module-name=test -enable-experimental-cxx-interop -I %S/Inputs | %FileCheck %s
22

33
// REQUIRES: swift_in_compiler
44

@@ -7,6 +7,7 @@ sil_stage canonical
77
import Builtin
88
import Swift
99
import SwiftShims
10+
import CXXTypesWithUserProvidedDestructor
1011

1112
@inline(never) func log(_ s: StaticString)
1213

@@ -283,6 +284,16 @@ bb0(%0 : $*T):
283284
return %r : $()
284285
}
285286

287+
// CHECK-LABEL: sil [ossa] @nodevirt_of_cxx_type :
288+
// CHECK: destroy_addr %0
289+
// CHECK: } // end sil function 'nodevirt_of_cxx_type'
290+
sil [ossa] @nodevirt_of_cxx_type : $@convention(thin) (@in NonCopyable) -> () {
291+
bb0(%0 : $*NonCopyable):
292+
destroy_addr %0
293+
%5 = tuple ()
294+
return %5
295+
}
296+
286297
// CHECK-LABEL: sil @test_non_ossa :
287298
// CHECK: destroy_addr %0
288299
// CHECK: } // end sil function 'test_non_ossa'

0 commit comments

Comments
 (0)