]>
Commit | Line | Data |
---|---|---|
885824d3 | 1 | # include <stdlib.h> |
2 | ||
3 | typedef int ***(**f1)(void); /* f1 is a pointer to a function taking no args, returning int *** */ | |
4 | typedef int (*f2)(void); /* f2 is a function taking no args, returning an int */ | |
5 | typedef int **(*f3)(void); /* f3 is a function taking no args, returning a pointer to a pointer to an int */ | |
6 | typedef int *(*f4[])(void); /* f4 is an array of functions taking no args, returning pointers to ints */ | |
7 | typedef int *(f5)(int); /* f5 is a function taking an int, returning a pointer to an int */ | |
8 | typedef int *(*f6(int,int))(int); /* f6 is a function taking 2 int args, returns a function taking an int and | |
9 | returning a pointer to an int */ | |
10 | /* gcc complains if the pointer before f6 is omitted. why? */ | |
11 | /*@-paramuse*/ | |
12 | int func1(void) { return 3;} | |
13 | int *func2(void) { return (int *)malloc(sizeof(int));} | |
14 | /* 1. Possibly null storage returned as non-null | |
15 | ** 2. Returned storage not completely defined (allocated only) | |
16 | */ | |
17 | /*@null@*/ int **func3(void) { return (int **)0;} | |
18 | /*@null@*/ int ***func4(void) { return (int ***)0;} | |
19 | int *func5(int i) { return &i; } /* 3. Immediate address &i returned as only: &i */ | |
20 | /* 4. Return value references stack-allocated storage i: &i */ | |
21 | int *(*func6(int x, int y))(int) { return func5; } | |
22 | ||
23 | int main (void) | |
24 | { | |
25 | f1 t1; f2 t2; f3 t3; f3 *t3p; f4 *t4; f6 t6; | |
26 | int x, *xp, ***xppp; | |
27 | ||
28 | t1 = func1; /* 5. Assignment of int () * to f1 */ | |
29 | t1 = func4; /* 6. Assignment of int * * * () * to f1 */ | |
30 | *t1 = func4; | |
31 | ||
32 | t2 = func1; | |
33 | t2 = func2; /* 7. Assignment of int * () * to f2 */ | |
34 | ||
35 | t3 = func3; | |
36 | t3p = func3; /* 8. Assignment of int * * () * to f3 *: t3p = func3 */ | |
37 | ||
38 | t4 = func2; /* 9. Assignment of int * () * to f4 *: t4 = func2 */ | |
39 | ||
40 | xppp = (*t1)(); | |
41 | x = (t1)(); /* 10. Call to non-function (type f1): (t1) */ | |
42 | x = (t2)(); | |
43 | xp = (*t1)(); /* 11. Assignment of int * * * to int *: xp = (*t1)() */ | |
44 | xp = (t4)(); /* 12. Call to non-function (type f4 *): (t4) */ | |
45 | ||
46 | t6 = func1; /* 13. Assignment of int () * to f6: t6 = func1 */ | |
47 | t6 = func6; /* funcpointer.c:43: invalid lvalue in assignment */ | |
48 | (void) (t6)(); /* 14. Function (t6) called with 0 args, expects 2 */ | |
49 | (void) (t6)(3); /* 15. Function (t6) called with 1 args, expects 2 */ | |
50 | (void) ((t6)(3))(); /* 16. Function (t6) called with 1 args, expects 2 */ | |
51 | /* 17. Function ((t6)(3)) called with 0 args, expects 1 */ | |
52 | (void) ((t6)(5, 3))(7); | |
53 | return 3; | |
54 | } | |
55 | ||
56 | /* function pointer bug, provided by Marc Espie */ | |
57 | ||
58 | typedef void (*func)(void); | |
59 | ||
60 | void (*f[10])(void); | |
61 | func g[10]; | |
62 | ||
63 | void a(void) | |
64 | { | |
65 | } | |
66 | ||
67 | void b(void) | |
68 | { | |
69 | func *h; | |
70 | ||
71 | h = f; | |
72 | f[0] = a; | |
73 | g[0] = a; | |
74 | f[1] = g[0]; | |
75 | h[2] = a; | |
76 | } | |
77 | ||
78 | ||
79 | ||
80 |