@@ -6763,11 +6763,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
6763
6763
return false ;
6764
6764
}
6765
6765
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
+
6766
6818
bool IsSafeUseOfCxxDecl::evaluate (Evaluator &evaluator,
6767
6819
SafeUseOfCxxDeclDescriptor desc) const {
6768
6820
const clang::Decl *decl = desc.decl ;
6769
6821
6770
6822
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6823
+ if (!desc.ctx .LangOpts .hasFeature (Feature::NewCxxMethodSafetyHeuristics))
6824
+ return legacyIsSafeUseOfCxxMethod (method);
6825
+
6771
6826
// The user explicitly asked us to import this method.
6772
6827
if (hasUnsafeAPIAttr (method))
6773
6828
return true ;
0 commit comments