[C2x] Add test coverage for WG14 N2607
authorAaron Ballman <aaron@aaronballman.com>
Wed, 8 Mar 2023 19:57:32 +0000 (14:57 -0500)
committerAaron Ballman <aaron@aaronballman.com>
Wed, 8 Mar 2023 19:59:53 +0000 (14:59 -0500)
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.

clang/test/C/C2x/n2607.c [new file with mode: 0644]
clang/www/c_status.html

diff --git a/clang/test/C/C2x/n2607.c b/clang/test/C/C2x/n2607.c
new file mode 100644 (file)
index 0000000..763cfd9
--- /dev/null
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -std=c2x -Wall -pedantic -verify %s
+// RUN: %clang_cc1 -std=c17 -Wall -pedantic -verify %s
+
+/* WG14 N2607: Partial
+ * Compatibility of Pointers to Arrays with Qualifiers
+ *
+ * FIXME: We consider this partially implemented because there are still issues
+ * with the composite type from a conditional operator. Further, we don't issue
+ * any diagnostics in C17 or earlier when we need at least a pedantic
+ * diagnostic about the type incompatibilities.
+ */
+
+void matrix_fun(int N, const float x[N][N]);
+void test1(void) {
+  int N = 100;
+  float x[N][N];
+  // FIXME: This is OK in C2x but should be diagnosed as passing incompatible
+  // pointer types in C17 and earlier.
+  matrix_fun(N, x);
+}
+
+#define TEST(Expr, Type) _Generic(Expr, Type : 1)
+
+void test2(void) {
+  typedef int array[1];
+  array reg_array;
+  const array const_array;
+
+  // An array and its elements are identically qualified. We have to test this
+  // using pointers to the array and element, because the controlling
+  // expression of _Generic will undergo lvalue conversion, which drops
+  // qualifiers.
+  (void)_Generic(&reg_array, int (*)[1] : 1);
+  (void)_Generic(&reg_array[0], int * : 1);
+
+  (void)_Generic(&const_array, const int (*)[1] : 1);
+  (void)_Generic(&const_array[0], const int * : 1);
+
+  // But identical qualification does *not* apply to the _Atomic specifier,
+  // because that's a special case. You cannot apply the _Atomic specifier or
+  // qualifier to an array type directly.
+  _Atomic array atomic_array;       // expected-error {{_Atomic cannot be applied to array type 'array'}}
+  _Atomic(array) also_atomic_array; // expected-error {{_Atomic cannot be applied to array type 'array'}}
+
+  // Ensure we support arrays of restrict-qualified pointer types.
+  int *restrict array_of_restricted_ptrs[1];
+  int *restrict md_array_of_restricted_ptrs[1][1];
+}
+
+void test3(void) {
+  // Validate that we pick the correct composite type for a conditional
+  // operator in the presence of qualifiers.
+  const int const_array[1];
+  int array[1];
+
+  // FIXME: the type here should be `const int (*)[1]`, but for some reason,
+  // Clang is deciding it's `void *`. This relates to N2607 because the
+  // conditional operator is not properly implementing 6.5.15p7 regarding
+  // qualifiers, despite that wording not being touched by this paper.
+  // However, it should get a pedantic diagnostic in C17 about use of
+  // incompatible pointer types.
+  (void)_Generic(1 ? &const_array : &array, const int (*)[1] : 1);   /* expected-error {{controlling expression type 'void *' not compatible with any generic association type}}
+                                                                        expected-warning {{pointer type mismatch ('const int (*)[1]' and 'int (*)[1]')}}
+                                                                      */
+}
index 2729677..764c7c5 100644 (file)
@@ -829,7 +829,15 @@ conformance.</p>
     <tr>
       <td>Compatibility of Pointers to Arrays with Qualifiers</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2607.pdf">N2607</a></td>
-      <td class="partial" align="center">Partial</td>
+      <td class="partial" align="center">
+        <details><summary>Partial</summary>
+          Much of the proposal is implemented, but Clang lacks pedantic diagnostics
+          in C17 and earlier regarding use of incompatible pointer types as an
+          extension. Further, Clang does not properly compute the correct result
+          type for the <code>?:</code> operator when the result type should be a
+          qualified array type.
+        </details>
+      </td>
     </tr>
     <tr>
       <td>Unclear type relationship between a format specifier and its argument</td>