1 /* { dg-do run } */
2 /* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
3 /* { dg-options "-fsanitize=undefined" } */
4
5 /* Sanity-test -fsanitize=object-size. We use -fsanitize=undefined option
6 to check that this feature doesn't clash with -fsanitize=bounds et al. */
7
8 #define N 20
9
10 __attribute__((noinline, noclone)) void
f1(int i)11 f1 (int i)
12 {
13 volatile int j;
14 char *p, *orig;
15 orig = p = (char *) __builtin_calloc (N, 1);
16 j = *(p + i);
17 j = p[i];
18 p++;
19 j = p[i - 1];
20 j = *(p + i - 1);
21 __builtin_free (orig);
22 }
23
24 /* { dg-output "load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
25 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
26 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
27 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
28 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
29 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
30 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
31 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
32 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
33 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
34 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
35 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
36 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
37 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
38 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
39 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
40
41 __attribute__((noinline, noclone)) void
f2(int i)42 f2 (int i)
43 {
44 volatile int j;
45 char a[N];
46 __builtin_memset (a, 0, N);
47 j = *(a + i);
48 char *p = a;
49 j = *(p + i);
50 j = p[i];
51 p += 10;
52 j = *(p + i - 10);
53 j = p[i - 10];
54 }
55
56 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
57 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
58 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
59 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
60 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
61 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
62 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
63 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
64 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
65 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
66 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
67 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
68 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
69 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
70 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
71 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
72
73 __attribute__((noinline, noclone)) void
f3(int i)74 f3 (int i)
75 {
76 volatile int j;
77 int *p = (int *) __builtin_calloc (N, sizeof (*p));
78 int *o = &p[i];
79 j = *o;
80 j = o[0];
81 __builtin_free (p);
82 }
83
84 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
85 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
86 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
87 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
88 /* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
89 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
90 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
91 /* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
92
93 __attribute__((noinline, noclone)) void
f4(void)94 f4 (void)
95 {
96 /* The second argument to __builtin_calloc is intentional. */
97 int *p = (int *) __builtin_calloc (3, 1);
98 *p = 42;
99 __builtin_free (p);
100 }
101
102 /* { dg-output "\[^\n\r]*store to address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */
103 /* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */
104 /* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */
105 /* { dg-output "\[^\n\r]*\\^" } */
106
107 __attribute__((noinline, noclone)) void
f5(int * p)108 f5 (int *p)
109 {
110 /* This is not instrumented. But don't ICE, etc. */
111 volatile int i = p[N];
112 }
113
114 int
main()115 main ()
116 {
117 f1 (N);
118 f2 (N);
119 f3 (N);
120 f4 ();
121 int *p = (int *) __builtin_calloc (N, sizeof (*p));
122 f5 (p);
123 __builtin_free (p);
124 return 0;
125 }
126