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
11f1 (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
42f2 (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
74f3 (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
94f4 (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]*\\^\[^\n\r]*(\n|\r\n|\r)" } */
106
107__attribute__((noinline, noclone)) void
108f5 (int *p)
109{
110  /* This is not instrumented.  But don't ICE, etc.  */
111  volatile int i = p[N];
112}
113
114int
115main ()
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