@@ -8723,56 +8723,6 @@ SourceLoc swift::extractNearestSourceLoc(SafeUseOfCxxDeclDescriptor desc) {
87238723 return SourceLoc ();
87248724}
87258725
8726- void swift::simple_display (llvm::raw_ostream &out,
8727- ClangTypeExplicitSafetyDescriptor desc) {
8728- auto qt = static_cast <clang::QualType>(desc.type );
8729- out << " Checking if type '" << qt.getAsString () << " ' is explicitly safe.\n " ;
8730- }
8731-
8732- SourceLoc swift::extractNearestSourceLoc (ClangTypeExplicitSafetyDescriptor desc) {
8733- return SourceLoc ();
8734- }
8735-
8736- ExplicitSafety ClangTypeExplicitSafety::evaluate (
8737- Evaluator &evaluator, ClangTypeExplicitSafetyDescriptor desc) const {
8738- auto clangType = static_cast <clang::QualType>(desc.type );
8739-
8740- // Handle pointers.
8741- auto pointeeType = clangType->getPointeeType ();
8742- if (!pointeeType.isNull ()) {
8743- // Function pointers are okay.
8744- if (pointeeType->isFunctionType ())
8745- return ExplicitSafety::Safe;
8746-
8747- // Pointers to record types are okay if they come in as foreign reference
8748- // types.
8749- if (auto *recordDecl = pointeeType->getAsRecordDecl ()) {
8750- if (hasImportAsRefAttr (recordDecl))
8751- return ExplicitSafety::Safe;
8752- }
8753-
8754- // All other pointers are considered unsafe.
8755- return ExplicitSafety::Unsafe;
8756- }
8757-
8758- // Handle records recursively.
8759- if (auto recordDecl = clangType->getAsTagDecl ()) {
8760- // If we reached this point the types is not imported as a shared reference,
8761- // so we don't need to check the bases whether they are shared references.
8762- auto req = ClangDeclExplicitSafety ({recordDecl, false });
8763- if (evaluator.hasActiveRequest (req))
8764- // Cycles are allowed in templates, e.g.:
8765- // template <typename> class Foo { ... }; // throws away template arg
8766- // template <typename T> class Bar : Foo<Bar<T>> { ... };
8767- // We need to avoid them here.
8768- return ExplicitSafety::Unspecified;
8769- return evaluateOrDefault (evaluator, req, ExplicitSafety::Unspecified);
8770- }
8771-
8772- // Everything else is safe.
8773- return ExplicitSafety::Safe;
8774- }
8775-
87768726void swift::simple_display (llvm::raw_ostream &out,
87778727 CxxDeclExplicitSafetyDescriptor desc) {
87788728 out << " Checking if '" ;
@@ -8844,13 +8794,43 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
88448794
88458795// / Check whether the given Clang type involves an unsafe type.
88468796static bool hasUnsafeType (Evaluator &evaluator, clang::QualType clangType) {
8847- auto req = ClangTypeExplicitSafety ({clangType});
8848- if (evaluator.hasActiveRequest (req))
8849- // If there is a cycle in a type, assume ExplicitSafety is Unspecified,
8850- // i.e., not unsafe:
8851- return false ;
8852- return evaluateOrDefault (evaluator, req, ExplicitSafety::Unspecified) ==
8853- ExplicitSafety::Unsafe;
8797+ // Handle pointers.
8798+ auto pointeeType = clangType->getPointeeType ();
8799+ if (!pointeeType.isNull ()) {
8800+ // Function pointers are okay.
8801+ if (pointeeType->isFunctionType ())
8802+ return false ;
8803+
8804+ // Pointers to record types are okay if they come in as foreign reference
8805+ // types.
8806+ if (auto recordDecl = pointeeType->getAsRecordDecl ()) {
8807+ if (hasImportAsRefAttr (recordDecl))
8808+ return false ;
8809+ }
8810+
8811+ // All other pointers are considered unsafe.
8812+ return true ;
8813+ }
8814+
8815+ // Handle records recursively.
8816+ if (auto recordDecl = clangType->getAsTagDecl ()) {
8817+ // If we reached this point the types is not imported as a shared reference,
8818+ // so we don't need to check the bases whether they are shared references.
8819+ auto safety = evaluateOrDefault (
8820+ evaluator, ClangDeclExplicitSafety ({recordDecl, false }),
8821+ ExplicitSafety::Unspecified);
8822+ switch (safety) {
8823+ case ExplicitSafety::Unsafe:
8824+ return true ;
8825+
8826+ case ExplicitSafety::Safe:
8827+ case ExplicitSafety::Unspecified:
8828+ return false ;
8829+ }
8830+ }
8831+
8832+ // Everything else is safe.
8833+ return false ;
88548834}
88558835
88568836ExplicitSafety
@@ -8888,29 +8868,6 @@ ClangDeclExplicitSafety::evaluate(Evaluator &evaluator,
88888868 ClangTypeEscapability ({recordDecl->getTypeForDecl (), nullptr }),
88898869 CxxEscapability::Unknown) != CxxEscapability::Unknown)
88908870 return ExplicitSafety::Safe;
8891-
8892- // A template class is unsafe if any of its type arguments are unsafe.
8893- // Note that this does not rely on the record being defined.
8894- if (const auto *ctsd =
8895- dyn_cast<clang::ClassTemplateSpecializationDecl>(recordDecl)) {
8896- for (auto arg : ctsd->getTemplateArgs ().asArray ()) {
8897- switch (arg.getKind ()) {
8898- case clang::TemplateArgument::Type:
8899- if (hasUnsafeType (evaluator, arg.getAsType ()))
8900- return ExplicitSafety::Unsafe;
8901- break ;
8902- case clang::TemplateArgument::Pack:
8903- for (auto pkArg : arg.getPackAsArray ()) {
8904- if (pkArg.getKind () == clang::TemplateArgument::Type &&
8905- hasUnsafeType (evaluator, pkArg.getAsType ()))
8906- return ExplicitSafety::Unsafe;
8907- }
8908- break ;
8909- default :
8910- continue ;
8911- }
8912- }
8913- }
89148871
89158872 // If we don't have a definition, leave it unspecified.
89168873 recordDecl = recordDecl->getDefinition ();
@@ -8924,7 +8881,7 @@ ClangDeclExplicitSafety::evaluate(Evaluator &evaluator,
89248881 return ExplicitSafety::Unsafe;
89258882 }
89268883 }
8927-
8884+
89288885 // Check the fields.
89298886 for (auto field : recordDecl->fields ()) {
89308887 if (hasUnsafeType (evaluator, field->getType ()))
0 commit comments