@@ -2194,6 +2194,39 @@ namespace {
2194
2194
dc);
2195
2195
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
2196
2196
2197
+ // We have to do this after populating ImportedDecls to avoid importing
2198
+ // the same multiple times.
2199
+ if (Impl.SwiftContext .LangOpts .hasFeature (Feature::SafeInterop) &&
2200
+ Impl.SwiftContext .LangOpts .hasFeature (
2201
+ Feature::AllowUnsafeAttribute)) {
2202
+ if (const auto *ctsd =
2203
+ dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
2204
+ for (auto arg : ctsd->getTemplateArgs ().asArray ()) {
2205
+ llvm::SmallVector<clang::TemplateArgument, 1 > nonPackArgs;
2206
+ if (arg.getKind () == clang::TemplateArgument::Pack) {
2207
+ auto pack = arg.getPackAsArray ();
2208
+ nonPackArgs.assign (pack.begin (), pack.end ());
2209
+ } else {
2210
+ nonPackArgs.push_back (arg);
2211
+ }
2212
+ for (auto realArg : nonPackArgs) {
2213
+ if (realArg.getKind () != clang::TemplateArgument::Type)
2214
+ continue ;
2215
+ auto SwiftType = Impl.importTypeIgnoreIUO (
2216
+ realArg.getAsType (), ImportTypeKind::Abstract,
2217
+ [](Diagnostic &&diag) {}, false , Bridgeability::None,
2218
+ ImportTypeAttrs ());
2219
+ if (SwiftType && SwiftType->isUnsafe ()) {
2220
+ auto attr =
2221
+ new (Impl.SwiftContext ) UnsafeAttr (/* implicit=*/ true );
2222
+ result->getAttrs ().add (attr);
2223
+ break ;
2224
+ }
2225
+ }
2226
+ }
2227
+ }
2228
+ }
2229
+
2197
2230
if (recordHasMoveOnlySemantics (decl)) {
2198
2231
if (decl->isInStdNamespace () && decl->getName () == " promise" ) {
2199
2232
// Do not import std::promise.
@@ -8405,6 +8438,13 @@ static bool importAsUnsafe(ClangImporter::Implementation &impl,
8405
8438
if (isa<ClassDecl>(MappedDecl))
8406
8439
return false ;
8407
8440
8441
+ // Most STL containers have std::allocator as their default allocator. We need
8442
+ // to consider std::allocator safe for the STL containers to be ever
8443
+ // considered safe.
8444
+ if (decl->isInStdNamespace () && decl->getIdentifier () &&
8445
+ decl->getName () == " allocator" )
8446
+ return false ;
8447
+
8408
8448
if (const auto *record = dyn_cast<clang::RecordDecl>(decl))
8409
8449
return evaluateOrDefault (
8410
8450
context.evaluator ,
0 commit comments