Skip to content

Commit d885dec

Browse files
author
Gabor Horvath
committed
[cxx-interop] Import some C++ methods as Unsafe
ClangImporter already had some logic in place to rename certain unsafe C++ methods to make sure their name indicates unsafety. With the recent push for auditability, we have a new @unsafe attribute so we can automate parts of the auditing process. This patch makes sure whenever we rename a method as "Unsafe", we also add the @unsafe attribute.
1 parent 09c89fb commit d885dec

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8202,18 +8202,27 @@ bool swift::importer::isMutabilityAttr(const clang::SwiftAttrAttr *swiftAttr) {
82028202
swiftAttr->getAttribute() == "nonmutating";
82038203
}
82048204

8205-
static bool importAsUnsafe(ASTContext &context, const clang::RecordDecl *decl,
8205+
static bool importAsUnsafe(ASTContext &context, const clang::NamedDecl *decl,
82068206
const Decl *MappedDecl) {
82078207
if (!context.LangOpts.hasFeature(Feature::SafeInterop) ||
8208-
!context.LangOpts.hasFeature(Feature::AllowUnsafeAttribute) || !decl)
8208+
!context.LangOpts.hasFeature(Feature::AllowUnsafeAttribute))
82098209
return false;
82108210

8211+
if (isa<clang::CXXMethodDecl>(decl) &&
8212+
!evaluateOrDefault(context.evaluator, IsSafeUseOfCxxDecl({decl, context}),
8213+
{}))
8214+
return true;
8215+
82118216
if (isa<ClassDecl>(MappedDecl))
82128217
return false;
82138218

8214-
return evaluateOrDefault(
8215-
context.evaluator, ClangTypeEscapability({decl->getTypeForDecl()}),
8216-
CxxEscapability::Unknown) == CxxEscapability::Unknown;
8219+
if (const auto *record = dyn_cast<clang::RecordDecl>(decl))
8220+
return evaluateOrDefault(context.evaluator,
8221+
ClangTypeEscapability({record->getTypeForDecl()}),
8222+
CxxEscapability::Unknown) ==
8223+
CxxEscapability::Unknown;
8224+
8225+
return false;
82178226
}
82188227

82198228
void
@@ -8395,9 +8404,7 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
83958404
}
83968405
}
83978406

8398-
if (seenUnsafe ||
8399-
importAsUnsafe(SwiftContext, dyn_cast<clang::RecordDecl>(ClangDecl),
8400-
MappedDecl)) {
8407+
if (seenUnsafe || importAsUnsafe(SwiftContext, ClangDecl, MappedDecl)) {
84018408
auto attr = new (SwiftContext) UnsafeAttr(/*implicit=*/!seenUnsafe);
84028409
MappedDecl->getAttrs().add(attr);
84038410
}

test/Interop/Cxx/class/safe-interop-mode.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ struct UnknownEscapabilityAggregate {
4242
Unannotated unann;
4343
};
4444

45+
struct MyContainer {
46+
int begin() const { return 0; }
47+
int end() const { return -1; }
48+
};
49+
4550
//--- test.swift
4651

4752
import Test
@@ -57,7 +62,8 @@ func useUnsafeParam2(x: UnsafeReference) { // expected-warning{{reference to uns
5762
func useUnsafeParam3(x: UnknownEscapabilityAggregate) { // expected-warning{{reference to unsafe struct 'UnknownEscapabilityAggregate'}}
5863
}
5964

60-
func useSafeParams(x: Owner, y: View, z: SafeEscapableAggregate) {
65+
func useSafeParams(x: Owner, y: View, z: SafeEscapableAggregate, c: MyContainer) {
66+
let _ = c.__beginUnsafe() // expected-warning{{call to unsafe instance method '__beginUnsafe'}}
6167
}
6268

6369
func useCfType(x: CFArray) {

0 commit comments

Comments
 (0)