xref: /llvm-project/clang/test/C/C23/n2607.c (revision 50c81128de8616117118564eff22cf508cba7848)
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]);
test1(void)14 void test1(void) {
15   int N = 100;
16   float x[N][N];
17   // FIXME: This is OK in C23 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 
test2(void)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 
test3(void)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 }
66