]> git.saurik.com Git - apple/objc4.git/blob - test/badCache.m
objc4-756.2.tar.gz
[apple/objc4.git] / test / badCache.m
1 /*
2 TEST_CRASHES
3 TEST_RUN_OUTPUT
4 arm
5 OK: badCache.m
6 OR
7 crash now
8 objc\[\d+\]: Method cache corrupted.*
9 objc\[\d+\]: .*
10 objc\[\d+\]: .*
11 objc\[\d+\]: .*
12 objc\[\d+\]: .*
13 objc\[\d+\]: Method cache corrupted.*
14 objc\[\d+\]: HALTED
15 END
16 */
17
18
19 #include "test.h"
20
21 // Test objc_msgSend's detection of infinite loops during cache scan.
22
23 #if __arm__
24
25 int main()
26 {
27 testwarn("objc_msgSend on arm doesn't detect infinite loops");
28 fprintf(stderr, "arm\n");
29 succeed(__FILE__);
30 }
31
32 #else
33
34 #include "testroot.i"
35
36 #if __LP64__
37 typedef uint32_t mask_t;
38 #else
39 typedef uint16_t mask_t;
40 #endif
41
42 struct bucket_t {
43 uintptr_t sel;
44 uintptr_t imp;
45 };
46
47 struct cache_t {
48 struct bucket_t *buckets;
49 mask_t mask;
50 mask_t occupied;
51 };
52
53 struct class_t {
54 void *isa;
55 void *supercls;
56 struct cache_t cache;
57 };
58
59 @interface Subclass : TestRoot @end
60 @implementation Subclass @end
61
62 int main()
63 {
64 Class cls = [TestRoot class];
65 id obj = [cls new];
66 [obj self];
67
68 struct cache_t *cache = &((__bridge struct class_t *)cls)->cache;
69
70 # define COUNT 4
71 struct bucket_t *buckets = (struct bucket_t *)calloc(sizeof(struct bucket_t), COUNT+1);
72 for (int i = 0; i < COUNT; i++) {
73 buckets[i].sel = ~0;
74 buckets[i].imp = ~0;
75 }
76 buckets[COUNT].sel = 1;
77 buckets[COUNT].imp = (uintptr_t)buckets;
78
79 cache->mask = COUNT-1;
80 cache->occupied = 0;
81 cache->buckets = buckets;
82
83 fprintf(stderr, "crash now\n");
84 [obj self];
85
86 fail("should have crashed");
87 }
88
89 #endif