1 /* PR middle-end/83859 - attribute to establish relation between parameters
2 for buffer and its size
3 Test to verify that -Wstringop-overflow warnings are issued even with
4 no optimization for calls to user-defined functions with attribute
5 access and with constant out-of-bounds arguments.
7 { dg-options "-O0 -Wall" } */
9 #define INT_MAX __INT_MAX__
10 #define INT_MIN (-INT_MAX - 1)
12 #define rdonly __attribute__ ((access (read_only)))
13 #define RDONLY(...) __attribute__ ((access (read_only, __VA_ARGS__)))
14 #define WRONLY(...) __attribute__ ((access (write_only, __VA_ARGS__)))
15 #define RDWR(...) __attribute__ ((access (read_write, __VA_ARGS__)))
17 typedef __INT32_TYPE__
int32_t;
19 extern const char s1
[1], s2
[2], s3
[3];
20 extern char d1
[1], d2
[2], d3
[3];
22 /* Exercise that null pointers are allowed in functions declared with
23 the attribute without a size operand. */
26 rd1_int (const int32_t*); // { dg-message "in a call to function 'rd1_int' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
28 void test_rd1_int (void)
35 rd1_int ((int32_t*)s1
); // { dg-warning "reading 4 bytes from a region of size 1" }
38 /* Exercise null pointer detection in functions declared with
39 the attribute and with non-zero size. */
42 rd2_1 (int, const void*); // { dg-message "in a call to function 'rd2_1' declared with attribute 'access \\\(read_only, 2, 1\\\)" "note" }
44 void test_rd2_1 (void)
48 rd2_1 (1, 0); // { dg-warning "argument 2 is null but the corresponding size argument 1 value is 1" }
52 wr3_1 (int, int, void*); // { dg-message "in a call to function 'wr3_1' declared with attribute 'access \\\(write_only, 3, 1\\\)" "note" }
54 void test_wr3_1 (void)
58 wr3_1 (2, 1, 0); // { dg-warning "argument 3 is null but the corresponding size argument 1 value is 2" }
62 /* Exercise pointer to an incomplete type other than void. */
65 extern struct Incomplete inc
;
68 rd_inc (const struct Incomplete
*);
70 void test_rd_inc (const struct Incomplete
*pinc
)
75 rd_inc ((const struct Incomplete
*)s1
);
77 rd_inc ((const struct Incomplete
*)&s1
[1]);
78 // { dg-warning "'rd_inc' reading 1 byte from a region of size 0" "past-the-end pointer" { target *-*-* } .-1 }
82 rd1_2_inc (const struct Incomplete
*, unsigned);
84 void test_rd1_2_inc (const struct Incomplete
*pinc
)
87 rd1_2_inc (0, 1); // { dg-warning "argument 1 is null but the corresponding size argument 2 value is 1" }
92 rd1_2_inc (pinc
, 123);
93 rd1_2_inc (&inc
, 456);
95 rd1_2_inc ((const struct Incomplete
*)s3
, 4);
96 // { dg-warning "'rd1_2_inc' reading 4 bytes from a region of size 3" "small buffer cast to incomplete" { target *-*-* } .-1 }
100 /* Verify the handling of two attributes sharing the same size operand . */
102 RDONLY (1, 3) WRONLY (2, 3) void
103 rd1_3_wr2_3 (const void*, void*, int);
105 void test_rd1_3_wr2_3 (void)
107 rd1_3_wr2_3 (s1
, d1
, 0);
108 rd1_3_wr2_3 (s1
, d1
, 1);
110 rd1_3_wr2_3 (s1
, d1
, 2);
111 // { dg-warning "'rd1_3_wr2_3' reading 2 bytes from a region of size 1" "read" { target *-*-* } .-1 }
112 // { dg-warning "'rd1_3_wr2_3' writing 2 bytes into a region of size 1" "write" { target *-*-* } .-2 }
114 rd1_3_wr2_3 (s1
, d2
, 2);
115 // { dg-warning "'rd1_3_wr2_3' reading 2 bytes from a region of size 1" "read" { target *-*-* } .-1 }
117 rd1_3_wr2_3 (s2
, d1
, 2);
118 // { dg-warning "'rd1_3_wr2_3' writing 2 bytes into a region of size 1" "write" { target *-*-* } .-1 }
122 /* Verify the handling of multiple attributes of the same kind with
123 out-of-order operands. */
125 RDONLY (1, 6) RDONLY (2, 5) RDONLY (3, 4) void
126 rd1_6_2_5_3_4 (const void *s1
, const void *s2
, const void *s3
,
127 int n3
, int n2
, int n1
);
129 void test_rd1_6_2_5_3_4 (void)
131 rd1_6_2_5_3_4 (s1
, s2
, s3
, 4, 2, 1); // { dg-warning "reading 4 bytes from a region of size 3" }
132 rd1_6_2_5_3_4 (s1
, s2
, s3
, 3, 5, 1); // { dg-warning "reading 5 bytes from a region of size 2" }
133 rd1_6_2_5_3_4 (s1
, s2
, s3
, 3, 2, 6); // { dg-warning "reading 6 bytes from a region of size 1" }
137 /* Verify the handling of multiple attributes of different kinds with
138 out-of-order operands. */
140 RDONLY (1, 6) WRONLY (2, 5) RDONLY (3, 4) void
141 rd1_6_wr2_5_rd3_4 (const void *s1
, void *d2
, const void *s3
,
142 int n3
, int n2
, int n1
);
144 void test_rd1_6_wr2_5_rd3_4 (void)
146 rd1_6_wr2_5_rd3_4 (s1
, d2
, s3
, 7, 2, 1); // { dg-warning "reading 7 bytes from a region of size 3" }
147 rd1_6_wr2_5_rd3_4 (s1
, d2
, s3
, 3, 8, 1); // { dg-warning "writing 8 bytes into a region of size 2" }
148 rd1_6_wr2_5_rd3_4 (s1
, d2
, s3
, 3, 2, 9); // { dg-warning "reading 9 bytes from a region of size 1" }
152 RDONLY (6, 1) WRONLY (5, 2) RDWR (4, 3) void
153 rd6_1_wr5_2_rd4_3 (int n1
, int n2
, int n3
,
154 void *d3
, void *d2
, const void *s1
);
156 void test_rd6_1_wr5_2_rd4_3 (void)
158 rd6_1_wr5_2_rd4_3 (7, 2, 1, d1
, d2
, s3
); // { dg-warning "reading 7 bytes from a region of size 3" }
159 rd6_1_wr5_2_rd4_3 (3, 8, 1, d1
, d2
, s3
); // { dg-warning "writing 8 bytes into a region of size 2" }
160 rd6_1_wr5_2_rd4_3 (3, 2, 9, d1
, d2
, s3
); // { dg-warning "accessing 9 bytes in a region of size 1" }
164 RDONLY (1, 3) WRONLY (2, 4) void
165 rd1_3_wr2_4 (const void*, void*, int, int);
167 void test_rd1_3_wr2_4 (const void *s
, void *d
, int n1
, int n2
)
169 rd1_3_wr2_4 (s
, d
, 1, 2);
170 rd1_3_wr2_4 (s
, d
, 123, 456);
171 rd1_3_wr2_4 (s
, d
, INT_MAX
, INT_MAX
);
172 rd1_3_wr2_4 (s
, d
, -1, 2); // { dg-warning "argument 3 value -1 is negative" }
174 const char s11
[11] = "0123456789";
176 rd1_3_wr2_4 (s11
, d
, 11, n2
);
177 rd1_3_wr2_4 (s11
, d
, 12, n2
); // { dg-warning "'rd1_3_wr2_4' reading 12 bytes from a region of size 11" }
181 /* Verify that function pointers are handled. */
183 RDONLY (1) void (*pfrd1
)(const void*, const void*);
185 void test_pfrd1 (void)
191 pfrd1 ("" + 1, ""); // { dg-warning "reading 1 byte from a region of size 0" }
195 WRONLY (4, 3) void (*pfwr4_3
)(int, const char*, int, int32_t*);
197 void test_pfwr4_3 (void)
199 pfwr4_3 (0, 0, 0, 0);
202 pfwr4_3 (3, "", 0, &i
+ 1);
203 pfwr4_3 (5, "", 1, &i
+ 1); // { dg-warning "writing 4 bytes into a region of size 0" }