1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5
6 /*
7 * objectassign.c
8 * testObjects
9 *
10 * Created by Blaine Garst on 10/28/08.
11 *
12 * This just tests that the compiler is issuing the proper helper routines
13 * CONFIG C rdar://6175959
14 */
15
16
17 #include <stdio.h>
18 #include <Block_private.h>
19
20
21 int AssignCalled = 0;
22 int DisposeCalled = 0;
23
24 // local copy instead of libSystem.B.dylib copy
_Block_object_assign(void * destAddr,const void * object,const int isWeak)25 void _Block_object_assign(void *destAddr, const void *object, const int isWeak) {
26 //printf("_Block_object_assign(%p, %p, %d) called\n", destAddr, object, isWeak);
27 AssignCalled = 1;
28 }
29
_Block_object_dispose(const void * object,const int isWeak)30 void _Block_object_dispose(const void *object, const int isWeak) {
31 //printf("_Block_object_dispose(%p, %d) called\n", object, isWeak);
32 DisposeCalled = 1;
33 }
34
35 struct MyStruct {
36 long isa;
37 long field;
38 };
39
40 typedef struct MyStruct *__attribute__((NSObject)) MyStruct_t;
41
main(int argc,char * argv[])42 int main(int argc, char *argv[]) {
43 if (__APPLE_CC__ < 5627) {
44 printf("need compiler version %d, have %d\n", 5627, __APPLE_CC__);
45 return 0;
46 }
47 // create a block
48 struct MyStruct X;
49 MyStruct_t xp = (MyStruct_t)&X;
50 xp->field = 10;
51 void (^myBlock)(void) = ^{ printf("field is %ld\n", xp->field); };
52 // should be a copy helper generated with a calls to above routines
53 // Lets find out!
54 struct Block_layout *bl = (struct Block_layout *)(void *)myBlock;
55 if ((bl->flags & BLOCK_HAS_COPY_DISPOSE) != BLOCK_HAS_COPY_DISPOSE) {
56 printf("no copy dispose!!!!\n");
57 return 1;
58 }
59 // call helper routines directly. These will, in turn, we hope, call the stubs above
60 long destBuffer[256];
61 //printf("destbuffer is at %p, block at %p\n", destBuffer, (void *)bl);
62 //printf("dump is %s\n", _Block_dump(myBlock));
63 bl->descriptor->copy(destBuffer, bl);
64 bl->descriptor->dispose(bl);
65 if (AssignCalled == 0) {
66 printf("did not call assign helper!\n");
67 return 1;
68 }
69 if (DisposeCalled == 0) {
70 printf("did not call dispose helper\n");
71 return 1;
72 }
73 printf("%s: Success!\n", argv[0]);
74 return 0;
75 }
76