Skip to content

Commit 8bc6960

Browse files
committed
[cxx-interop] Emit IR for destructors of temporary C++ values
This fixes the "undefined reference" linker errors. rdar://101092732
1 parent 3daa875 commit 8bc6960

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ class ClangDeclFinder
7575
return true;
7676
}
7777

78+
bool VisitCXXBindTemporaryExpr(clang::CXXBindTemporaryExpr *BTE) {
79+
// This is a temporary value with a custom destructor. C++ will implicitly
80+
// call the destructor at some point. Make sure we emit IR for it.
81+
callback(BTE->getTemporary()->getDestructor());
82+
return true;
83+
}
84+
7885
// Do not traverse unevaluated expressions. Doing to might result in compile
7986
// errors if we try to instantiate an un-instantiatable template.
8087

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H
2+
#define TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H
3+
4+
struct Value {
5+
void referencedByDestructor() {}
6+
7+
double r() { return 1.5; }
8+
};
9+
10+
void referencedByDestructor(Value *ptr) { ptr->referencedByDestructor(); }
11+
12+
struct Reference {
13+
~Reference() {
14+
if (ptr)
15+
referencedByDestructor(ptr);
16+
}
17+
Value *ptr;
18+
};
19+
20+
inline Reference getRef() { return Reference(); }
21+
inline void takeDouble(double) {}
22+
23+
inline void testFunction() { takeDouble(getRef().ptr->r()); }
24+
25+
#endif // TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %target-swiftxx-frontend -emit-ir -I %S/Inputs -validate-tbd-against-ir=none %s | %FileCheck %s
2+
3+
import DestructorsWithTemporaryValues
4+
5+
public func test() {
6+
testFunction()
7+
}
8+
9+
// Make sure that we emit IR for functions that are called from the custom
10+
// destructor of a temporary value created on the C++ side.
11+
12+
// CHECK: define void @_Z22referencedByDestructorP5Value
13+
// CHECK: define linkonce_odr void @_ZN5Value22referencedByDestructorEv

0 commit comments

Comments
 (0)