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