@@ -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>`.)
@@ -1699,7 +1699,8 @@ ImportedType ClangImporter::Implementation::importType(
1699
1699
llvm::function_ref<void (Diagnostic &&)> addImportDiagnosticFn,
1700
1700
bool allowNSUIntegerAsInt, Bridgeability bridging, ImportTypeAttrs attrs,
1701
1701
OptionalTypeKind optionality, bool resugarNSErrorPointer,
1702
- std::optional<unsigned> completionHandlerErrorParamIndex) {
1702
+ std::optional<unsigned> completionHandlerErrorParamIndex,
1703
+ bool *isSafePointer) {
1703
1704
if (type.isNull ())
1704
1705
return {Type (), false };
1705
1706
@@ -1761,6 +1762,8 @@ ImportedType ClangImporter::Implementation::importType(
1761
1762
*this , addImportDiagnosticFn, allowNSUIntegerAsInt, bridging,
1762
1763
completionHandlerType, completionHandlerErrorParamIndex);
1763
1764
auto importResult = converter.Visit (type);
1765
+ if (isSafePointer)
1766
+ *isSafePointer |= converter.hasSafePointer ();
1764
1767
1765
1768
// Now fix up the type based on how we're concretely using it.
1766
1769
auto adjustedType = adjustTypeForConcreteImport (
@@ -1774,13 +1777,13 @@ ImportedType ClangImporter::Implementation::importType(
1774
1777
Type ClangImporter::Implementation::importTypeIgnoreIUO (
1775
1778
clang::QualType type, ImportTypeKind importKind,
1776
1779
llvm::function_ref<void (Diagnostic &&)> addImportDiagnosticFn,
1777
- bool allowNSUIntegerAsInt, Bridgeability bridging,
1778
- ImportTypeAttrs attrs, OptionalTypeKind optionality ,
1779
- bool resugarNSErrorPointer ) {
1780
+ bool allowNSUIntegerAsInt, Bridgeability bridging, ImportTypeAttrs attrs,
1781
+ OptionalTypeKind optionality, bool resugarNSErrorPointer ,
1782
+ bool *isSafePointer ) {
1780
1783
1781
- auto importedType = importType (type, importKind, addImportDiagnosticFn,
1782
- allowNSUIntegerAsInt, bridging, attrs ,
1783
- optionality, resugarNSErrorPointer);
1784
+ auto importedType = importType (
1785
+ type, importKind, addImportDiagnosticFn, allowNSUIntegerAsInt, bridging,
1786
+ attrs, optionality, resugarNSErrorPointer, std::nullopt, isSafePointer );
1784
1787
1785
1788
return importedType.getType ();
1786
1789
}
@@ -2165,7 +2168,7 @@ applyImportTypeAttrs(ImportTypeAttrs attrs, Type type,
2165
2168
2166
2169
ImportedType ClangImporter::Implementation::importFunctionReturnType (
2167
2170
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2168
- bool allowNSUIntegerAsInt) {
2171
+ bool allowNSUIntegerAsInt, bool *isSafePointer ) {
2169
2172
2170
2173
// Hardcode handling of certain result types for builtins.
2171
2174
if (auto builtinID = clangDecl->getBuiltinID ()) {
@@ -2274,13 +2277,13 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
2274
2277
}
2275
2278
2276
2279
// Import the result type.
2277
- return importType (returnType,
2278
- (isAuditedResult ? ImportTypeKind::AuditedResult
2279
- : ImportTypeKind::Result),
2280
- ImportDiagnosticAdder (* this , clangDecl ,
2281
- clangDecl->getLocation ()),
2282
- allowNSUIntegerAsInt, Bridgeability::Full,
2283
- getImportTypeAttrs (clangDecl), OptionalityOfReturn );
2280
+ return importType (
2281
+ returnType,
2282
+ (isAuditedResult ? ImportTypeKind::AuditedResult
2283
+ : ImportTypeKind::Result) ,
2284
+ ImportDiagnosticAdder (* this , clangDecl, clangDecl->getLocation ()),
2285
+ allowNSUIntegerAsInt, Bridgeability::Full, getImportTypeAttrs (clangDecl) ,
2286
+ OptionalityOfReturn, isSafePointer );
2284
2287
}
2285
2288
2286
2289
static Type
@@ -2315,7 +2318,7 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2315
2318
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2316
2319
ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
2317
2320
bool isFromSystemModule, DeclName name, ParameterList *¶meterList,
2318
- ArrayRef<GenericTypeParamDecl *> genericParams) {
2321
+ ArrayRef<GenericTypeParamDecl *> genericParams, bool *hasSafePointer ) {
2319
2322
2320
2323
bool allowNSUIntegerAsInt =
2321
2324
shouldAllowNSUIntegerAsInt (isFromSystemModule, clangDecl);
@@ -2372,8 +2375,8 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2372
2375
// If importedType is already initialized, it means we found the enum that
2373
2376
// was supposed to be used (instead of the typedef type).
2374
2377
if (!importedType) {
2375
- importedType =
2376
- importFunctionReturnType ( dc, clangDecl, allowNSUIntegerAsInt);
2378
+ importedType = importFunctionReturnType (
2379
+ dc, clangDecl, allowNSUIntegerAsInt, hasSafePointer );
2377
2380
if (!importedType) {
2378
2381
addDiag (Diagnostic (diag::return_type_not_imported));
2379
2382
return {Type (), false };
@@ -2383,9 +2386,9 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2383
2386
2384
2387
Type swiftResultTy = importedType.getType ();
2385
2388
ArrayRef<Identifier> argNames = name.getArgumentNames ();
2386
- parameterList = importFunctionParameterList (dc, clangDecl, params, isVariadic,
2387
- allowNSUIntegerAsInt, argNames,
2388
- genericParams, swiftResultTy);
2389
+ parameterList = importFunctionParameterList (
2390
+ dc, clangDecl, params, isVariadic, allowNSUIntegerAsInt, argNames,
2391
+ genericParams, swiftResultTy, hasSafePointer );
2389
2392
if (!parameterList)
2390
2393
return {Type (), false };
2391
2394
@@ -2434,13 +2437,6 @@ ClangImporter::Implementation::importParameterType(
2434
2437
}
2435
2438
}
2436
2439
}
2437
- } else if (auto CAT = dyn_cast<clang::CountAttributedType>(paramTy)) {
2438
- // Treat as a normal pointer. importBoundsAttributes() will generate a safe
2439
- // overload later.
2440
- paramTy = CAT->desugar ();
2441
- if (auto FuncD =
2442
- dyn_cast<clang::FunctionDecl>(param->getParentFunctionOrMethod ()))
2443
- funcsWithPointerBounds.insert (FuncD);
2444
2440
} else if (isa<clang::PointerType>(paramTy) &&
2445
2441
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
2446
2442
auto pointeeType = paramTy->getPointeeType ();
@@ -2529,6 +2525,7 @@ ClangImporter::Implementation::importParameterType(
2529
2525
}
2530
2526
}
2531
2527
2528
+ bool isSafePointer = false ;
2532
2529
if (!swiftParamTy) {
2533
2530
// If this is the throws error parameter, we don't need to convert any
2534
2531
// NSError** arguments to the sugared NSErrorPointer typealias form,
@@ -2538,11 +2535,11 @@ ClangImporter::Implementation::importParameterType(
2538
2535
// for the specific case when the throws conversion works, but is not
2539
2536
// sufficient if it fails. (The correct, overarching fix is ClangImporter
2540
2537
// being lazier.)
2541
- auto importedType = importType (paramTy, importKind, addImportDiagnosticFn,
2542
- allowNSUIntegerAsInt, Bridgeability::Full ,
2543
- attrs, optionalityOfParam,
2544
- /* resugarNSErrorPointer=*/ !paramIsError,
2545
- completionHandlerErrorParamIndex);
2538
+ auto importedType = importType (
2539
+ paramTy, importKind, addImportDiagnosticFn, allowNSUIntegerAsInt ,
2540
+ Bridgeability::Full, attrs, optionalityOfParam,
2541
+ /* resugarNSErrorPointer=*/ !paramIsError,
2542
+ completionHandlerErrorParamIndex, &isSafePointer );
2546
2543
if (!importedType)
2547
2544
return std::nullopt;
2548
2545
@@ -2559,8 +2556,8 @@ ClangImporter::Implementation::importParameterType(
2559
2556
if (isInOut && isDirectUseOfForeignReferenceType (paramTy, swiftParamTy))
2560
2557
isInOut = false ;
2561
2558
2562
- return ImportParameterTypeResult{swiftParamTy, isInOut,
2563
- isParamTypeImplicitlyUnwrapped};
2559
+ return ImportParameterTypeResult{
2560
+ swiftParamTy, isInOut, isParamTypeImplicitlyUnwrapped, isSafePointer };
2564
2561
}
2565
2562
2566
2563
bool ClangImporter::Implementation::isDefaultArgSafeToImport (
@@ -2671,7 +2668,8 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2671
2668
DeclContext *dc, const clang::FunctionDecl *clangDecl,
2672
2669
ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
2673
2670
bool allowNSUIntegerAsInt, ArrayRef<Identifier> argNames,
2674
- ArrayRef<GenericTypeParamDecl *> genericParams, Type resultType) {
2671
+ ArrayRef<GenericTypeParamDecl *> genericParams, Type resultType,
2672
+ bool *hasSafePointerParam) {
2675
2673
// Import the parameters.
2676
2674
SmallVector<ParamDecl *, 4 > parameters;
2677
2675
unsigned index = 0 ;
@@ -2711,6 +2709,8 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2711
2709
bool isInOut = swiftParamTyOpt->isInOut ;
2712
2710
bool isParamTypeImplicitlyUnwrapped =
2713
2711
swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
2712
+ if (swiftParamTyOpt->isSafePointer && hasSafePointerParam)
2713
+ *hasSafePointerParam = true ;
2714
2714
2715
2715
// Retrieve the argument name.
2716
2716
Identifier name;
0 commit comments