|
| 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(®_array, int (*)[1] : 1); |
| 34 | + (void)_Generic(®_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 | +} |
0 commit comments