Skip to content

Commit c852f9f

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

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
@@ -6809,11 +6809,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
68096809
return false;
68106810
}
68116811

6812+
static bool legacyIsSafeUseOfCxxMethod(clang::CXXMethodDecl *method) {
6813+
// The user explicitly asked us to import this method.
6814+
if (hasUnsafeAPIAttr(method))
6815+
return true;
6816+
6817+
// If it's a static method, it cannot project anything. It's fine.
6818+
if (method->isOverloadedOperator() || method->isStatic() ||
6819+
isa<clang::CXXConstructorDecl>(decl))
6820+
return true;
6821+
6822+
if (isForeignReferenceType(method->getReturnType()))
6823+
return true;
6824+
6825+
// If it returns a pointer or reference, that's a projection.
6826+
if (method->getReturnType()->isPointerType() ||
6827+
method->getReturnType()->isReferenceType())
6828+
return false;
6829+
6830+
// Check if it's one of the known unsafe methods we currently
6831+
// mark as safe by default.
6832+
if (isUnsafeStdMethod(method))
6833+
return false;
6834+
6835+
// Try to figure out the semantics of the return type. If it's a
6836+
// pointer/iterator, it's unsafe.
6837+
if (auto returnType = dyn_cast<clang::RecordType>(
6838+
method->getReturnType().getCanonicalType())) {
6839+
if (auto cxxRecordReturnType =
6840+
dyn_cast<clang::CXXRecordDecl>(returnType->getDecl())) {
6841+
if (isSwiftClassType(cxxRecordReturnType))
6842+
return true;
6843+
if (hasIteratorAPIAttr(cxxRecordReturnType) ||
6844+
isIterator(cxxRecordReturnType)) {
6845+
return false;
6846+
}
6847+
6848+
// Mark this as safe to help our diganostics down the road.
6849+
if (!cxxRecordReturnType->getDefinition()) {
6850+
return true;
6851+
}
6852+
6853+
if (!hasCustomCopyOrMoveConstructor(cxxRecordReturnType) &&
6854+
!hasOwnedValueAttr(cxxRecordReturnType) &&
6855+
hasPointerInSubobjects(cxxRecordReturnType)) {
6856+
return false;
6857+
}
6858+
}
6859+
}
6860+
6861+
return true;
6862+
}
6863+
68126864
bool IsSafeUseOfCxxDecl::evaluate(Evaluator &evaluator,
68136865
SafeUseOfCxxDeclDescriptor desc) const {
68146866
const clang::Decl *decl = desc.decl;
68156867

68166868
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6869+
if (!desc.ctx.LangOpts.hasFeature(Feature::NewCxxMethodSafetyHeuristics))
6870+
return legacyIsSafeUseOfCxxMethod(method);
6871+
68176872
// The user explicitly asked us to import this method.
68186873
if (hasUnsafeAPIAttr(method))
68196874
return true;

0 commit comments

Comments
 (0)