Here is a patch that adds the minor corrections needed for
qualifiers of pointers to arrays in C23.

-- Martin


C: Correct qualifiers for pointers to arrays according to C2X [PR98397]
    
2020-12-12  Martin Uecker  <muec...@gwdg.de>
    
gcc/c/
     PR c/98397
     * c-typeck.c (comp_target_types): Change pedwarn to pedwarn_c11
     for pointers to arrays with qualifiers.      
     (build_conditional_expr): For C23 don't lose qualifiers for pointers
     to arrays when the other pointer is a void pointer.
     (convert_for_assignment): For C23 don't pedwarn when converting from
     void* with qualifiers to a pointer to array with the same qualifiers.

gcc/testsuite/
     PR c/98397
     * gcc.dg/c2x-qual-1.c: New test.   
     * gcc.dg/c2x-qual-2.c: New test.


diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index f68cb01529b..46a66e96db5 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -1318,8 +1318,8 @@ comp_target_types (location_t location, tree ttl, tree 
ttr)
   val = comptypes_check_enum_int (mvl, mvr, &enum_and_int_p);
 
   if (val == 1 && val_ped != 1)
-    pedwarn (location, OPT_Wpedantic, "pointers to arrays with different 
qualifiers "
-                                      "are incompatible in ISO C");
+    pedwarn_c11 (location, OPT_Wpedantic, "pointers to arrays with different 
qualifiers "
+                                         "are incompatible in ISO C before 
C2X");
 
   if (val == 2)
     pedwarn (location, OPT_Wpedantic, "types are not quite compatible");
@@ -5331,39 +5331,32 @@ build_conditional_expr (location_t colon_loc, tree 
ifexp, bool ifexp_bcp,
                    "used in conditional expression");
          return error_mark_node;
        }
-      else if (VOID_TYPE_P (TREE_TYPE (type1))
-              && !TYPE_ATOMIC (TREE_TYPE (type1)))
-       {
-         if ((TREE_CODE (TREE_TYPE (type2)) == ARRAY_TYPE)
-             && (TYPE_QUALS (strip_array_types (TREE_TYPE (type2)))
-                 & ~TYPE_QUALS (TREE_TYPE (type1))))
+      else if ((VOID_TYPE_P (TREE_TYPE (type1))
+               && !TYPE_ATOMIC (TREE_TYPE (type1)))
+              || (VOID_TYPE_P (TREE_TYPE (type2))
+                  && !TYPE_ATOMIC (TREE_TYPE (type2))))
+       {
+         tree t1 = TREE_TYPE (type1);
+         tree t2 = TREE_TYPE (type2);
+         if (!VOID_TYPE_P (t1))
+          {
+            /* roles are swapped */
+            t1 = t2;
+            t2 = TREE_TYPE (type1);
+          }
+         tree t2_stripped = strip_array_types (t2);
+         if (flag_isoc2x)
+           t2 = t2_stripped;
+         else if ((TREE_CODE (t2) == ARRAY_TYPE)
+                  && (TYPE_QUALS (t2_stripped) & ~TYPE_QUALS (t1)))
            warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers,
                        "pointer to array loses qualifier "
                        "in conditional expression");
-
-         if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
-           pedwarn (colon_loc, OPT_Wpedantic,
-                    "ISO C forbids conditional expr between "
-                    "%<void *%> and function pointer");
-         result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
-                                                         TREE_TYPE (type2)));
-       }
-      else if (VOID_TYPE_P (TREE_TYPE (type2))
-              && !TYPE_ATOMIC (TREE_TYPE (type2)))
-       {
-         if ((TREE_CODE (TREE_TYPE (type1)) == ARRAY_TYPE)
-             && (TYPE_QUALS (strip_array_types (TREE_TYPE (type1)))
-                 & ~TYPE_QUALS (TREE_TYPE (type2))))
-           warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers,
-                       "pointer to array loses qualifier "
-                       "in conditional expression");
-
-         if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
+         if (TREE_CODE (t2) == FUNCTION_TYPE)
            pedwarn (colon_loc, OPT_Wpedantic,
                     "ISO C forbids conditional expr between "
                     "%<void *%> and function pointer");
-         result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
-                                                         TREE_TYPE (type1)));
+         result_type = build_pointer_type (qualify_type (t1, t2));
        }
       /* Objective-C pointer comparisons are a bit more lenient.  */
       else if (objc_have_common_type (type1, type2, -3, NULL_TREE))
@@ -7319,7 +7312,7 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
              /* Don't warn about loss of qualifier for conversions from
                 qualified void* to pointers to arrays with corresponding
                 qualifier on the element type. */
-             if (!pedantic)
+             if (flag_isoc2x || !pedantic)
                ttl = strip_array_types (ttl);
 
              /* Assignments between atomic and non-atomic objects are OK.  */
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-1.c 
b/gcc/testsuite/gcc.dg/c2x-qual-1.c
new file mode 100644
index 00000000000..058a840e04c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-1.c
@@ -0,0 +1,12 @@
+/* Test that qualifiers are not lost in tertiary operator for pointers to 
arrays, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2x" } */
+
+void foo(void)
+{
+       const int (*u)[1];
+       void *v;
+       extern const void *vc;
+       extern typeof(1 ? u : v) vc;
+       extern typeof(1 ? v : u) vc;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-2.c 
b/gcc/testsuite/gcc.dg/c2x-qual-2.c
new file mode 100644
index 00000000000..68b897226d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-2.c
@@ -0,0 +1,12 @@
+/* Test that there are no warnings about lost qualifiers for pointers to arrays
+   with pedantic for C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu2x -pedantic" } */
+
+void foo(void)
+{
+       const void *w;
+       const int (*u)[1] = w;
+       void *v;
+       (1 ? u : v);
+}

Reply via email to