Skip to content

Commit d7e06d5

Browse files
committed
Update the status of some more C99 features
This also adds some test coverage to demonstrate we implement what was standardized.
1 parent 956f8c0 commit d7e06d5

File tree

5 files changed

+203
-4
lines changed

5 files changed

+203
-4
lines changed

clang/test/C/C99/n617.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -verify %s
2+
3+
// expected-no-diagnostics
4+
5+
/* WG14 N617: yes
6+
* reliable integer division
7+
*/
8+
void test(void) {
9+
_Static_assert(59 / 4 == 14, "we didn't truncate properly");
10+
_Static_assert(59 / -4 == -14, "we didn't truncate properly");
11+
_Static_assert(-59 / 4 == -14, "we didn't truncate properly");
12+
_Static_assert(-59 / -4 == 14, "we didn't truncate properly");
13+
14+
// Might as well test % for the quotient.
15+
_Static_assert(59 % 4 == 3, "we didn't truncate properly");
16+
_Static_assert(59 % -4 == 3, "we didn't truncate properly");
17+
_Static_assert(-59 % 4 == -3, "we didn't truncate properly");
18+
_Static_assert(-59 % -4 == -3, "we didn't truncate properly");
19+
20+
// Test the idiom for rounding up.
21+
_Static_assert((59 + (4 - 1)) / 4 == 15, "failed to 'round up' with the usual idiom");
22+
_Static_assert((59 + (4 - 1)) % 4 == 2, "failed to 'round up' with the usual idiom");
23+
}
24+

clang/test/C/C99/n629.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux -verify %s
2+
// RUN: %clang_cc1 -triple i686-unknown-linux -verify %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-win32 -verify %s
4+
// RUN: %clang_cc1 -triple i686-unknown-win32 -verify %s
5+
6+
/* WG14 N629: yes
7+
* integer constant type rules
8+
*/
9+
10+
// expected-no-diagnostics
11+
12+
void test_decimal_constants(void) {
13+
// Easy cases where the value fits into the type you'd expect.
14+
(void)_Generic(2, int : 1);
15+
(void)_Generic(2u, unsigned int : 1);
16+
(void)_Generic(2l, long : 1);
17+
(void)_Generic(2ul, unsigned long : 1);
18+
(void)_Generic(2ll, long long : 1);
19+
(void)_Generic(2ull, unsigned long long : 1);
20+
21+
#if __INT_WIDTH__ == 16
22+
#if __LONG_WIDTH__ > 16
23+
(void)_Generic(65536, long : 1);
24+
(void)_Generic(65536U, unsigned long : 1);
25+
#else
26+
(void)_Generic(65536, long long : 1);
27+
(void)_Generic(65536U, unsigned long : 1);
28+
#endif // __LONG_WIDTH__ > 16
29+
#elif __INT_WIDTH__ == 32
30+
#if __LONG_WIDTH__ > 32
31+
(void)_Generic(4294967296, long : 1);
32+
(void)_Generic(4294967296U, unsigned long : 1);
33+
#else
34+
(void)_Generic(4294967296, long long : 1);
35+
(void)_Generic(4294967296U, unsigned long long : 1);
36+
#endif // __LONG_WIDTH__ > 32
37+
#endif
38+
39+
#if __LONG_WIDTH__ > 32
40+
(void)_Generic(4294967296L, long : 1);
41+
(void)_Generic(4294967296U, unsigned long : 1);
42+
#else
43+
(void)_Generic(4294967296L, long long : 1);
44+
(void)_Generic(4294967296U, unsigned long long : 1);
45+
#endif
46+
}
47+
48+
void test_octal_constants(void) {
49+
(void)_Generic(02, int : 1);
50+
(void)_Generic(02u, unsigned int : 1);
51+
(void)_Generic(02l, long : 1);
52+
(void)_Generic(02ul, unsigned long : 1);
53+
(void)_Generic(02ll, long long : 1);
54+
(void)_Generic(02ull, unsigned long long : 1);
55+
56+
#if __INT_WIDTH__ == 16
57+
#if __LONG_WIDTH__ > 16
58+
(void)_Generic(0200000, long : 1);
59+
(void)_Generic(0200000U, unsigned long : 1);
60+
#else
61+
(void)_Generic(0200000, long long : 1);
62+
(void)_Generic(0200000U, unsigned long : 1);
63+
#endif // __LONG_WIDTH__ > 16
64+
#elif __INT_WIDTH__ == 32
65+
#if __LONG_WIDTH__ > 32
66+
(void)_Generic(040000000000, long : 1);
67+
(void)_Generic(040000000000U, unsigned long : 1);
68+
#else
69+
(void)_Generic(040000000000, long long : 1);
70+
(void)_Generic(040000000000U, unsigned long long : 1);
71+
#endif // __LONG_WIDTH__ > 32
72+
#endif
73+
74+
#if __LONG_WIDTH__ > 32
75+
(void)_Generic(040000000000L, long : 1);
76+
(void)_Generic(040000000000U, unsigned long : 1);
77+
#else
78+
(void)_Generic(040000000000L, long long : 1);
79+
(void)_Generic(040000000000U, unsigned long long : 1);
80+
#endif
81+
}
82+
83+
void test_hexadecimal_constants(void) {
84+
(void)_Generic(0x2, int : 1);
85+
(void)_Generic(0x2u, unsigned int : 1);
86+
(void)_Generic(0x2l, long : 1);
87+
(void)_Generic(0x2ul, unsigned long : 1);
88+
(void)_Generic(0x2ll, long long : 1);
89+
(void)_Generic(0x2ull, unsigned long long : 1);
90+
91+
#if __INT_WIDTH__ == 16
92+
#if __LONG_WIDTH__ > 16
93+
(void)_Generic(0x10000, long : 1);
94+
(void)_Generic(0x10000U, unsigned long : 1);
95+
#else
96+
(void)_Generic(0x10000, long long : 1);
97+
(void)_Generic(0x10000U, unsigned long : 1);
98+
#endif // __LONG_WIDTH__ > 16
99+
#elif __INT_WIDTH__ == 32
100+
#if __LONG_WIDTH__ > 32
101+
(void)_Generic(0x100000000, long : 1);
102+
(void)_Generic(0x100000000U, unsigned long : 1);
103+
#else
104+
(void)_Generic(0x100000000, long long : 1);
105+
(void)_Generic(0x100000000U, unsigned long long : 1);
106+
#endif // __LONG_WIDTH__ > 32
107+
#endif
108+
109+
#if __LONG_WIDTH__ > 32
110+
(void)_Generic(0x100000000L, long : 1);
111+
(void)_Generic(0x100000000U, unsigned long : 1);
112+
#else
113+
(void)_Generic(0x100000000L, long long : 1);
114+
(void)_Generic(0x100000000U, unsigned long long : 1);
115+
#endif
116+
}

clang/test/C/C99/n636.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -verify %s
2+
// RUN: %clang_cc1 -verify=c2x -std=c2x %s
3+
4+
/* WG14 N636: yes
5+
* remove implicit function declaration
6+
*/
7+
8+
void test(void) {
9+
frobble(); // expected-error {{call to undeclared function 'frobble'; ISO C99 and later do not support implicit function declarations}} \
10+
c2x-error {{undeclared identifier 'frobble'}}
11+
}
12+

clang/test/C/C99/n736.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %clang_cc1 -verify %s
2+
3+
/* WG14 N736: yes
4+
* preprocessor arithmetic done in intmax_t/uintmax_t
5+
*/
6+
7+
// There is not a standard requirement that this relationships holds. If these
8+
// asserts fail, it means we have another test scenario to consider.
9+
_Static_assert(__INTMAX_MAX__ == __LONG_LONG_MAX__,
10+
"intmax_t is not the same width as long long?");
11+
_Static_assert((-__INTMAX_MAX__ - 1) == (-__LONG_LONG_MAX__ - 1LL),
12+
"intmax_t is not the same width as long long?");
13+
_Static_assert(__UINTMAX_MAX__ == (__LONG_LONG_MAX__ * 2ULL + 1ULL),
14+
"uintmax_t is not the same width as unsigned long long?");
15+
16+
// Test that arithmetic on the largest positive signed intmax_t works.
17+
#if 9223372036854775807LL + 0LL != 9223372036854775807LL
18+
#error "uh oh"
19+
#endif
20+
21+
// Same for negative.
22+
#if -9223372036854775807LL - 1LL + 0LL != -9223372036854775807LL - 1LL
23+
#error "uh oh"
24+
#endif
25+
26+
// Then test the same for unsigned
27+
#if 18446744073709551615ULL + 0ULL != 18446744073709551615ULL
28+
#error "uh oh"
29+
#endif
30+
31+
// Test that unsigned overflow causes silent wraparound.
32+
#if 18446744073709551615ULL + 1ULL != 0 // Silently wraps to 0.
33+
#error "uh oh"
34+
#endif
35+
36+
#if 0ULL - 1ULL != 18446744073709551615ULL // Silently wraps to 0xFFFF'FFFF'FFFF'FFFF.
37+
#error "uh oh"
38+
#endif
39+
40+
// Now test that signed arithmetic that pushes us over a limit is properly
41+
// diagnosed.
42+
#if 9223372036854775807LL + 1LL // expected-warning {{integer overflow in preprocessor expression}}
43+
#endif
44+
45+
#if -9223372036854775807LL - 2LL // expected-warning {{integer overflow in preprocessor expression}}
46+
#endif
47+

clang/www/c_status.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ <h2 id="c99">C99 implementation status</h2>
198198
<tr>
199199
<td>reliable integer division</td>
200200
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n617.htm">N617</a></td>
201-
<td class="unknown" align="center">Unknown</td>
201+
<td class="full" align="center">Yes</td>
202202
</tr>
203203
<tr>
204204
<td>universal character names (\u and \U)</td>
@@ -245,12 +245,12 @@ <h2 id="c99">C99 implementation status</h2>
245245
<tr>
246246
<td>remove implicit function declaration</td>
247247
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n636.htm">N636</a></td>
248-
<td class="unknown" align="center">Unknown</td>
248+
<td class="full" align="center">Yes</td>
249249
</tr>
250250
<tr>
251251
<td>preprocessor arithmetic done in intmax_t/uintmax_t</td>
252252
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n736.htm">N736</a></td>
253-
<td class="unknown" align="center">Unknown</td>
253+
<td class="full" align="center">Yes</td>
254254
</tr>
255255
<tr>
256256
<td>mixed declarations and code</td>
@@ -265,7 +265,7 @@ <h2 id="c99">C99 implementation status</h2>
265265
<tr>
266266
<td>integer constant type rules</td>
267267
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n629.htm">N629</a></td>
268-
<td class="unknown" align="center">Unknown</td>
268+
<td class="full" align="center">Yes</td>
269269
</tr>
270270
<tr>
271271
<td>integer promotion rules</td>

0 commit comments

Comments
 (0)