@@ -6820,11 +6820,66 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
6820
6820
return false ;
6821
6821
}
6822
6822
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
+
6823
6875
bool IsSafeUseOfCxxDecl::evaluate (Evaluator &evaluator,
6824
6876
SafeUseOfCxxDeclDescriptor desc) const {
6825
6877
const clang::Decl *decl = desc.decl ;
6826
6878
6827
6879
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl)) {
6880
+ if (!desc.ctx .LangOpts .hasFeature (Feature::NewCxxMethodSafetyHeuristics))
6881
+ return legacyIsSafeUseOfCxxMethod (method);
6882
+
6828
6883
// The user explicitly asked us to import this method.
6829
6884
if (hasUnsafeAPIAttr (method))
6830
6885
return true ;
0 commit comments