Skip to content

Commit fb2a6ee

Browse files
committed
LifetimeDependenceDiagnostics: fix source loc for implicit variables
Diagnostics on an indirect result ($return_value) did not report a source location. (cherry picked from commit c030b78)
1 parent b862300 commit fb2a6ee

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceDiagnostics.swift

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,12 @@ private struct DiagnoseDependence {
241241
onError()
242242

243243
// Identify the escaping variable.
244-
let escapingVar = LifetimeVariable(dependent: operand.value, context)
244+
let escapingVar = LifetimeVariable(usedBy: operand, context)
245245
if let varDecl = escapingVar.varDecl {
246246
// Use the variable location, not the access location.
247-
diagnose(varDecl.nameLoc, .lifetime_variable_outside_scope, escapingVar.name ?? "")
247+
// Variable names like $return_value and $implicit_value don't have source locations.
248+
let sourceLoc = varDecl.nameLoc ?? escapingVar.sourceLoc
249+
diagnose(sourceLoc, .lifetime_variable_outside_scope, escapingVar.name ?? "")
248250
} else if let sourceLoc = escapingVar.sourceLoc {
249251
diagnose(sourceLoc, .lifetime_value_outside_scope)
250252
} else {
@@ -267,7 +269,7 @@ private struct DiagnoseDependence {
267269

268270
// Identify the dependence scope. If no source location is found, bypass this diagnostic.
269271
func reportScope() {
270-
let parentVar = LifetimeVariable(dependent: dependence.parentValue, context)
272+
let parentVar = LifetimeVariable(definedBy: dependence.parentValue, context)
271273
// First check if the dependency is limited to an access scope. If the access has no source location then
272274
// fall-through to report possible dependence on an argument.
273275
if parentVar.isAccessScope, let accessLoc = parentVar.sourceLoc {
@@ -314,7 +316,22 @@ private struct LifetimeVariable {
314316
return varDecl?.userFacingName
315317
}
316318

317-
init(dependent value: Value, _ context: some Context) {
319+
init(usedBy operand: Operand, _ context: some Context) {
320+
self = .init(dependent: operand.value, context)
321+
// variable names like $return_value and $implicit_value don't have source locations.
322+
// For @out arguments, the operand's location is the best answer.
323+
// Otherwise, fall back to the function's location.
324+
self.sourceLoc = self.sourceLoc ?? operand.instruction.location.sourceLoc
325+
?? operand.instruction.parentFunction.location.sourceLoc
326+
}
327+
328+
init(definedBy value: Value, _ context: some Context) {
329+
self = .init(dependent: value, context)
330+
// Fall back to the function's location.
331+
self.sourceLoc = self.sourceLoc ?? value.parentFunction.location.sourceLoc
332+
}
333+
334+
private init(dependent value: Value, _ context: some Context) {
318335
guard let introducer = getFirstVariableIntroducer(of: value, context) else {
319336
return
320337
}

0 commit comments

Comments
 (0)