Skip to content

[cxx-interop] Emit IR for destructors of temporary C++ values #61638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/IRGen/GenClangDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ class ClangDeclFinder
return true;
}

bool VisitCXXBindTemporaryExpr(clang::CXXBindTemporaryExpr *BTE) {
// This is a temporary value with a custom destructor. C++ will implicitly
// call the destructor at some point. Make sure we emit IR for it.
callback(BTE->getTemporary()->getDestructor());
return true;
}

// Do not traverse unevaluated expressions. Doing to might result in compile
// errors if we try to instantiate an un-instantiatable template.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H
#define TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H

struct Value {
void referencedByDestructor() { r(); }

double r();
};

void referencedByDestructor(Value *ptr) { ptr->referencedByDestructor(); }

struct Reference {
~Reference() {
if (ptr)
referencedByDestructor(ptr);
}
Value *ptr;
};

inline Reference getRef();
inline void takeDouble(double);

inline void testFunction() { takeDouble(getRef().ptr->r()); }

#endif // TEST_INTEROP_CXX_CLASS_INPUTS_DESTRUCTORS_WITH_TEMPORARY_VALUES_H
5 changes: 5 additions & 0 deletions test/Interop/Cxx/class/Inputs/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module Destructors {
requires cplusplus
}

module DestructorsWithTemporaryValues {
header "destructors-with-temporary-values.h"
requires cplusplus
}

module Extensions {
header "extensions.h"
requires cplusplus
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %target-swiftxx-frontend -emit-ir -I %S/Inputs -validate-tbd-against-ir=none %s | %FileCheck %s

import DestructorsWithTemporaryValues

public func test() {
testFunction()
}

// Make sure that we emit IR for functions that are called from the custom
// destructor of a temporary value created on the C++ side.

// CHECK: define{{( dso_local)?}} void @{{_Z22referencedByDestructorP5Value|"\?referencedByDestructor@@YAXPEAUValue@@@Z"}}
// CHECK: define linkonce_odr{{( dso_local)?}} void @{{_ZN5Value22referencedByDestructorEv|"\?referencedByDestructor@Value@@QEAAXXZ"}}