Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/gcc.dg/builtin-stringop-chk-6.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Test exercising -Wrawmem-overflow and -Wstringop-overflow warnings. */ | |
2 /* { dg-do compile } */ | |
3 /* { dg-options "-O2 -Wstringop-overflow=2" } */ | |
4 | |
5 #define offsetof(type, mem) __builtin_offsetof (type, mem) | |
6 | |
7 /* Return the number of bytes from member MEM of TYPE to the end | |
8 of object OBJ. */ | |
9 #define offsetfrom(type, obj, mem) (sizeof (obj) - offsetof (type, mem)) | |
10 | |
11 | |
12 typedef __SIZE_TYPE__ size_t; | |
13 extern void* memcpy (void*, const void*, size_t); | |
14 extern void* memset (void*, int, __SIZE_TYPE__); | |
15 | |
16 | |
17 struct A { char a, b; }; | |
18 struct B { struct A a; char c, d; }; | |
19 | |
20 /* Function to call to "escape" pointers from tests below to prevent | |
21 GCC from assuming the values of the objects they point to stay | |
22 the unchanged. */ | |
23 void escape (void*, ...); | |
24 | |
25 /* Function to "generate" a random number each time it's called. Declared | |
26 (but not defined) and used to prevent GCC from making assumptions about | |
27 their values based on the variables uses in the tested expressions. */ | |
28 size_t random_unsigned_value (void); | |
29 | |
30 /* Return a random unsigned value between MIN and MAX. */ | |
31 | |
32 static inline size_t | |
33 range (size_t min, size_t max) | |
34 { | |
35 const size_t val = random_unsigned_value (); | |
36 return val < min || max < val ? min : val; | |
37 } | |
38 | |
39 | |
40 void test_memop_warn_object (const void *src) | |
41 { | |
42 unsigned n = range (17, 29); | |
43 | |
44 struct A a[2]; | |
45 | |
46 /* At both -Wstringop-overflow=2, like at 1, the destination of functions | |
47 that operate on raw memory is considered to be the whole array and its | |
48 size is therefore sizeof a. */ | |
49 memcpy (&a[0], src, n); /* { dg-warning "writing between 17 and 29 bytes into a region of size 4 overflows the destination" } */ | |
50 escape (a); | |
51 } | |
52 | |
53 void test_memop_warn_subobject (const void *src) | |
54 { | |
55 unsigned n = range (17, 31); | |
56 | |
57 struct B b[2]; | |
58 | |
59 /* At -Wrawmem-overflow=2 the destination is considered to be | |
60 the member sobobject of the first array element and its size | |
61 is therefore sizeof b[0].a. */ | |
62 memcpy (&b[0].a, src, n); /* { dg-warning "writing between 17 and 31 bytes into a region of size 8 overflows the destination" } */ | |
63 | |
64 escape (b); | |
65 } | |
66 | |
67 void test_memop_nowarn_subobject (void) | |
68 { | |
69 struct B b[2]; | |
70 | |
71 /* The following idiom of clearing multiple members of a struct | |
72 has been seen in a few places in the Linux kernel. Verify | |
73 that a warning is not issued for it. */ | |
74 memset (&b[0].c, 0, sizeof b[0] - offsetof (struct B, c)); | |
75 | |
76 escape (b); | |
77 } | |
78 | |
79 struct C { char a[3], b; }; | |
80 struct D { struct C c; char d, e; }; | |
81 | |
82 extern char* strncpy (char*, const char*, __SIZE_TYPE__); | |
83 | |
84 void test_stringop_warn_object (const char *str) | |
85 { | |
86 unsigned n = range (2 * sizeof (struct D), 32); | |
87 | |
88 struct C c[2]; | |
89 | |
90 /* Similarly, at -Wstringop-overflow=2 the destination is considered | |
91 to be the array member of the first element of the array c and its | |
92 size is therefore sizeof c[0].a. */ | |
93 strncpy (c[0].a, "123", n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */ | |
94 escape (c); | |
95 | |
96 strncpy (c[0].a, str, n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */ | |
97 escape (c); | |
98 } | |
99 | |
100 void test_stringop_warn_subobject (const char *src) | |
101 { | |
102 unsigned n = range (2 * sizeof (struct D), 32); | |
103 | |
104 struct D d[2]; | |
105 | |
106 /* Same as above. */ | |
107 strncpy (d[0].c.a, "123", n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */ | |
108 escape (d); | |
109 | |
110 strncpy (d[0].c.a, src, n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */ | |
111 escape (d); | |
112 } |