Skip to content

Commit de35114

Browse files
committed
[Diagnostics] Add a tailored diagnostic for Swift -> C pointer conversion
Diagnose situations where Swift -> C pointer implicit conversion is attempted on a Swift function instead of one imported from C header. ```swift func test(_: UnsafePointer<UInt8>) {} func pass_ptr(ptr: UnsafeRawPointer) { test(ptr) // Only okay if `test` was an imported C function. } ```
1 parent f53bcea commit de35114

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,11 @@ ERROR(cannot_convert_argument_value,none,
362362
"cannot convert value of type %0 to expected argument type %1",
363363
(Type,Type))
364364

365+
ERROR(cannot_convert_argument_value_for_swift_func,none,
366+
"cannot convert value of type %0 to expected argument type %1 "
367+
"because %2 %3 was not imported from C header",
368+
(Type,Type, DescriptiveDeclKind, DeclName))
369+
365370
NOTE(candidate_has_invalid_argument_at_position,none,
366371
"candidate expects %select{|in-out }2value of type %0 for parameter #%1 (got %3)",
367372
(Type, unsigned, bool, Type))

lib/Sema/CSDiagnostics.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7825,3 +7825,17 @@ bool InvalidWeakAttributeUse::diagnoseAsError() {
78257825

78267826
return true;
78277827
}
7828+
7829+
bool SwiftToCPointerConversionInInvalidContext::diagnoseAsError() {
7830+
auto argInfo = getFunctionArgApplyInfo(getLocator());
7831+
if (!argInfo)
7832+
return false;
7833+
7834+
auto *callee = argInfo->getCallee();
7835+
auto argType = resolveType(argInfo->getArgType());
7836+
auto paramType = resolveType(argInfo->getParamType());
7837+
7838+
emitDiagnostic(diag::cannot_convert_argument_value_for_swift_func, argType,
7839+
paramType, callee->getDescriptiveKind(), callee->getName());
7840+
return true;
7841+
}

lib/Sema/CSDiagnostics.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,26 @@ class InvalidWeakAttributeUse final : public FailureDiagnostic {
26072607
bool diagnoseAsError() override;
26082608
};
26092609

2610+
/// Diagnose situations where Swift -> C pointer implicit conversion
2611+
/// is attempted on a Swift function instead of one imported from C header.
2612+
///
2613+
/// \code
2614+
/// func test(_: UnsafePointer<UInt8>) {}
2615+
///
2616+
/// func pass_ptr(ptr: UnsafeRawPointer) {
2617+
/// test(ptr) // Only okay if `test` was an imported C function.
2618+
/// }
2619+
/// \endcode
2620+
class SwiftToCPointerConversionInInvalidContext final
2621+
: public FailureDiagnostic {
2622+
public:
2623+
SwiftToCPointerConversionInInvalidContext(const Solution &solution,
2624+
ConstraintLocator *locator)
2625+
: FailureDiagnostic(solution, locator) {}
2626+
2627+
bool diagnoseAsError() override;
2628+
};
2629+
26102630
} // end namespace constraints
26112631
} // end namespace swift
26122632

lib/Sema/CSFix.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2003,7 +2003,8 @@ AllowNonOptionalWeak *AllowNonOptionalWeak::create(ConstraintSystem &cs,
20032003

20042004
bool AllowSwiftToCPointerConversion::diagnose(const Solution &solution,
20052005
bool asNote) const {
2006-
return false;
2006+
SwiftToCPointerConversionInInvalidContext failure(solution, getLocator());
2007+
return failure.diagnose(asNote);
20072008
}
20082009

20092010
AllowSwiftToCPointerConversion *

0 commit comments

Comments
 (0)