Skip to content

SIL memory lifetime failures on multi consume of bindings #83635

@jamieQ

Description

@jamieQ

Description

SIL verifier crashes on some patterns with repeated invalid use of the consume operator

Reproduction

func f() {
    var x = "a"
    let y = consume x
    let z = consume x
    print(y)
    print(z)
}

Stack dump

SIL memory lifetime failure in @$s6output1fyyF: memory is not initialized, but should be
memory location:   %0 = alloc_stack [var_decl] [moveable_value_debuginfo] $String, var, name "x", type $String // users: %64, %7, %8, %14
at instruction:   %15 = load [take] %14 : $*String                // user: %18

in function:
// f()
// Isolation: unspecified
sil hidden [ossa] @$s6output1fyyF : $@convention(thin) () -> () {
bb0:
  %0 = alloc_stack [var_decl] [moveable_value_debuginfo] $String, var, name "x", type $String // users: %64, %7, %8, %14
  %1 = string_literal utf8 "a"                    // user: %6
  %2 = integer_literal $Builtin.Word, 1           // user: %6
  %3 = integer_literal $Builtin.Int1, -1          // user: %6
  %4 = metatype $@thin String.Type                // user: %6
  // function_ref String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %5 = function_ref @$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %6
  %6 = apply %5(%1, %2, %3, %4) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %7
  store %6 to [init] %0                           // id: %7
  %8 = begin_access [modify] [static] %0          // users: %9, %11
  %9 = load [take] %8                             // user: %12
  debug_value [moveable_value_debuginfo] undef : $*String, var, name "x" // id: %10
  end_access %8                                   // id: %11
  %12 = move_value [var_decl] %9                  // users: %27, %63, %13
  debug_value %12, let, name "y"                  // id: %13
  %14 = begin_access [modify] [static] %0         // users: %15, %17
  %15 = load [take] %14                           // user: %18
  debug_value [moveable_value_debuginfo] undef : $*String, var, name "x" // id: %16
  end_access %14                                  // id: %17
  %18 = move_value [var_decl] %15                 // users: %48, %62, %19
  debug_value %18, let, name "z"                  // id: %19
  %20 = integer_literal $Builtin.Word, 1          // user: %22
  // function_ref _allocateUninitializedArray<A>(_:)
  %21 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %22
  %22 = apply %21<Any>(%20) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %23
  (%23, %24) = destructure_tuple %22              // users: %31, %25, %25
  %25 = mark_dependence %24 on %23                // user: %26
  %26 = pointer_to_address %25 to [strict] $*Any  // user: %28
  %27 = copy_value %12                            // user: %29
  %28 = init_existential_addr %26, $String        // user: %29
  store %27 to [init] %28                         // id: %29
  // function_ref _finalizeUninitializedArray<A>(_:)
  %30 = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0> // user: %31
  %31 = apply %30<Any>(%23) : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0> // users: %40, %37
  // function_ref default argument 1 of print(_:separator:terminator:)
  %32 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %33
  %33 = apply %32() : $@convention(thin) () -> @owned String // users: %39, %37
  // function_ref default argument 2 of print(_:separator:terminator:)
  %34 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %35
  %35 = apply %34() : $@convention(thin) () -> @owned String // users: %38, %37
  // function_ref print(_:separator:terminator:)
  %36 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %37
  %37 = apply %36(%31, %33, %35) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
  destroy_value %35                               // id: %38
  destroy_value %33                               // id: %39
  destroy_value %31                               // id: %40
  %41 = integer_literal $Builtin.Word, 1          // user: %43
  // function_ref _allocateUninitializedArray<A>(_:)
  %42 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %43
  %43 = apply %42<Any>(%41) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer) // user: %44
  (%44, %45) = destructure_tuple %43              // users: %52, %46, %46
  %46 = mark_dependence %45 on %44                // user: %47
  %47 = pointer_to_address %46 to [strict] $*Any  // user: %49
  %48 = copy_value %18                            // user: %50
  %49 = init_existential_addr %47, $String        // user: %50
  store %48 to [init] %49                         // id: %50
  // function_ref _finalizeUninitializedArray<A>(_:)
  %51 = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0> // user: %52
  %52 = apply %51<Any>(%44) : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned Array<τ_0_0> // users: %61, %58
  // function_ref default argument 1 of print(_:separator:terminator:)
  %53 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA0_ : $@convention(thin) () -> @owned String // user: %54
  %54 = apply %53() : $@convention(thin) () -> @owned String // users: %60, %58
  // function_ref default argument 2 of print(_:separator:terminator:)
  %55 = function_ref @$ss5print_9separator10terminatoryypd_S2StFfA1_ : $@convention(thin) () -> @owned String // user: %56
  %56 = apply %55() : $@convention(thin) () -> @owned String // users: %59, %58
  // function_ref print(_:separator:terminator:)
  %57 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %58
  %58 = apply %57(%52, %54, %56) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
  destroy_value %56                               // id: %59
  destroy_value %54                               // id: %60
  destroy_value %52                               // id: %61
  destroy_value %18                               // id: %62
  destroy_value %12                               // id: %63
  dealloc_stack %0                                // id: %64
  %65 = tuple ()                                  // user: %66
  return %65                                      // id: %66
} // end sil function '$s6output1fyyF'

Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend -frontend -emit-sil -primary-file <source> -target x86_64-unknown-linux-gnu -disable-objc-interop -no-color-diagnostics -Xcc -fno-color-diagnostics -g -debug-info-format=dwarf -dwarf-version=4 -debug-diagnostic-names -empty-abi-descriptor -enable-anonymous-context-mangled-names -file-compilation-dir /app -Xllvm --x86-asm-syntax=intel -no-auto-bridging-header-chaining -module-name output -in-process-plugin-server-path /opt/compiler-explorer/swift-dev-snapshot/usr/lib/swift/host/libSwiftInProcPluginServer.so -plugin-path /opt/compiler-explorer/swift-dev-snapshot/usr/lib/swift/host/plugins -plugin-path /opt/compiler-explorer/swift-dev-snapshot/usr/local/lib/swift/host/plugins -o /app/output.s
1.	Swift version 6.2-dev (LLVM cf66110ca9e9508, Swift 838cb7a91b98fb5)
2.	Compiling with effective version 5.10
3.	While verifying SIL function "@$s6output1fyyF".
 for 'f()' (at <source>:35:1)
 #0 0x00005d2686da5a68 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x8bf2a68)
 #1 0x00005d2686da358e llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x8bf058e)
 #2 0x00005d2686da6101 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007011b9242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007011b92969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #5 0x00007011b9242476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #6 0x00007011b92287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #7 0x00005d2680591123 (anonymous namespace)::MemoryLifetimeVerifier::reportError(llvm::Twine const&, int, swift::SILInstruction*) MemoryLifetimeVerifier.cpp:0:0
 #8 0x00005d268059056e (anonymous namespace)::MemoryLifetimeVerifier::require(llvm::SmallBitVector const&, llvm::Twine const&, swift::SILInstruction*, bool) MemoryLifetimeVerifier.cpp:0:0
 #9 0x00005d2680590a0a (anonymous namespace)::MemoryLifetimeVerifier::requireBitsSet(llvm::SmallBitVector const&, swift::SILValue, swift::SILInstruction*) MemoryLifetimeVerifier.cpp:0:0
#10 0x00005d268058ead7 (anonymous namespace)::MemoryLifetimeVerifier::checkBlock(swift::SILBasicBlock*, llvm::SmallBitVector&) MemoryLifetimeVerifier.cpp:0:0
#11 0x00005d268059175a std::_Function_handler<void (swift::SILBasicBlock*), (anonymous namespace)::MemoryLifetimeVerifier::verify()::$_0>::_M_invoke(std::_Any_data const&, swift::SILBasicBlock*&&) MemoryLifetimeVerifier.cpp:0:0
#12 0x00005d2680592bb2 swift::MemoryLocations::handleSingleBlockLocations(std::function<void (swift::SILBasicBlock*)>) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x23dfbb2)
#13 0x00005d268058dee0 (anonymous namespace)::MemoryLifetimeVerifier::verify() MemoryLifetimeVerifier.cpp:0:0
#14 0x00005d268058c6e7 swift::SILFunction::verifyMemoryLifetime(swift::CalleeCache*) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x23d96e7)
#15 0x00005d268051951e (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) SILVerifier.cpp:0:0
#16 0x00005d2680510bc8 swift::SILFunction::verify(swift::CalleeCache*, bool, bool, bool) const (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x235dbc8)
#17 0x00005d2680514938 swift::SILModule::verify(swift::CalleeCache*, bool, bool) const (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x2361938)
#18 0x00005d26805147ef swift::SILModule::verify(bool, bool) const (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x23617ef)
#19 0x00005d267f4681c4 swift::CompilerInstance::performSILProcessing(swift::SILModule*) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0x12b51c4)
#20 0x00005d267f0fb177 performCompileStepsPostSILGen(swift::CompilerInstance&, std::unique_ptr<swift::SILModule, std::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) FrontendTool.cpp:0:0
#21 0x00005d267f0fa0ce swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0xf470ce)
#22 0x00005d267f10bcca withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) FrontendTool.cpp:0:0
#23 0x00005d267f0fd05e performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) FrontendTool.cpp:0:0
#24 0x00005d267f0fc0f8 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0xf490f8)
#25 0x00005d267ee7acfb swift::mainEntry(int, char const**) (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0xcc7cfb)
#26 0x00007011b9229d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#27 0x00007011b9229e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#28 0x00005d267ee79cf5 _start (/opt/compiler-explorer/swift-dev-snapshot/usr/bin/swift-frontend+0xcc6cf5)

*** Signal 11: Backtracing from 0x7011b9228898... done ***

*** Program crashed: Bad pointer dereference at 0x0000000000000000 ***

Platform: x86_64 Linux (Ubuntu 22.04.5 LTS)

Thread 0 "swift-frontend" crashed:

  0  0x00007011b9228898 <unknown> in libc.so.6
...


Registers:

rax 0x0000000000000000  0
rdx 0x00007011b9862880  80 28 86 b9 11 70 00 00 a0 32 86 b9 11 70 00 00  ·(·¹·p·· 2·¹·p··
rcx 0x00007011b92969fc  41 89 c5 41 f7 dd 3d 00 f0 ff ff b8 00 00 00 00  A·ÅA÷Ý=·ðÿÿ¸····
rbx 0x0000000000000006  6
rsi 0x0000000000000001  1
rdi 0x0000000000000001  1
rbp 0x00007011b941be90  01 00 00 00 01 00 00 00 80 28 86 b9 11 70 00 00  ·········(·¹·p··
rsp 0x00007fff8638eac0  20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ···············
 r8 0x0000000000000000  0
 r9 0x0000000000000000  0
r10 0x0000000000000008  8
r11 0x0000000000000246  582
r12 0x00005d268b750918  b8 72 61 88 26 5d 00 00 00 00 00 00 00 00 00 00  ¸ra·&]··········
r13 0x000000000000000e  14
r14 0x00005d26bba019f0  50 44 97 bb 26 5d 00 00 f0 ae 95 bb 26 5d 00 00  PD·»&]··ð®·»&]··
r15 0x00005d268b750918  b8 72 61 88 26 5d 00 00 00 00 00 00 00 00 00 00  ¸ra·&]··········
rip 0x00007011b9228898  f4 83 3d 00 36 1f 00 05 75 14 c7 05 f4 35 1f 00  ô·=·6···u·Ç·ô5··

rflags 0x0000000000010246  ZF PF

cs 0x0033  fs 0x0000  gs 0x0000


Images (25 omitted):

0x00007011b9200000–0x00007011b93bc341 cd410b710f0f094c6832edd95931006d883af48e libc.so.6 /lib/x86_64-linux-gnu/libc.so.6

Backtrace took 0.00s

Program terminated with signal: SIGSEGV
Compiler returned: 139

Expected behavior

invalid use of the consume operator should be diagnosed rather than crashing in an asserts build

Environment

Swift version 6.2-dev (LLVM cf66110ca9e9508, Swift 838cb7a)
Target: x86_64-unknown-linux-gnu

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions