File tree Expand file tree Collapse file tree 2 files changed +65
-1
lines changed Expand file tree Collapse file tree 2 files changed +65
-1
lines changed Original file line number Diff line number Diff line change @@ -85,8 +85,19 @@ class ClangDeclFinder
8585 bool VisitCXXConstructorDecl (clang::CXXConstructorDecl *CXXCD) {
8686 callback (CXXCD);
8787 for (clang::CXXCtorInitializer *CXXCI : CXXCD->inits ()) {
88- if (clang::FieldDecl *FD = CXXCI->getMember ())
88+ if (clang::FieldDecl *FD = CXXCI->getMember ()) {
8989 callback (FD);
90+ // A throwing constructor might throw after the field is initialized,
91+ // emitting additional cleanup code that destroys the field. Make sure
92+ // we record the destructor of the field in that case as it might need
93+ // to be potentially emitted.
94+ if (auto *recordType = FD->getType ()->getAsCXXRecordDecl ()) {
95+ if (auto *destructor = recordType->getDestructor ()) {
96+ if (!destructor->isDeleted ())
97+ callback (destructor);
98+ }
99+ }
100+ }
90101 }
91102 return true ;
92103 }
Original file line number Diff line number Diff line change 1+ // RUN: rm -rf %t
2+ // RUN: split-file %s %t
3+ // RUN: %target-swiftxx-frontend -emit-ir -I %t/Inputs -validate-tbd-against-ir=none %t/test.swift | %FileCheck %s
4+
5+ //--- Inputs/module.modulemap
6+ module ThrowingConstructorDestructorCleanupRef {
7+ header " test.h "
8+ requires cplusplus
9+ }
10+ //--- Inputs/test.h
11+
12+ void testFunc( int x) ;
13+
14+ template < class T>
15+ class HasDestruct or {
16+ T x = 0 ;
17+ public:
18+
19+ HasDestructor ( ) { }
20+ HasDestructor ( const HasDestruct or & other) : x( other. x) { }
21+ inline ~ HasDestructor( ) { testFunc ( 42 ) ; }
22+ } ;
23+
24+ template < class T>
25+ class HasThrowingConstructor {
26+ HasDestructor< T> m;
27+ public:
28+ HasThrowingConstructor ( ) ;
29+ ~ HasThrowingConstructor( ) ;
30+ inline HasThrowingConstructor( const HasThrowingConstructor & f ) : m( f. m) {
31+ doSomethingThatMightThrow ( ) ;
32+ }
33+
34+ void doSomethingThatMightThrow ( ) ;
35+ } ;
36+
37+ inline void test33 ( const HasThrowingConstruct or< int> x) {
38+
39+ }
40+
41+ using HasThrowingConstructorInt = HasThrowingConstructor < int > ;
42+
43+ //--- test.swift
44+
45+ import ThrowingConstructorDestructorCleanupRef
46+
47+ public func test( ) {
48+ let x = HasThrowingConstructorInt ( )
49+ test33 ( x)
50+ }
51+
52+ // Make sure we reach the destructor of 'HasDestructor'
53+ // CHECK: define linkonce_odr {{.*}} @{{_ZN13HasDestructorIiED2Ev|"\?\?1\?\$HasDestructor@H@@QEAA@XZ"}}
You can’t perform that action at this time.
0 commit comments