1/*
2TEST_CRASHES
3TEST_RUN_OUTPUT
4objc1
5OK: badCache.m
6OR
7crash now
8objc\[\d+\]: Method cache corrupted.*
9objc\[\d+\]: .*
10objc\[\d+\]: .*
11objc\[\d+\]: .*
12objc\[\d+\]: .*
13objc\[\d+\]: Method cache corrupted\.
14CRASHED: SIG(ILL|TRAP)
15END
16*/
17
18
19#include "test.h"
20
21#if !__OBJC2__
22
23int main()
24{
25    fprintf(stderr, "objc1\n");
26    succeed(__FILE__);
27}
28
29#else
30
31#include "testroot.i"
32
33#if __LP64__
34typedef uint32_t mask_t;
35#else
36typedef uint16_t mask_t;
37#endif
38
39struct bucket_t {
40    void *sel;
41    void *imp;
42};
43
44struct cache_t {
45    struct bucket_t *buckets;
46    mask_t mask;
47    mask_t occupied;
48};
49
50struct class_t {
51    void *isa;
52    void *supercls;
53    struct cache_t cache;
54};
55
56@interface Subclass : TestRoot @end
57@implementation Subclass @end
58
59int main()
60{
61    Class cls = [TestRoot class];
62    id obj = [cls new];
63    [obj self];
64
65    // Test objc_msgSend.
66    struct cache_t *cache = &((__bridge struct class_t *)cls)->cache;
67    cache->mask = 0;
68    cache->buckets[0].sel = (void*)~0;
69    cache->buckets[0].imp = (void*)~0;
70    cache->buckets[1].sel = (void*)(uintptr_t)1;
71    cache->buckets[1].imp = (void*)cache->buckets;
72
73    fprintf(stderr, "crash now\n");
74    [obj self];
75
76    fail("should have crashed");
77}
78
79#endif
80