@@ -6774,11 +6774,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
6774
6774
return false ;
6775
6775
}
6776
6776
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
+
6777
6829
bool IsSafeUseOfCxxDecl::evaluate (Evaluator &evaluator,
6778
6830
SafeUseOfCxxDeclDescriptor desc) const {
6779
6831
const clang::Decl *decl = desc.decl ;
6780
6832
6781
6833
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6834
+ if (!desc.ctx .LangOpts .hasFeature (Feature::NewCxxMethodSafetyHeuristics))
6835
+ return legacyIsSafeUseOfCxxMethod (method);
6836
+
6782
6837
// The user explicitly asked us to import this method.
6783
6838
if (hasUnsafeAPIAttr (method))
6784
6839
return true ;
0 commit comments