4 objc\[\d+\]: Deallocator object 0x[0-9a-fA-F]+ overreleased while already deallocating; break on objc_overrelease_during_dealloc_error to debug
7 no overrelease enforcement
17 @interface Deallocator : TestRoot @end
18 @implementation Deallocator
26 testprintf("Retain a lot during dealloc\n");
29 testassert([o retainCount] == rc);
32 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
33 } while (++rc < LOTS);
35 testassert([o retainCount] == rc);
39 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
43 testassert([o retainCount] == rc);
46 testprintf("Overrelease during dealloc\n");
48 // Not all architectures enforce this.
49 #if !SUPPORT_NONPOINTER_ISA
50 testwarn("no overrelease enforcement");
51 fprintf(stderr, "no overrelease enforcement\n");
63 Deallocator *o = [Deallocator new];
68 uintptr_t isa = *(uintptr_t *)o;
70 // Assume refcount in high bits.
71 LOTS = 1 << (4 + __builtin_clzll(isa));
72 testprintf("LOTS %zu via cntlzw\n", LOTS);
75 testprintf("LOTS %zu via guess\n", LOTS);
81 testprintf("Retain a lot\n");
84 testassert([o retainCount] == rc);
87 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
88 } while (++rc < LOTS);
90 testassert([o retainCount] == rc);
94 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
98 testassert([o retainCount] == rc);
101 testprintf("tryRetain a lot\n");
104 objc_storeWeak(&w, o);
108 testassert([o retainCount] == rc);
110 objc_loadWeakRetained(&w);
111 if (rc % 0x100000 == 0) testprintf("%zx/%zx ++\n", rc, LOTS);
112 } while (++rc < LOTS);
114 testassert([o retainCount] == rc);
118 if (rc % 0x100000 == 0) testprintf("%zx/%zx --\n", rc, LOTS);
122 testassert([o retainCount] == rc);
124 objc_storeWeak(&w, nil);
127 testprintf("dealloc\n");
129 testassert(TestRootDealloc == 0);
131 testassert(TestRootDealloc == 1);