aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.c-torture/compile/pr83510.c
blob: 7f222fa9bdb5b803fa10aefe72bc6db6425e0119 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* Various examples of safe array access for which -Warray-bounds
   shouldn't issue a warning at any optimization level
   (PR tree-optimization/83510).  */

/* { dg-options "-Warray-bounds" } */

/*  This test is XFAILed because thread1 threads a switch statement
    such that the various cases have been split into different
    independent blocks.  One of these blocks exposes an arr[i_27]
    which is later propagated by VRP to be arr[10].  This is an
    invalid access, but the array bounds code doesn't know it is an
    unreachable path.

    However, it is not until dom2 that we "know" that the value of the
    switch index is such that the path to arr[10] is unreachable.  For
    that matter, it is not until dom3 that we remove the unreachable
    path.


    See:
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83510
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83312

    It's not until here that ranger "knows" that the path is
    unreachable:

    thread1
    vrp1		<-- array bounds checking
    dce2
    stdarg
    cdce
    cselim
    copyprop
    ifcombine
    mergephi3		<-- too late
*/

extern int get_flag (void);

unsigned int arr[10];

struct xyz {
  unsigned int a0;
};

extern void wfm(struct xyz *, int, unsigned int);

static unsigned int f(struct xyz * ctx, unsigned int number)
{
  switch (number) {
  case 0x9:
    return ctx->a0;
  case 0xA: case 0xB:
  case 0xC: case 0xD: case 0xE: case 0xF:
  case 0x10: case 0x11: case 0x12: case 0x13:
    return arr[number - 0xa];
  }
  return 0;
}

int g(struct xyz * ctx) {
  int i;

  for (i = 0; i < 10; i++) {
    wfm(ctx, i, f(ctx, i));
  }

  return 0;
}

int g_signed(struct xyz * ctx) {
  int i;

  for (i = 0; i < 10; i++) {
    wfm(ctx, i, f(ctx, i));
  }

  return 0;
}

void test_2 (struct xyz * ctx)
{
  int i;

  for (i = 0; i < 10; i++) {
    if (get_flag ())
      wfm(ctx, i, f(ctx, i));
  }
}

void test_3 (struct xyz * ctx)
{
  unsigned int i;
  
  for (i = 0; i < 10; i++) {
    switch (i) {
    case 0x9:
      wfm(ctx, i, ctx->a0);
      break;
    case 0xA: case 0xB:
    case 0xC: case 0xD: case 0xE: case 0xF:
    case 0x10: case 0x11: case 0x12: case 0x13:
      if (get_flag ())
	wfm(ctx, i, arr[i - 0xa]);
      break;
    }
  }
}

void test_3_signed (struct xyz * ctx)
{
  int i;
  
  for (i = 0; i < 10; i++) {
    switch (i) {
    case 0x9:
      wfm(ctx, i, ctx->a0);
      break;
    case 0xA: case 0xB:
    case 0xC: case 0xD: case 0xE: case 0xF:
    case 0x10: case 0x11: case 0x12: case 0x13:
      if (get_flag ())
	wfm(ctx, i, arr[i]);
      break;
    }
  }
}

void test_4 (struct xyz * ctx)
{
  unsigned int i, j;
  
  for (i = 0; i < 10; i++) {
    switch (i) {
    case 0x9:
      wfm(ctx, i, ctx->a0);
      break;
    case 0xA: case 0xB:
    case 0xC: case 0xD: case 0xE: case 0xF:
    case 0x10: case 0x11: case 0x12: case 0x13:
      for (j = 0; j < 5; j++)
	wfm(ctx, i, arr[i - 0xa]);
      break;
    }
  }
}
void test_4_signed (struct xyz * ctx)
{
  int i, j;
  
  for (i = 0; i < 10; i++) {
    switch (i) {
    case 0x9:
      wfm(ctx, i, ctx->a0);
      break;
    case 0xA: case 0xB:
    case 0xC: case 0xD: case 0xE: case 0xF:
    case 0x10: case 0x11: case 0x12: case 0x13:
      for (j = 0; j < 5; j++)
	wfm(ctx, i, arr[i]);
      break;
    }
  }
}

void test_5 (struct xyz * ctx)
{
  unsigned int i;
  for (i = 10; i < 20; i++) {
    wfm(ctx, i, arr[i - 10]);
  }    
}

void test_5_signed (struct xyz * ctx)
{
  int i;
  for (i = 10; i < 20; i++) {
    wfm(ctx, i, arr[i - 10]);
  }    
}