@@ -216,6 +216,7 @@ namespace {
216
216
Bridgeability Bridging;
217
217
const clang::FunctionType *CompletionHandlerType;
218
218
std::optional<unsigned > CompletionHandlerErrorParamIndex;
219
+ bool isSafePointer = false ;
219
220
220
221
public:
221
222
SwiftTypeConverter (ClangImporter::Implementation &impl,
@@ -238,6 +239,8 @@ namespace {
238
239
return IR;
239
240
}
240
241
242
+ bool hasSafePointer () { return isSafePointer; }
243
+
241
244
ImportResult VisitType (const Type*) = delete;
242
245
243
246
// TODO(https://github.com/apple/swift/issues/56206): Add support for dependent types.
@@ -412,13 +415,8 @@ namespace {
412
415
413
416
ImportResult VisitCountAttributedType (
414
417
const clang::CountAttributedType *type) {
415
- // CountAttributedType is a clang type representing a pointer with
416
- // a "counted_by" type attribute. For now, we don't import these
417
- // into Swift.
418
- // In the future we could do something more clever (such as trying to
419
- // import as an Array where possible) or less clever (such as importing
420
- // as the desugared, underlying pointer type).
421
- return Type ();
418
+ isSafePointer = true ;
419
+ return Visit (type->desugar ());
422
420
}
423
421
424
422
ImportResult VisitMemberPointerType (const clang::MemberPointerType *type) {
@@ -470,7 +468,9 @@ namespace {
470
468
// without special hints.
471
469
Type pointeeType = Impl.importTypeIgnoreIUO (
472
470
pointeeQualType, ImportTypeKind::Value, addImportDiagnostic,
473
- AllowNSUIntegerAsInt, Bridgeability::None, ImportTypeAttrs ());
471
+ AllowNSUIntegerAsInt, Bridgeability::None, ImportTypeAttrs (),
472
+ OTK_ImplicitlyUnwrappedOptional, /* resugarNSErrorPointer=*/ true ,
473
+ &isSafePointer);
474
474
475
475
// If this is imported as a reference type, ignore the innermost pointer.
476
476
// (`T *` becomes `T`, but `T **` becomes `UnsafeMutablePointer<T>`.)
@@ -1689,7 +1689,8 @@ ImportedType ClangImporter::Implementation::importType(
1689
1689
llvm::function_ref<void (Diagnostic &&)> addImportDiagnosticFn,
1690
1690
bool allowNSUIntegerAsInt, Bridgeability bridging, ImportTypeAttrs attrs,
1691
1691
OptionalTypeKind optionality, bool resugarNSErrorPointer,
1692
- std::optional<unsigned> completionHandlerErrorParamIndex) {
1692
+ std::optional<unsigned> completionHandlerErrorParamIndex,
1693
+ bool *isSafePointer) {
1693
1694
if (type.isNull ())
1694
1695
return {Type (), false };
1695
1696
@@ -1751,6 +1752,8 @@ ImportedType ClangImporter::Implementation::importType(
1751
1752
*this , addImportDiagnosticFn, allowNSUIntegerAsInt, bridging,
1752
1753
completionHandlerType, completionHandlerErrorParamIndex);
1753
1754
auto importResult = converter.Visit (type);
1755
+ if (isSafePointer)
1756
+ *isSafePointer |= converter.hasSafePointer ();
1754
1757
1755
1758
// Now fix up the type based on how we're concretely using it.
1756
1759
auto adjustedType = adjustTypeForConcreteImport (
@@ -1764,13 +1767,13 @@ ImportedType ClangImporter::Implementation::importType(
1764
1767
Type ClangImporter::Implementation::importTypeIgnoreIUO (
1765
1768
clang::QualType type, ImportTypeKind importKind,
1766
1769
llvm::function_ref<void (Diagnostic &&)> addImportDiagnosticFn,
1767
- bool allowNSUIntegerAsInt, Bridgeability bridging,
1768
- ImportTypeAttrs attrs, OptionalTypeKind optionality ,
1769
- bool resugarNSErrorPointer ) {
1770
+ bool allowNSUIntegerAsInt, Bridgeability bridging, ImportTypeAttrs attrs,
1771
+ OptionalTypeKind optionality, bool resugarNSErrorPointer ,
1772
+ bool *isSafePointer ) {
1770
1773
1771
- auto importedType = importType (type, importKind, addImportDiagnosticFn,
1772
- allowNSUIntegerAsInt, bridging, attrs ,
1773
- optionality, resugarNSErrorPointer);
1774
+ auto importedType = importType (
1775
+ type, importKind, addImportDiagnosticFn, allowNSUIntegerAsInt, bridging,
1776
+ attrs, optionality, resugarNSErrorPointer, std::nullopt, isSafePointer );
1774
1777
1775
1778
return importedType.getType ();
1776
1779
}
@@ -2155,7 +2158,7 @@ applyImportTypeAttrs(ImportTypeAttrs attrs, Type type,
2155
2158
2156
2159
ImportedType ClangImporter::Implementation::importFunctionReturnType (
2157
2160
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2158
- bool allowNSUIntegerAsInt) {
2161
+ bool allowNSUIntegerAsInt, bool *isSafePointer ) {
2159
2162
2160
2163
// Hardcode handling of certain result types for builtins.
2161
2164
if (auto builtinID = clangDecl->getBuiltinID ()) {
@@ -2264,13 +2267,13 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
2264
2267
}
2265
2268
2266
2269
// Import the result type.
2267
- return importType (returnType,
2268
- (isAuditedResult ? ImportTypeKind::AuditedResult
2269
- : ImportTypeKind::Result),
2270
- ImportDiagnosticAdder (* this , clangDecl ,
2271
- clangDecl->getLocation ()),
2272
- allowNSUIntegerAsInt, Bridgeability::Full,
2273
- getImportTypeAttrs (clangDecl), OptionalityOfReturn );
2270
+ return importType (
2271
+ returnType,
2272
+ (isAuditedResult ? ImportTypeKind::AuditedResult
2273
+ : ImportTypeKind::Result) ,
2274
+ ImportDiagnosticAdder (* this , clangDecl, clangDecl->getLocation ()),
2275
+ allowNSUIntegerAsInt, Bridgeability::Full, getImportTypeAttrs (clangDecl) ,
2276
+ OptionalityOfReturn, isSafePointer );
2274
2277
}
2275
2278
2276
2279
static Type
@@ -2305,7 +2308,7 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2305
2308
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2306
2309
ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
2307
2310
bool isFromSystemModule, DeclName name, ParameterList *¶meterList,
2308
- ArrayRef<GenericTypeParamDecl *> genericParams) {
2311
+ ArrayRef<GenericTypeParamDecl *> genericParams, bool *hasSafePointer ) {
2309
2312
2310
2313
bool allowNSUIntegerAsInt =
2311
2314
shouldAllowNSUIntegerAsInt (isFromSystemModule, clangDecl);
@@ -2362,8 +2365,8 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2362
2365
// If importedType is already initialized, it means we found the enum that
2363
2366
// was supposed to be used (instead of the typedef type).
2364
2367
if (!importedType) {
2365
- importedType =
2366
- importFunctionReturnType ( dc, clangDecl, allowNSUIntegerAsInt);
2368
+ importedType = importFunctionReturnType (
2369
+ dc, clangDecl, allowNSUIntegerAsInt, hasSafePointer );
2367
2370
if (!importedType) {
2368
2371
addDiag (Diagnostic (diag::return_type_not_imported));
2369
2372
return {Type (), false };
@@ -2373,9 +2376,9 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2373
2376
2374
2377
Type swiftResultTy = importedType.getType ();
2375
2378
ArrayRef<Identifier> argNames = name.getArgumentNames ();
2376
- parameterList = importFunctionParameterList (dc, clangDecl, params, isVariadic,
2377
- allowNSUIntegerAsInt, argNames,
2378
- genericParams, swiftResultTy);
2379
+ parameterList = importFunctionParameterList (
2380
+ dc, clangDecl, params, isVariadic, allowNSUIntegerAsInt, argNames,
2381
+ genericParams, swiftResultTy, hasSafePointer );
2379
2382
if (!parameterList)
2380
2383
return {Type (), false };
2381
2384
@@ -2424,13 +2427,6 @@ ClangImporter::Implementation::importParameterType(
2424
2427
}
2425
2428
}
2426
2429
}
2427
- } else if (auto CAT = dyn_cast<clang::CountAttributedType>(paramTy)) {
2428
- // Treat as a normal pointer. importBoundsAttributes() will generate a safe
2429
- // overload later.
2430
- paramTy = CAT->desugar ();
2431
- if (auto FuncD =
2432
- dyn_cast<clang::FunctionDecl>(param->getParentFunctionOrMethod ()))
2433
- funcsWithPointerBounds.insert (FuncD);
2434
2430
} else if (isa<clang::PointerType>(paramTy) &&
2435
2431
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
2436
2432
auto pointeeType = paramTy->getPointeeType ();
@@ -2519,6 +2515,7 @@ ClangImporter::Implementation::importParameterType(
2519
2515
}
2520
2516
}
2521
2517
2518
+ bool isSafePointer = false ;
2522
2519
if (!swiftParamTy) {
2523
2520
// If this is the throws error parameter, we don't need to convert any
2524
2521
// NSError** arguments to the sugared NSErrorPointer typealias form,
@@ -2528,11 +2525,11 @@ ClangImporter::Implementation::importParameterType(
2528
2525
// for the specific case when the throws conversion works, but is not
2529
2526
// sufficient if it fails. (The correct, overarching fix is ClangImporter
2530
2527
// being lazier.)
2531
- auto importedType = importType (paramTy, importKind, addImportDiagnosticFn,
2532
- allowNSUIntegerAsInt, Bridgeability::Full ,
2533
- attrs, optionalityOfParam,
2534
- /* resugarNSErrorPointer=*/ !paramIsError,
2535
- completionHandlerErrorParamIndex);
2528
+ auto importedType = importType (
2529
+ paramTy, importKind, addImportDiagnosticFn, allowNSUIntegerAsInt ,
2530
+ Bridgeability::Full, attrs, optionalityOfParam,
2531
+ /* resugarNSErrorPointer=*/ !paramIsError,
2532
+ completionHandlerErrorParamIndex, &isSafePointer );
2536
2533
if (!importedType)
2537
2534
return std::nullopt;
2538
2535
@@ -2549,8 +2546,8 @@ ClangImporter::Implementation::importParameterType(
2549
2546
if (isInOut && isDirectUseOfForeignReferenceType (paramTy, swiftParamTy))
2550
2547
isInOut = false ;
2551
2548
2552
- return ImportParameterTypeResult{swiftParamTy, isInOut,
2553
- isParamTypeImplicitlyUnwrapped};
2549
+ return ImportParameterTypeResult{
2550
+ swiftParamTy, isInOut, isParamTypeImplicitlyUnwrapped, isSafePointer };
2554
2551
}
2555
2552
2556
2553
bool ClangImporter::Implementation::isDefaultArgSafeToImport (
@@ -2661,7 +2658,8 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2661
2658
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2662
2659
ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
2663
2660
bool allowNSUIntegerAsInt, ArrayRef<Identifier> argNames,
2664
- ArrayRef<GenericTypeParamDecl *> genericParams, Type resultType) {
2661
+ ArrayRef<GenericTypeParamDecl *> genericParams, Type resultType,
2662
+ bool *hasSafePointerParam) {
2665
2663
// Import the parameters.
2666
2664
SmallVector<ParamDecl *, 4 > parameters;
2667
2665
unsigned index = 0 ;
@@ -2701,6 +2699,8 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2701
2699
bool isInOut = swiftParamTyOpt->isInOut ;
2702
2700
bool isParamTypeImplicitlyUnwrapped =
2703
2701
swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
2702
+ if (swiftParamTyOpt->isSafePointer && hasSafePointerParam)
2703
+ *hasSafePointerParam = true ;
2704
2704
2705
2705
// Retrieve the argument name.
2706
2706
Identifier name;
0 commit comments