Skip to content

Commit 8251525

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

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
@@ -6763,11 +6763,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
67636763
return false;
67646764
}
67656765

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

67706822
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6823+
if (!desc.ctx.LangOpts.hasFeature(Feature::NewCxxMethodSafetyHeuristics))
6824+
return legacyIsSafeUseOfCxxMethod(method);
6825+
67716826
// The user explicitly asked us to import this method.
67726827
if (hasUnsafeAPIAttr(method))
67736828
return true;

0 commit comments

Comments
 (0)