42
|
1 #include<stdio.h>
|
|
2 #include<assert.h>
|
|
3
|
|
4 #define dprint(f, args...) \
|
|
5 fprintf(stdout, "in %s\t: "f, __FUNCTION__, ## args)
|
|
6
|
|
7
|
|
8 /* for integer. */
|
|
9 int goodint = 33;
|
|
10 int badint = 0;
|
|
11 typedef void (*RETINT_FUNC)(int, void *);
|
|
12 void g_int(RETINT_FUNC func)
|
|
13 {
|
|
14 func(goodint, NULL);
|
|
15 }
|
|
16 int f_int()
|
|
17 {
|
|
18 void *ret;
|
|
19
|
|
20 ret = _CbC_return;
|
|
21
|
|
22 dprint("fp = %p\n", __builtin_frame_address(0));
|
|
23 dprint("__return_func = %p\n", ret);
|
|
24 g_int(ret);
|
|
25 //goto g(ret);
|
|
26
|
|
27 dprint("not good\n");
|
|
28 return badint;
|
|
29 }
|
|
30
|
|
31
|
|
32 /* for double. */
|
|
33 double gooddouble = 333.3;
|
|
34 double baddouble = 0.00;
|
|
35 typedef void (*RETDOUBLE_FUNC)(double, void *);
|
|
36 void g_double(RETDOUBLE_FUNC func)
|
|
37 {
|
|
38 func(gooddouble, NULL);
|
|
39 }
|
|
40 double f_double()
|
|
41 {
|
|
42 void *ret;
|
|
43 ret = _CbC_return;
|
|
44
|
|
45 dprint("fp = %p\n", __builtin_frame_address(0));
|
|
46 dprint("__return_func = %p\n", ret);
|
|
47 g_double(ret);
|
|
48 //goto g_double(ret);
|
|
49
|
|
50 dprint("not good\n");
|
|
51 return baddouble;
|
|
52 }
|
|
53
|
|
54 /* for float. */
|
|
55 float goodfloat = 33.3f;
|
|
56 float badfloat = 0.0f;
|
|
57 typedef void (*RETFLOAT_FUNC)(float, void *);
|
|
58 void g_float(RETFLOAT_FUNC func)
|
|
59 {
|
|
60 func(goodfloat, NULL);
|
|
61 }
|
|
62 float f_float()
|
|
63 {
|
|
64 void *ret;
|
|
65 ret = _CbC_return;
|
|
66
|
|
67 dprint("fp = %p\n", __builtin_frame_address(0));
|
|
68 dprint("__return_func = %p\n", ret);
|
|
69 g_float(ret);
|
|
70 //goto g_float(ret);
|
|
71
|
|
72 dprint("not good\n");
|
|
73 return badfloat;
|
|
74 }
|
|
75
|
|
76 /* for char. */
|
|
77 char goodchar = 33;
|
|
78 char badchar = 0;
|
|
79 typedef void (*RETCHAR_FUNC)(char, void *);
|
|
80 void g_char(RETCHAR_FUNC func)
|
|
81 {
|
|
82 func(goodchar, NULL);
|
|
83 }
|
|
84 char f_char()
|
|
85 {
|
|
86 void *ret;
|
|
87
|
|
88 ret = _CbC_return;
|
|
89
|
|
90 dprint("fp = %p\n", __builtin_frame_address(0));
|
|
91 dprint("__return_func = %p\n", ret);
|
|
92 g_char(ret);
|
|
93 //goto g(ret);
|
|
94
|
|
95 dprint("not good\n");
|
|
96 return badchar;
|
|
97 }
|
|
98
|
|
99
|
|
100 /* for struct. */
|
|
101 struct ifid {
|
|
102 int a;
|
|
103 float b;
|
|
104 int c[4];
|
|
105 double d;
|
|
106 };
|
|
107 struct ifid goodstruct = {33, 33.3, {4,4,4,4}, 333.333};
|
|
108 struct ifid badstruct = {0, 00.0, {0,0,0,0}, 0.0};
|
|
109 typedef void (*RETSTRUCT_FUNC)(struct ifid, void *);
|
|
110 void g_struct(RETSTRUCT_FUNC func)
|
|
111 {
|
|
112 func(goodstruct, NULL);
|
|
113 }
|
|
114 struct ifid f_struct()
|
|
115 {
|
|
116 void *ret;
|
|
117
|
|
118 ret = _CbC_return;
|
|
119
|
|
120 dprint("fp = %p\n", __builtin_frame_address(0));
|
|
121 dprint("__return_func = %p\n", ret);
|
|
122 g_struct(ret);
|
|
123 //goto g(ret);
|
|
124
|
|
125 dprint("not good\n");
|
|
126 return badstruct;
|
|
127 }
|
|
128
|
|
129 int main(int argc, char **argv)
|
|
130 {
|
|
131 void *bptr;
|
|
132 int rint;
|
|
133 float rfloat;
|
|
134 double rdouble;
|
|
135 char rchar;
|
|
136 struct ifid rstruct;
|
|
137
|
|
138 bptr = __builtin_frame_address(0);
|
|
139
|
|
140 dprint("before int: fp = %p\n", __builtin_frame_address(0));
|
|
141 rint = f_int();
|
|
142 dprint("f_int = %d, good=%d,bad=%d\n", rint,goodint,badint);
|
|
143
|
|
144 dprint("before float: fp = %p\n", __builtin_frame_address(0));
|
|
145 rfloat = f_float();
|
|
146 dprint("f_float = %3.3f, good=%3.3f,bad=%3.3f\n", rfloat,goodfloat,badfloat);
|
|
147 assert(bptr==__builtin_frame_address(0));
|
|
148
|
|
149 dprint("before double: fp = %p\n", __builtin_frame_address(0));
|
|
150 rdouble = f_double();
|
|
151 dprint("f_double = %3.3lf, good=%3.3lf,bad=%3.3lf\n", rdouble,gooddouble,baddouble);
|
|
152 assert(bptr==__builtin_frame_address(0));
|
|
153
|
|
154 dprint("before char: fp = %p\n", __builtin_frame_address(0));
|
|
155 rchar = f_char();
|
|
156 dprint("f_char = %d, good=%d,bad=%d\n", rchar,goodchar,badchar);
|
|
157 assert(bptr==__builtin_frame_address(0));
|
|
158
|
|
159 dprint("before struct: fp = %p\n", __builtin_frame_address(0));
|
|
160 rstruct = f_struct();
|
|
161 dprint( "return value = {\n"
|
|
162 " a = %d\n"
|
|
163 " b = %2.3f\n"
|
|
164 " c = { %d, %d, %d, %d }\n"
|
|
165 " d = %3.3f\n"
|
|
166 "}\n", rstruct.a, rstruct.b,
|
|
167 rstruct.c[0],rstruct.c[1],rstruct.c[2],rstruct.c[3], rstruct.d);
|
|
168
|
|
169
|
|
170
|
|
171 dprint("end: fp = %p\n", __builtin_frame_address(0));
|
|
172
|
|
173 if (bptr!=__builtin_frame_address(0)) {
|
|
174 dprint("CbC_return failure!\n");
|
|
175 return 1;
|
|
176 }
|
|
177 if ( rint!=goodint
|
|
178 || rchar!=goodchar
|
|
179 || (rfloat < goodfloat-0.01 || goodfloat+0.01 < rfloat)
|
|
180 || (rdouble < gooddouble-0.01 || gooddouble+0.01 < rdouble)
|
|
181 || rstruct.a!=goodstruct.a
|
|
182 || (rstruct.b < goodstruct.b-0.01 || goodstruct.b+0.01 < rstruct.b)
|
|
183 || (rstruct.d < goodstruct.d-0.01 || goodstruct.d+0.01 < rstruct.d)
|
|
184 || rstruct.c[0]!=goodstruct.c[0]
|
|
185 || rstruct.c[1]!=goodstruct.c[1]
|
|
186 || rstruct.c[2]!=goodstruct.c[2]
|
|
187 || rstruct.c[3]!=goodstruct.c[3] ) {
|
|
188 dprint("CbC_return failure!\n");
|
|
189 return 1;
|
|
190 }
|
|
191
|
|
192
|
|
193 dprint("CbC_return successful!\n");
|
|
194 return 0;
|
|
195 }
|
|
196
|