Skip to content

Commit b2d1adc

Browse files
authored
Merge pull request #80671 from swiftlang/gaborh/escapable-type-nonesc-field
[cxx-interop] Diagnose Escapable C++ types with non-escapable fields
2 parents edb25ce + e0a431e commit b2d1adc

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

include/swift/AST/DiagnosticsClangImporter.def

+4
Original file line numberDiff line numberDiff line change
@@ -377,5 +377,9 @@ NOTE(ptr_to_nonescapable,none,
377377
"pointer to non-escapable type %0 cannot be imported",
378378
(const clang::Type*))
379379

380+
NOTE(nonescapable_field_of_escapable, none,
381+
"escapable record %0 cannot have non-escapable field '%1'",
382+
(const clang::NamedDecl *, StringRef))
383+
380384
#define UNDEFINE_DIAGNOSTIC_MACROS
381385
#include "DefineDiagnosticMacros.h"

lib/ClangImporter/ImportDecl.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,23 @@ namespace {
24012401
continue;
24022402
}
24032403

2404-
members.push_back(cast<VarDecl>(member));
2404+
auto *vd = cast<VarDecl>(member);
2405+
if (!isNonEscapable) {
2406+
if (const auto *fd = dyn_cast<clang::FieldDecl>(nd))
2407+
if (evaluateOrDefault(
2408+
Impl.SwiftContext.evaluator,
2409+
ClangTypeEscapability({fd->getType().getTypePtr(), &Impl}),
2410+
CxxEscapability::Unknown) ==
2411+
CxxEscapability::NonEscapable) {
2412+
Impl.addImportDiagnostic(
2413+
decl,
2414+
Diagnostic(diag::nonescapable_field_of_escapable, decl,
2415+
nd->getName()),
2416+
decl->getLocation());
2417+
return nullptr;
2418+
}
2419+
}
2420+
members.push_back(vd);
24052421
}
24062422

24072423
bool hasReferenceableFields = !members.empty();

test/Interop/Cxx/class/nonescapable-errors.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,21 @@ const View* usedToCrash(const View* p) {
9595
return p;
9696
}
9797

98+
struct SWIFT_ESCAPABLE Invalid {
99+
View v;
100+
};
101+
98102
//--- test.swift
99103
import Test
100104
import CxxStdlib
101105

106+
// CHECK: error: cannot find type 'Invalid' in scope
107+
// CHECK: note: escapable record 'Invalid' cannot have non-escapable field 'v'
108+
public func importInvalid(_ x: Invalid) {
109+
}
110+
102111
// CHECK: error: a function with a ~Escapable result needs a parameter to depend on
103-
// CHECK-NO-LIFETIMES: test.swift:6:32: error: a function with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'
112+
// CHECK-NO-LIFETIMES: test.swift:11:32: error: a function with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'
104113
public func noAnnotations() -> View {
105114
// CHECK: nonescapable.h:16:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies
106115
// CHECK-NO-LIFETIMES: nonescapable.h:16:7: warning: the returned type 'Owner' is annotated as escapable; it cannot have lifetime dependencies

0 commit comments

Comments
 (0)