diff --git a/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp b/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp index eee7080c649c5..633fee2330050 100644 --- a/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp +++ b/lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp @@ -208,7 +208,7 @@ bool PerformanceDiagnostics::visitFunction(SILFunction *function, if (auto *fri = dyn_cast(bi->getArguments()[1])) { if (visitCallee(bi, fri->getReferencedFunction(), perfConstr, parentLoc)) return true; - } else { + } else if (perfConstr != PerformanceConstraints::ManualOwnership) { LocWithParent loc(inst.getLoc().getSourceLoc(), parentLoc); diagnose(loc, diag::performance_unknown_callees); return true; @@ -250,6 +250,12 @@ bool PerformanceDiagnostics::checkClosureValue(SILValue closure, SILInstruction *callInst, PerformanceConstraints perfConstr, LocWithParent *parentLoc) { + // Closures within a function are pre-annotated with [manual_ownership] + // within SILGen, if they're visible to users for annotation at all. + // So no recursive closure checking is needed here. + if (perfConstr == PerformanceConstraints::ManualOwnership) + return false; + // Walk through the definition of the closure until we find the "underlying" // function_ref instruction. while (!isa(closure)) { diff --git a/test/SIL/manual_ownership.swift b/test/SIL/manual_ownership.swift index cf069b49c0b70..e4180306bbd14 100644 --- a/test/SIL/manual_ownership.swift +++ b/test/SIL/manual_ownership.swift @@ -144,6 +144,14 @@ func basic_methods_consuming_fixed(_ t1: Triangle) { (copy t2).consuming() // FIXME: why is this not propagated? } +open class OpenClass { + open func classMethod() {} +} +@_manualOwnership +func callOpenMethod(_ c: OpenClass) { + return c.classMethod() +} + @_manualOwnership @discardableResult func consumingFunc(_ t0: consuming Triangle) -> Bool { return false }