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
|
/* PRE tree-optimization/90626 - fold strcmp(a, b) == 0 to zero when
one string length is exact and the other is unequal
{ dg-do run }
{ dg-options "-O2 -Wall" } */
#include "strlenopt.h"
#define A(expr) \
((expr) \
? (void)0 \
: (__builtin_printf ("assertion failed on line %i: %s\n", \
__LINE__, #expr), \
__builtin_abort ()))
__attribute__ ((noclone, noinline, noipa)) void
clobber (void *p, int x, size_t n)
{
for (volatile unsigned char *q = p; n--; )
*q = x;
}
__attribute__ ((noclone, noinline, noipa)) void
test_strcmp (void)
{
char a[8], b[8];
strcpy (a, "1235");
strcpy (b, "1234");
A (strcmp (a, b));
clobber (a, 0, sizeof a);
clobber (b, 0, sizeof b);
clobber (b + 4, '5', 1);
memcpy (a, "1234", 4);
memcpy (b, "1234", 4);
A (0 > strcmp (a, b));
A (0 < strcmp (b, a));
}
__attribute__ ((noclone, noinline, noipa)) void
test_strncmp (void)
{
char a[8], b[8];
strcpy (a, "1235");
strcpy (b, "1234");
A (0 == strncmp (a, b, 1));
A (0 == strncmp (a, b, 2));
A (0 == strncmp (a, b, 3));
A (0 < strncmp (a, b, 4));
A (0 > strncmp (b, a, 4));
clobber (a, 0, sizeof a);
clobber (b, 0, sizeof b);
clobber (b + 4, '5', 1);
memcpy (a, "1234", 4);
memcpy (b, "1234", 4);
A (0 == strncmp (a, b, 4));
A (0 > strncmp (a, b, 5));
A (0 < strncmp (b, a, 5));
}
__attribute__ ((noclone, noinline, noipa)) void
test_strncmp_a4_cond_s5_s2_2 (const char *s, int i)
{
char a4[4];
strcpy (a4, s);
A (0 == strncmp (a4, i ? "12345" : "12", 2));
}
__attribute__ ((noclone, noinline, noipa)) void
test_strncmp_a4_cond_a5_s2_5 (const char *s, const char *t, int i)
{
char a4[4], a5[5];
strcpy (a4, s);
strcpy (a5, t);
A (0 == strncmp (a4, i ? a5 : "12", 5));
}
__attribute__ ((noclone, noinline, noipa)) void
test_strncmp_a4_cond_a5_a3_n (const char *s1, const char *s2, const char *s3,
int i, unsigned n)
{
char a3[3], a4[4], a5[5];
strcpy (a3, s1);
strcpy (a4, s2);
strcpy (a5, s3);
A (0 == strncmp (a4, i ? a5 : a3, n));
}
int main (void)
{
test_strcmp ();
test_strncmp ();
test_strncmp_a4_cond_s5_s2_2 ("12", 0);
test_strncmp_a4_cond_a5_s2_5 ("12", "1234", 0);
test_strncmp_a4_cond_a5_a3_n ("12", "1", "1", 0, 1);
test_strncmp_a4_cond_a5_a3_n ("", "1", "1234", 1, 1);
test_strncmp_a4_cond_a5_a3_n ("12", "12", "1", 0, 2);
test_strncmp_a4_cond_a5_a3_n ("", "12", "1234", 1, 2);
test_strncmp_a4_cond_a5_a3_n ("12", "123", "1", 0, 2);
test_strncmp_a4_cond_a5_a3_n ("", "123", "1234", 1, 3);
}
|