OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [gcc.c-torture/] [execute/] [builtins/] [stpcpy-chk.c] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 688 jeremybenn
/* Copyright (C) 2004, 2005  Free Software Foundation.
2
 
3
   Ensure builtin __stpcpy_chk performs correctly.  */
4
 
5
extern void abort (void);
6
typedef __SIZE_TYPE__ size_t;
7
extern size_t strlen(const char *);
8
extern void *memcpy (void *, const void *, size_t);
9
extern char *stpcpy (char *, const char *);
10
extern int memcmp (const void *, const void *, size_t);
11
 
12
#include "chk.h"
13
 
14
LOCAL const char s1[] = "123";
15
char p[32] = "";
16
char *s2 = "defg";
17
char *s3 = "FGH";
18
char *s4;
19
size_t l1 = 1;
20
 
21
void
22
__attribute__((noinline))
23
test1 (void)
24
{
25
  int i = 8;
26
 
27
#if defined __i386__ || defined __x86_64__
28
  /* The functions below might not be optimized into direct stores on all
29
     arches.  It depends on how many instructions would be generated and
30
     what limits the architecture chooses in STORE_BY_PIECES_P.  */
31
  stpcpy_disallowed = 1;
32
#endif
33
  if (stpcpy (p, "abcde") != p + 5 || memcmp (p, "abcde", 6))
34
    abort ();
35
  if (stpcpy (p + 16, "vwxyz" + 1) != p + 16 + 4 || memcmp (p + 16, "wxyz", 5))
36
    abort ();
37
  if (stpcpy (p + 1, "") != p + 1 + 0 || memcmp (p, "a\0cde", 6))
38
    abort ();
39
  if (stpcpy (p + 3, "fghij") != p + 3 + 5 || memcmp (p, "a\0cfghij", 9))
40
    abort ();
41
 
42
  if (stpcpy ((i++, p + 20 + 1), "23") != (p + 20 + 1 + 2)
43
      || i != 9 || memcmp (p + 19, "z\0""23\0", 5))
44
    abort ();
45
 
46
  if (stpcpy (stpcpy (p, "ABCD"), "EFG") != p + 7 || memcmp (p, "ABCDEFG", 8))
47
    abort();
48
 
49
  /* Test at least one instance of the __builtin_ style.  We do this
50
     to ensure that it works and that the prototype is correct.  */
51
  if (__builtin_stpcpy (p, "abcde") != p + 5 || memcmp (p, "abcde", 6))
52
    abort ();
53
 
54
  /* If return value of stpcpy is ignored, it should be optimized into
55
     strcpy call.  */
56
  stpcpy_disallowed = 1;
57
  stpcpy (p + 1, "abcd");
58
  stpcpy_disallowed = 0;
59
  if (memcmp (p, "aabcd", 6))
60
    abort ();
61
 
62
  if (chk_calls)
63
    abort ();
64
 
65
  chk_calls = 0;
66
  strcpy_disallowed = 1;
67
  if (stpcpy (p, s2) != p + 4 || memcmp (p, "defg\0", 6))
68
    abort ();
69
  strcpy_disallowed = 0;
70
  stpcpy_disallowed = 1;
71
  stpcpy (p + 2, s3);
72
  stpcpy_disallowed = 0;
73
  if (memcmp (p, "deFGH", 6))
74
    abort ();
75
  if (chk_calls != 2)
76
    abort ();
77
}
78
 
79
#ifndef MAX_OFFSET
80
#define MAX_OFFSET (sizeof (long long))
81
#endif
82
 
83
#ifndef MAX_COPY
84
#define MAX_COPY (10 * sizeof (long long))
85
#endif
86
 
87
#ifndef MAX_EXTRA
88
#define MAX_EXTRA (sizeof (long long))
89
#endif
90
 
91
#define MAX_LENGTH (MAX_OFFSET + MAX_COPY + 1 + MAX_EXTRA)
92
 
93
/* Use a sequence length that is not divisible by two, to make it more
94
   likely to detect when words are mixed up.  */
95
#define SEQUENCE_LENGTH 31
96
 
97
static union {
98
  char buf[MAX_LENGTH];
99
  long long align_int;
100
  long double align_fp;
101
} u1, u2;
102
 
103
volatile char *vx;
104
 
105
void
106
__attribute__((noinline))
107
test2 (void)
108
{
109
  int off1, off2, len, i;
110
  char *p, *q, c;
111
 
112
  for (off1 = 0; off1 < MAX_OFFSET; off1++)
113
    for (off2 = 0; off2 < MAX_OFFSET; off2++)
114
      for (len = 1; len < MAX_COPY; len++)
115
        {
116
          for (i = 0, c = 'A'; i < MAX_LENGTH; i++, c++)
117
            {
118
              u1.buf[i] = 'a';
119
              if (c >= 'A' + SEQUENCE_LENGTH)
120
                c = 'A';
121
              u2.buf[i] = c;
122
            }
123
          u2.buf[off2 + len] = '\0';
124
 
125
          p = stpcpy (u1.buf + off1, u2.buf + off2);
126
          if (p != u1.buf + off1 + len)
127
            abort ();
128
 
129
          q = u1.buf;
130
          for (i = 0; i < off1; i++, q++)
131
            if (*q != 'a')
132
              abort ();
133
 
134
          for (i = 0, c = 'A' + off2; i < len; i++, q++, c++)
135
            {
136
              if (c >= 'A' + SEQUENCE_LENGTH)
137
                c = 'A';
138
              if (*q != c)
139
                abort ();
140
            }
141
 
142
          if (*q++ != '\0')
143
            abort ();
144
          for (i = 0; i < MAX_EXTRA; i++, q++)
145
            if (*q != 'a')
146
              abort ();
147
        }
148
}
149
 
150
/* Test whether compile time checking is done where it should
151
   and so is runtime object size checking.  */
152
void
153
__attribute__((noinline))
154
test3 (void)
155
{
156
  struct A { char buf1[10]; char buf2[10]; } a;
157
  char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
158
  char buf3[20];
159
  int i;
160
  const char *l;
161
 
162
  /* The following calls should do runtime checking
163
     - source length is not known, but destination is.  */
164
  chk_calls = 0;
165
  vx = stpcpy (a.buf1 + 2, s3 + 3);
166
  vx = stpcpy (r, s3 + 2);
167
  r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
168
  vx = stpcpy (r, s2 + 2);
169
  vx = stpcpy (r + 2, s3 + 3);
170
  r = buf3;
171
  for (i = 0; i < 4; ++i)
172
    {
173
      if (i == l1 - 1)
174
        r = &a.buf1[1];
175
      else if (i == l1)
176
        r = &a.buf2[7];
177
      else if (i == l1 + 1)
178
        r = &buf3[5];
179
      else if (i == l1 + 2)
180
        r = &a.buf1[9];
181
    }
182
  vx = stpcpy (r, s2 + 4);
183
  if (chk_calls != 5)
184
    abort ();
185
 
186
  /* Following have known destination and known source length,
187
     so if optimizing certainly shouldn't result in the checking
188
     variants.  */
189
  chk_calls = 0;
190
  vx = stpcpy (a.buf1 + 2, "");
191
  vx = stpcpy (r, "a");
192
  r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
193
  vx = stpcpy (r, s1 + 1);
194
  r = buf3;
195
  l = "abc";
196
  for (i = 0; i < 4; ++i)
197
    {
198
      if (i == l1 - 1)
199
        r = &a.buf1[1], l = "e";
200
      else if (i == l1)
201
        r = &a.buf2[7], l = "gh";
202
      else if (i == l1 + 1)
203
        r = &buf3[5], l = "jkl";
204
      else if (i == l1 + 2)
205
        r = &a.buf1[9], l = "";
206
    }
207
  vx = stpcpy (r, "");
208
  /* Here, strlen (l) + 1 is known to be at most 4 and
209
     __builtin_object_size (&buf3[16], 0) is 4, so this doesn't need
210
     runtime checking.  */
211
  vx = stpcpy (&buf3[16], l);
212
  /* Unknown destination and source, no checking.  */
213
  vx = stpcpy (s4, s3);
214
  stpcpy (s4 + 4, s3);
215
  if (chk_calls)
216
    abort ();
217
  chk_calls = 0;
218
}
219
 
220
/* Test whether runtime and/or compile time checking catches
221
   buffer overflows.  */
222
void
223
__attribute__((noinline))
224
test4 (void)
225
{
226
  struct A { char buf1[10]; char buf2[10]; } a;
227
  char buf3[20];
228
 
229
  chk_fail_allowed = 1;
230
  /* Runtime checks.  */
231
  if (__builtin_setjmp (chk_fail_buf) == 0)
232
    {
233
      vx = stpcpy (&a.buf2[9], s2 + 3);
234
      abort ();
235
    }
236
  if (__builtin_setjmp (chk_fail_buf) == 0)
237
    {
238
      vx = stpcpy (&a.buf2[7], s3 + strlen (s3) - 3);
239
      abort ();
240
    }
241
  /* This should be detectable at compile time already.  */
242
  if (__builtin_setjmp (chk_fail_buf) == 0)
243
    {
244
      vx = stpcpy (&buf3[19], "a");
245
      abort ();
246
    }
247
  chk_fail_allowed = 0;
248
}
249
 
250
void
251
main_test (void)
252
{
253
#ifndef __OPTIMIZE__
254
  /* Object size checking is only intended for -O[s123].  */
255
  return;
256
#endif
257
  __asm ("" : "=r" (s2) : "0" (s2));
258
  __asm ("" : "=r" (s3) : "0" (s3));
259
  __asm ("" : "=r" (l1) : "0" (l1));
260
  test1 ();
261
  s4 = p;
262
  test2 ();
263
  test3 ();
264
  test4 ();
265
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.