Skip to content

deferred context cleanup is handled too early #6032

@SOBEX

Description

@SOBEX

Context

having multiple context changes with deferred cleanup seems to misbehave on a conditional early return

package eager_context_reset

import "core:log"
import "core:mem"

main::proc(){
   original_allocator:=context.allocator
   tracking_allocator:mem.Tracking_Allocator
   mem.tracking_allocator_init(&tracking_allocator,original_allocator)
   context.allocator=mem.tracking_allocator(&tracking_allocator)
   defer{
      context.allocator=original_allocator
      mem.tracking_allocator_destroy(&tracking_allocator)
   }

   original_logger:=context.logger
   console_logger:=log.create_console_logger(.Info,{.Level,.Date,.Time})
   context.logger=console_logger
   defer{
      context.logger=original_logger
      log.destroy_console_logger(console_logger)
   }

   log.info("Trying...")
   if !try_config(){
      log.fatal("Error")
      return
   }
   log.info("Successful")
   fmt.println("logger is nil?",context.logger.procedure==log.nil_logger_proc)
}

try_config::proc()->(ok:bool){
   return true
}

i have tried it both on decembers release and the following nightly build from the 17th

        Odin:    dev-2025-12-nightly:ac61f08
        OS:      Windows 11 Professional (version: 24H2), build 26100.4946
        CPU:     Intel(R) Core(TM) Ultra 9 185H
        RAM:     32295 MiB
        Backend: LLVM 20.1.0

Expected Behavior

logger stays set correctly regardless of whether the if branch is taken

[INFO ] --- [*] Trying...
[INFO ] --- [*] Successful
logger is nil? false

Current Behavior

the second context change gets undone past the if !ok {return} block

[INFO ] --- [*] Trying...
logger is nil? true

Failure Information (for bugs)

in my example i expect to see the successful log however at that point the logger is reset to the nil logger
once execution jumps back to the deferred logger cleanup at line 20 the logger is correctly set to the console logger right before unsetting it
the tracking allocator does stay set past the if block and is correctly cleaned up in the defer

Steps to Reproduce

run snippet from context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions