Skip to content

Commit 37b45da

Browse files
hypegorzhdan
authored andcommitted
[interop] ensure C++ stdlib set's insert methods are unsafe
(cherry picked from commit 6c6092e)
1 parent 04668cd commit 37b45da

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

lib/ClangImporter/ClangDerivedConformances.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,23 @@ void swift::conformToCxxSequenceIfNeeded(
565565
}
566566
}
567567

568+
static bool isStdSetType(const clang::CXXRecordDecl *clangDecl) {
569+
return isStdDecl(clangDecl, {"set", "unordered_set", "multiset"});
570+
}
571+
572+
bool swift::isUnsafeStdMethod(const clang::CXXMethodDecl *methodDecl) {
573+
auto parentDecl =
574+
dyn_cast<clang::CXXRecordDecl>(methodDecl->getDeclContext());
575+
if (!parentDecl)
576+
return false;
577+
if (!isStdSetType(parentDecl))
578+
return false;
579+
if (methodDecl->getDeclName().isIdentifier() &&
580+
methodDecl->getName() == "insert")
581+
return true;
582+
return false;
583+
}
584+
568585
void swift::conformToCxxSetIfNeeded(ClangImporter::Implementation &impl,
569586
NominalTypeDecl *decl,
570587
const clang::CXXRecordDecl *clangDecl) {
@@ -576,7 +593,7 @@ void swift::conformToCxxSetIfNeeded(ClangImporter::Implementation &impl,
576593

577594
// Only auto-conform types from the C++ standard library. Custom user types
578595
// might have a similar interface but different semantics.
579-
if (!isStdDecl(clangDecl, {"set", "unordered_set", "multiset"}))
596+
if (!isStdSetType(clangDecl))
580597
return;
581598

582599
auto valueType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(

lib/ClangImporter/ClangDerivedConformances.h

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ namespace swift {
2020

2121
bool isIterator(const clang::CXXRecordDecl *clangDecl);
2222

23+
bool isUnsafeStdMethod(const clang::CXXMethodDecl *methodDecl);
24+
2325
/// If the decl is a C++ input iterator, synthesize a conformance to the
2426
/// UnsafeCxxInputIterator protocol, which is defined in the Cxx module.
2527
void conformToCxxIteratorIfNeeded(ClangImporter::Implementation &impl,

lib/ClangImporter/ClangImporter.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -6747,6 +6747,11 @@ bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
67476747
method->getReturnType()->isReferenceType())
67486748
return false;
67496749

6750+
// Check if it's one of the known unsafe methods we currently
6751+
// mark as safe by default.
6752+
if (isUnsafeStdMethod(method))
6753+
return false;
6754+
67506755
// Try to figure out the semantics of the return type. If it's a
67516756
// pointer/iterator, it's unsafe.
67526757
if (auto returnType = dyn_cast<clang::RecordType>(

0 commit comments

Comments
 (0)