Skip to content

Commit d2b768b

Browse files
committed
[C2x] Add test coverage for WG14 N2607
This adds test coverage for N2607, which makes arrays and their elements identically qualified. Clang already implements much of the functionality from this paper, but is still missing some support. It also adds some details to the C status page so users have this information as well.
1 parent 55270f5 commit d2b768b

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

clang/test/C/C2x/n2607.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// RUN: %clang_cc1 -std=c2x -Wall -pedantic -verify %s
2+
// RUN: %clang_cc1 -std=c17 -Wall -pedantic -verify %s
3+
4+
/* WG14 N2607: Partial
5+
* Compatibility of Pointers to Arrays with Qualifiers
6+
*
7+
* FIXME: We consider this partially implemented because there are still issues
8+
* with the composite type from a conditional operator. Further, we don't issue
9+
* any diagnostics in C17 or earlier when we need at least a pedantic
10+
* diagnostic about the type incompatibilities.
11+
*/
12+
13+
void matrix_fun(int N, const float x[N][N]);
14+
void test1(void) {
15+
int N = 100;
16+
float x[N][N];
17+
// FIXME: This is OK in C2x but should be diagnosed as passing incompatible
18+
// pointer types in C17 and earlier.
19+
matrix_fun(N, x);
20+
}
21+
22+
#define TEST(Expr, Type) _Generic(Expr, Type : 1)
23+
24+
void test2(void) {
25+
typedef int array[1];
26+
array reg_array;
27+
const array const_array;
28+
29+
// An array and its elements are identically qualified. We have to test this
30+
// using pointers to the array and element, because the controlling
31+
// expression of _Generic will undergo lvalue conversion, which drops
32+
// qualifiers.
33+
(void)_Generic(&reg_array, int (*)[1] : 1);
34+
(void)_Generic(&reg_array[0], int * : 1);
35+
36+
(void)_Generic(&const_array, const int (*)[1] : 1);
37+
(void)_Generic(&const_array[0], const int * : 1);
38+
39+
// But identical qualification does *not* apply to the _Atomic specifier,
40+
// because that's a special case. You cannot apply the _Atomic specifier or
41+
// qualifier to an array type directly.
42+
_Atomic array atomic_array; // expected-error {{_Atomic cannot be applied to array type 'array'}}
43+
_Atomic(array) also_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'array'}}
44+
45+
// Ensure we support arrays of restrict-qualified pointer types.
46+
int *restrict array_of_restricted_ptrs[1];
47+
int *restrict md_array_of_restricted_ptrs[1][1];
48+
}
49+
50+
void test3(void) {
51+
// Validate that we pick the correct composite type for a conditional
52+
// operator in the presence of qualifiers.
53+
const int const_array[1];
54+
int array[1];
55+
56+
// FIXME: the type here should be `const int (*)[1]`, but for some reason,
57+
// Clang is deciding it's `void *`. This relates to N2607 because the
58+
// conditional operator is not properly implementing 6.5.15p7 regarding
59+
// qualifiers, despite that wording not being touched by this paper.
60+
// However, it should get a pedantic diagnostic in C17 about use of
61+
// incompatible pointer types.
62+
(void)_Generic(1 ? &const_array : &array, const int (*)[1] : 1); /* expected-error {{controlling expression type 'void *' not compatible with any generic association type}}
63+
expected-warning {{pointer type mismatch ('const int (*)[1]' and 'int (*)[1]')}}
64+
*/
65+
}

clang/www/c_status.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,15 @@ <h2 id="c2x">C2x implementation status</h2>
829829
<tr>
830830
<td>Compatibility of Pointers to Arrays with Qualifiers</td>
831831
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2607.pdf">N2607</a></td>
832-
<td class="partial" align="center">Partial</td>
832+
<td class="partial" align="center">
833+
<details><summary>Partial</summary>
834+
Much of the proposal is implemented, but Clang lacks pedantic diagnostics
835+
in C17 and earlier regarding use of incompatible pointer types as an
836+
extension. Further, Clang does not properly compute the correct result
837+
type for the <code>?:</code> operator when the result type should be a
838+
qualified array type.
839+
</details>
840+
</td>
833841
</tr>
834842
<tr>
835843
<td>Unclear type relationship between a format specifier and its argument</td>

0 commit comments

Comments
 (0)