summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/strlenopt-78.c
blob: c028723e5938d4e2b3ddc53382c6e6f6f4a10a8d (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
/* PR middle-end/91490 - bogus argument missing terminating nul warning
   on strlen of a flexible array member
   Verify that strlen calls with a flexible array member (and its common
   forms) of declaraed objects are folded.
   { dg-do compile }
   { dg-options "-Wall -fdump-tree-gimple" } */

#include "strlenopt.h"

extern void* memchr (const void*, int, size_t);

struct A1 { char n, a[1]; };
struct A2 { char n, a[2]; };
struct A3 { char n, a[3]; };
struct Ax { char n, a[]; };

const struct A1 a1_0 = { 0 };
const struct A1 a1_0_ = { 0, { } };
const struct A1 a1_0_0 = { 0, { 0 } };

const struct A2 a2_1_ = { 1, { } };
const struct A2 a2_1_1 = { 1, { 1 } };
const struct A2 a2_1_1_0 = { 1, { 1, 0 } };

const struct A3 aa3_1_[2] = { { 1 } };

const struct Ax ax = { 3, { 3, 2, 1, 0 } };

struct BxA1 { int n; struct A1 a[]; };
struct BxA2 { int n; struct A2 a[]; };

const struct BxA2 bx = { 2, { { 2, { 2, 1 } }, { 2, { 1, 0 } } } };

#if 0

// Not implemented yet.

int mchr1, mchr1__, mchr1_0, mchr2_1, mchr2, mchr2_1_0, mchrax, mchrbx;

void test_memchr_flexarray (void)
{
  mchr1 = 0 != memchr (&a1_0, '1', sizeof a1_0);
  mchr1__ = 0 != memchr (&a1_0_, '2', sizeof a1_0_);
  mchr1_0 = 0 != memchr (&a1_0_0, '3', sizeof a1_0_0);

  mchr2 = 0 != memchr (&a2_1_, '4', sizeof a2_1_);
  mchr2_1 = 0 != memchr (&a2_1_1, '\001', sizeof a2_1_1);
  mchr2_1_0 = 0 != memchr (&a2_1_1_0, '\001', sizeof a2_1_1_0);

  mchrax = (const char*)&ax + sizeof ax - 1 == memchr (&ax, '\001', sizeof ax);
  mchrbx = (const char*)&bx + sizeof bx - 1 == memchr (&bx, '\001', sizeof bx);
}

#endif


int schr1, schr1__, schr1_0, schr2_1, schr2, schr2_1_0, schrax, schrbx;

void test_strchr_flexarray (void)
{
  schr1 = 0 != strchr (a1_0.a, '1');
  schr1__ = 0 != strchr (a1_0_.a, '2');
  schr1_0 = 0 != strchr (a1_0_0.a, '3');

  schr2 = 0 != strchr (a2_1_.a, '4');
  schr2_1 = 0 != strchr (a2_1_1.a, '\001');
  schr2_1_0 = 0 != strchr (a2_1_1_0.a, '\001');

  schrax = 0 != strchr (ax.a, '\001');
  schrbx = 0 != strchr (bx.a[1].a, '\0');

  /* { dg-final { scan-tree-dump "schr1 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "schr1__ = 0;" "gimple" } }
     { dg-final { scan-tree-dump "schr1_0 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "schr2 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "schr2_1 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "schr2_1_0 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "schrax = 1;" "gimple" } }
     { dg-final { scan-tree-dump "schrbx = 1;" "gimple" } } */
}


int scmp1, scmp1__, scmp1_0, scmp2_1, scmp2, scmp2_1_0, scmpax, scmpbx;

void test_strcmp_flexarray (void)
{
  scmp1 = 0 == strcmp (a1_0.a, "1");
  scmp1__ = 0 == strcmp (a1_0_.a, "2");
  scmp1_0 = 0 == strcmp (a1_0_0.a, "3");

  scmp2 = 0 == strcmp (a2_1_.a, "4");
  scmp2_1 = 0 == strcmp (a2_1_1.a, "\001");
  scmp2_1_0 = 0 == strcmp (a2_1_1_0.a, "\001");

  scmpax = 0 == strcmp (ax.a, "\003\002\001");
  scmpbx = 0 == strcmp (bx.a[1].a, "\001");

  /* { dg-final { scan-tree-dump "scmp1 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "scmp1__ = 0;" "gimple" } }
     { dg-final { scan-tree-dump "scmp1_0 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "scmp2 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "scmp2_1 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "scmp2_1_0 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "scmpax = 1;" "gimple" } }
     { dg-final { scan-tree-dump "scmpbx = 1;" "gimple" } } */
}


int len1, len1__, len1_0, len2_1, len2, len2_1_0, lenax, lenbx;

void test_strlen_flexarray (void)
{
  len1 = strlen (a1_0.a);
  len1__ = strlen (a1_0_.a);
  len1_0 = strlen (a1_0_0.a);

  len2 = strlen (a2_1_.a);
  len2_1 = strlen (a2_1_1.a);
  len2_1_0 = strlen (a2_1_1_0.a);

  lenax = strlen (ax.a);
  lenbx = strlen (bx.a[1].a);

  /* { dg-final { scan-tree-dump "len1 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "len1__ = 0;" "gimple" } }
     { dg-final { scan-tree-dump "len1_0 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "len2 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "len2_1 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "len2_1_0 = 1;" "gimple" } }
     { dg-final { scan-tree-dump "lenax = 3;" "gimple" } }
     { dg-final { scan-tree-dump "lenbx = 1;" "gimple" } } */
}


int schraa3, scmpaa3, lenaa3;

void test_trailing_array_empty_init (void)
{
  schraa3 = ((aa3_1_[0].a == strchr (aa3_1_[0].a, 0))
	     + (aa3_1_[1].a == strchr (aa3_1_[1].a, 0)));

  scmpaa3 = strcmp (aa3_1_[0].a, aa3_1_[1].a);
  lenaa3 = strlen (aa3_1_[0].a) + strlen (aa3_1_[1].a);

  /* { dg-final { scan-tree-dump "schraa3 = 2;" "gimple" } }
     { dg-final { scan-tree-dump "scmpaa3 = 0;" "gimple" } }
     { dg-final { scan-tree-dump "lenaa3 = 0;" "gimple" } }  */
}

union U4 { char a[4]; int i; };
const union U4 u4[2] = { { "123" } };

int ulen0, ulen1;

void test_union_init (void)
{
  ulen0 = strlen (u4[0].a);
  ulen1 = strlen (u4[1].a);

  /* { dg-final { scan-tree-dump "ulen0 = 3;" "gimple" } }
     { dg-final { scan-tree-dump "ulen1 = 0;" "gimple" } } */
}

/* { dg-final { scan-tree-dump-not "strchr *\\(" "gimple" } }
   { dg-final { scan-tree-dump-not "strcmp *\\(" "gimple" } }
   { dg-final { scan-tree-dump-not "strlen *\\(" "gimple" } } */