Skip to content

Commit 8677fab

Browse files
committed
[cxx-interop] Add legacy implementation of is-safe-use-of-cxx-method.
1 parent 2115f7a commit 8677fab

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
@@ -6820,11 +6820,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
68206820
return false;
68216821
}
68226822

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

68276879
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6880+
if (!desc.ctx.LangOpts.hasFeature(Feature::NewCxxMethodSafetyHeuristics))
6881+
return legacyIsSafeUseOfCxxMethod(method);
6882+
68286883
// The user explicitly asked us to import this method.
68296884
if (hasUnsafeAPIAttr(method))
68306885
return true;

0 commit comments

Comments
 (0)