summary refs log tree commit diff stats
path: root/tests/ccgbugs/tobjconstr_outoforder.nim
blob: 846a753d5e6fa0732407b6bd915edfaa45034c62 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
discard """
  output: '''(left: 1, up: 0, right: 2, down: 0)
(left: 0, up: 1, right: 0, down: 2)
@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)]
@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)]
true'''
"""

# bug #5339
type
  Dirs = object
    left: int
    up: int
    right: int
    down: int

let
  a = Dirs(
    left: 1,
    right: 2,
  )
  b = Dirs(
    up: 1,
    down: 2,
  )
  works = @[
    a,
    b,
  ]
  fails = @[
    Dirs(left: 1, right: 2),
    Dirs(up: 1, down: 2),
  ]
echo a
echo b
echo works
echo fails
echo works == fails
n> not emulatedThreadVars: type ThreadType {.pure.} = enum None = 0, NimThread = 1, ForeignThread = 2 var threadType {.rtlThreadVar.}: ThreadType threadType = ThreadType.NimThread when defined(gcDestructors): proc deallocThreadStorage(p: pointer) = c_free(p) else: template deallocThreadStorage(p: pointer) = deallocShared(p) template afterThreadRuns() = for i in countdown(nimThreadDestructionHandlers.len-1, 0): nimThreadDestructionHandlers[i]() proc onThreadDestruction*(handler: proc () {.closure, gcsafe, raises: [].}) = ## Registers a *thread local* handler that is called at the thread's ## destruction. ## ## A thread is destructed when the `.thread` proc returns ## normally or when it raises an exception. Note that unhandled exceptions ## in a thread nevertheless cause the whole process to die. nimThreadDestructionHandlers.add handler when defined(boehmgc): type GCStackBaseProc = proc(sb: pointer, t: pointer) {.noconv.} proc boehmGC_call_with_stack_base(sbp: GCStackBaseProc, p: pointer) {.importc: "GC_call_with_stack_base", boehmGC.} proc boehmGC_register_my_thread(sb: pointer) {.importc: "GC_register_my_thread", boehmGC.} proc boehmGC_unregister_my_thread() {.importc: "GC_unregister_my_thread", boehmGC.} proc threadProcWrapDispatch[TArg](sb: pointer, thrd: pointer) {.noconv, raises: [].} = boehmGC_register_my_thread(sb) try: let thrd = cast[ptr Thread[TArg]](thrd) when TArg is void: thrd.dataFn() else: thrd.dataFn(thrd.data) except: threadTrouble() finally: afterThreadRuns() boehmGC_unregister_my_thread() else: proc threadProcWrapDispatch[TArg](thrd: ptr Thread[TArg]) {.raises: [].} = try: when TArg is void: thrd.dataFn() else: when defined(nimV2): thrd.dataFn(thrd.data) else: var x: TArg deepCopy(x, thrd.data) thrd.dataFn(x) except: threadTrouble() finally: afterThreadRuns() when hasAllocStack: deallocThreadStorage(thrd.rawStack) proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) {.raises: [].} = when defined(boehmgc): boehmGC_call_with_stack_base(threadProcWrapDispatch[TArg], thrd) elif not defined(nogc) and not defined(gogc) and not defined(gcRegions) and not usesDestructors: var p {.volatile.}: pointer # init the GC for refc/markandsweep nimGC_setStackBottom(addr(p)) when declared(initGC): initGC() when declared(threadType): threadType = ThreadType.NimThread threadProcWrapDispatch[TArg](thrd) when declared(deallocOsPages): deallocOsPages() else: threadProcWrapDispatch(thrd) template nimThreadProcWrapperBody*(closure: untyped): untyped = var thrd = cast[ptr Thread[TArg]](closure) var core = thrd.core when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core) threadProcWrapStackFrame(thrd) # Since an unhandled exception terminates the whole process (!), there is # no need for a ``try finally`` here, nor would it be correct: The current # exception is tried to be re-raised by the code-gen after the ``finally``! # However this is doomed to fail, because we already unmapped every heap # page! # mark as not running anymore: thrd.core = nil thrd.dataFn = nil deallocThreadStorage(cast[pointer](core))