Skip to content

Commit 1c8486d

Browse files
committed
[cxx-interop] Add legacy implementation of is-safe-use-of-cxx-method.
1 parent 3e8867f commit 1c8486d

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6774,11 +6774,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
67746774
return false;
67756775
}
67766776

6777+
static bool legacyIsSafeUseOfCxxMethod(clang::CXXMethodDecl *method) {
6778+
// The user explicitly asked us to import this method.
6779+
if (hasUnsafeAPIAttr(method))
6780+
return true;
6781+
6782+
// If it's a static method, it cannot project anything. It's fine.
6783+
if (method->isOverloadedOperator() || method->isStatic() ||
6784+
isa<clang::CXXConstructorDecl>(decl))
6785+
return true;
6786+
6787+
if (isForeignReferenceType(method->getReturnType()))
6788+
return true;
6789+
6790+
// If it returns a pointer or reference, that's a projection.
6791+
if (method->getReturnType()->isPointerType() ||
6792+
method->getReturnType()->isReferenceType())
6793+
return false;
6794+
6795+
// Check if it's one of the known unsafe methods we currently
6796+
// mark as safe by default.
6797+
if (isUnsafeStdMethod(method))
6798+
return false;
6799+
6800+
// Try to figure out the semantics of the return type. If it's a
6801+
// pointer/iterator, it's unsafe.
6802+
if (auto returnType = dyn_cast<clang::RecordType>(
6803+
method->getReturnType().getCanonicalType())) {
6804+
if (auto cxxRecordReturnType =
6805+
dyn_cast<clang::CXXRecordDecl>(returnType->getDecl())) {
6806+
if (isSwiftClassType(cxxRecordReturnType))
6807+
return true;
6808+
if (hasIteratorAPIAttr(cxxRecordReturnType) ||
6809+
isIterator(cxxRecordReturnType)) {
6810+
return false;
6811+
}
6812+
6813+
// Mark this as safe to help our diganostics down the road.
6814+
if (!cxxRecordReturnType->getDefinition()) {
6815+
return true;
6816+
}
6817+
6818+
if (!hasCustomCopyOrMoveConstructor(cxxRecordReturnType) &&
6819+
!hasOwnedValueAttr(cxxRecordReturnType) &&
6820+
hasPointerInSubobjects(cxxRecordReturnType)) {
6821+
return false;
6822+
}
6823+
}
6824+
}
6825+
6826+
return true;
6827+
}
6828+
67776829
bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
67786830
SafeUseOfCxxDeclDescriptor desc) const {
67796831
const clang::Decl *decl = desc.decl;
67806832

67816833
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6834+
if (!desc.ctx.LangOpts.hasFeature(Feature::NewCxxMethodSafetyHeuristics))
6835+
return legacyIsSafeUseOfCxxMethod(method);
6836+
67826837
// The user explicitly asked us to import this method.
67836838
if (hasUnsafeAPIAttr(method))
67846839
return true;

0 commit comments

Comments
 (0)