@@ -6809,11 +6809,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
6809
6809
return false ;
6810
6810
}
6811
6811
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
+
6812
6864
bool IsSafeUseOfCxxDecl::evaluate (Evaluator &evaluator,
6813
6865
SafeUseOfCxxDeclDescriptor desc) const {
6814
6866
const clang::Decl *decl = desc.decl ;
6815
6867
6816
6868
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6869
+ if (!desc.ctx .LangOpts .hasFeature (Feature::NewCxxMethodSafetyHeuristics))
6870
+ return legacyIsSafeUseOfCxxMethod (method);
6871
+
6817
6872
// The user explicitly asked us to import this method.
6818
6873
if (hasUnsafeAPIAttr (method))
6819
6874
return true ;
0 commit comments