@@ -312,6 +312,7 @@ extension AccessBase {
312312struct AddressInitializationWalker : AddressDefUseWalker , AddressUseVisitor {
313313 let baseAddress : Value
314314 let requireFullyAssigned : IsFullyAssigned
315+ let onRead : WalkResult
315316 let context : any Context
316317
317318 var walkDownCache = WalkerCache < SmallProjectionPath > ( )
@@ -320,20 +321,21 @@ struct AddressInitializationWalker: AddressDefUseWalker, AddressUseVisitor {
320321 var initializer : AccessBase . Initializer ?
321322
322323 static func findSingleInitializer( ofAddress baseAddr: Value , requireFullyAssigned: IsFullyAssigned ,
323- _ context: some Context )
324+ allowRead : Bool = true , _ context: some Context )
324325 -> AccessBase . Initializer ? {
325326
326- var walker = AddressInitializationWalker ( baseAddress: baseAddr, requireFullyAssigned, context)
327+ var walker = AddressInitializationWalker ( baseAddress: baseAddr, requireFullyAssigned, allowRead : allowRead , context)
327328 if walker. walkDownUses ( ofAddress: baseAddr, path: SmallProjectionPath ( ) ) == . abortWalk {
328329 return nil
329330 }
330331 return walker. initializer
331332 }
332333
333- private init ( baseAddress: Value , _ requireFullyAssigned: IsFullyAssigned , _ context: some Context ) {
334+ private init ( baseAddress: Value , _ requireFullyAssigned: IsFullyAssigned , allowRead : Bool , _ context: some Context ) {
334335 assert ( requireFullyAssigned != . no)
335336 self . baseAddress = baseAddress
336337 self . requireFullyAssigned = requireFullyAssigned
338+ self . onRead = allowRead ? . continueWalk : . abortWalk
337339 self . context = context
338340 if let arg = baseAddress as? FunctionArgument {
339341 assert ( !arg. convention. isIndirectIn, " @in arguments cannot be initialized " )
@@ -391,15 +393,21 @@ extension AddressInitializationWalker {
391393 // FIXME: check mayWriteToMemory but ignore non-stores. Currently,
392394 // stores should all be checked my isAddressInitialization, but
393395 // this is not robust.
394- return . continueWalk
396+ return onRead
395397 }
396398
397399 mutating func appliedAddressUse( of operand: Operand , by apply: FullApplySite )
398400 -> WalkResult {
399401 switch apply. fullyAssigns ( operand: operand) {
400402 case . no:
403+ if onRead == . abortWalk {
404+ return . abortWalk
405+ }
401406 break
402407 case . lifetime:
408+ if onRead == . abortWalk {
409+ return . abortWalk
410+ }
403411 if requireFullyAssigned == . value {
404412 break
405413 }
@@ -415,26 +423,26 @@ extension AddressInitializationWalker {
415423
416424 mutating func loadedAddressUse( of operand: Operand , intoValue value: Value )
417425 -> WalkResult {
418- return . continueWalk
426+ return onRead
419427 }
420428
421429 mutating func loadedAddressUse( of operand: Operand , intoAddress address: Operand )
422430 -> WalkResult {
423- return . continueWalk
431+ return onRead
424432 }
425433
426434 mutating func yieldedAddressUse( of operand: Operand ) -> WalkResult {
427435 // An inout yield is a partial write. Initialization via coroutine is not supported, so we assume a prior
428436 // initialization must dominate the yield.
429- return . continueWalk
437+ return onRead
430438 }
431439
432440 mutating func dependentAddressUse( of operand: Operand , dependentValue value: Value ) -> WalkResult {
433- return . continueWalk
441+ return onRead
434442 }
435443
436444 mutating func dependentAddressUse( of operand: Operand , dependentAddress address: Value ) -> WalkResult {
437- return . continueWalk
445+ return onRead
438446 }
439447
440448 mutating func escapingAddressUse( of operand: Operand ) -> WalkResult {
0 commit comments