Am Freitag, den 01.01.2021, 00:01 +0000 schrieb Joseph Myers:
> 
> 
> I'd expect c2x-* tests to use -std=c2x not -std=gnu2x.  Tests needing 
> -std=gnu2x can be gnu2x-* tests, but you should be able to test the types 
> using _Generic without needing any gnu2x features.  c2x-* tests should 
> also use -pedantic or -pedantic-errors unless they are specifically 
> testing something that doesn't work with those options.
> 
> There should also be tests for cases where code is valid before C2x but 
> invalid in C2x (assignment storing a pointer-to-qualified-array in void *, 
> for example).
> 
> All the tests should have both c2x-* and c11-* variants so the testsuite 
> verifies that the code is properly handled in C11 mode (warnings with 
> -pedantic, errors with -pedantic-errors, in the cases that are invalid for 
> C11 but valid for C2x).  There should also be -Wc11-c2x-compat tests with 
> -std=c2x where appropriate.


Here is a revised version which adds some missing warnings 
and also fixed some error regarding which warnings got emitted.

I added tests for C2X that test with std=c2x and -pedantic-errors
with and without -Wc11-c2x-compat. In the conditional operator
I directly test for the type using _Generic and _Static_assert.
This test also exists for c11 testing for the old behavior.

I did not add tests for c11 for warnings because we already
had warnings before and the tests for these exist. (I removed 
-Wdiscarded-array-qualifiers from the old tests as this flag
is not needed.) Or should there be additional warnings
with -Wc11-c2x-compat for c11? But warning twice about
the same issue does not seem ideal...

More comments?

Best,
Martin


diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 67c0080a5ef..243790e7abf 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,39 @@ 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))))
-           warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers,
-                       "pointer to array loses qualifier "
-                       "in conditional expression");
-
-         if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
+      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 ((TREE_CODE (t2) == ARRAY_TYPE)
+             && (TYPE_QUALS (t2_stripped) & ~TYPE_QUALS (t1)))
+           {
+             if (!flag_isoc2x)
+               warning_at (colon_loc, OPT_Wdiscarded_array_qualifiers,
+                           "pointer to array loses qualifier "
+                           "in conditional expression");
+             else if (warn_c11_c2x_compat > 0)
+               warning_at (colon_loc, OPT_Wc11_c2x_compat,
+                           "pointer to array does not lose qualifier in C2X "
+                           "in conditional expression");
+           }
+         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 (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)
-           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)));
+         if (flag_isoc2x)
+           t2 = t2_stripped;
+         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))
@@ -7316,15 +7316,16 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
          else if (TREE_CODE (ttr) != FUNCTION_TYPE
                   && TREE_CODE (ttl) != FUNCTION_TYPE)
            {
+              /* Assignments between atomic and non-atomic objects are OK.  */
+              bool warn_quals_ped = TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
+                                    & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC 
(ttl);
+              bool warn_quals = TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
+                                & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC 
(strip_array_types (ttl));
+
              /* 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)
-               ttl = strip_array_types (ttl);
-
-             /* Assignments between atomic and non-atomic objects are OK.  */
-             if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
-                 & ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl))
+             if (warn_quals || (warn_quals_ped && pedantic && !flag_isoc2x))
                {
                  PEDWARN_FOR_QUALIFIERS (location, expr_loc,
                                          OPT_Wdiscarded_qualifiers,
@@ -7338,6 +7339,10 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
                                             "pointer target type"),
                                          TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
                }
+             else if (warn_quals_ped && pedantic && flag_isoc2x && 
(warn_c11_c2x_compat > 0))
+               pedwarn (expr_loc, OPT_Wc11_c2x_compat,
+                                  "array with qualifier on the element is not 
qualified before
C2X");
+
              /* If this is not a case of ignoring a mismatch in signedness,
                 no warning.  */
              else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
diff --git a/gcc/testsuite/gcc.dg/c11-qual-1.c 
b/gcc/testsuite/gcc.dg/c11-qual-1.c
new file mode 100644
index 00000000000..f731e068830
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-qual-1.c
@@ -0,0 +1,11 @@
+/* Test that qualifiers are lost in tertiary operator for pointers to arrays 
before C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors -Wno-discarded-array-qualifiers" } 
*/
+
+void foo(void)
+{
+       const int (*u)[1];
+       void *v;
+       _Static_assert(_Generic(1 ? u : v, const void*: 0, void*: 1), 
"qualifier not lost");
+       _Static_assert(_Generic(1 ? v : u, const void*: 0, void*: 1), 
"qualifier not lost");
+}
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..d53dc214f91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-1.c
@@ -0,0 +1,11 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+void foo(void)
+{
+       const int (*u)[1];
+       void *v;
+       _Static_assert(_Generic(1 ? u : v, const void*: 1, void*: 0), "lost 
qualifier");
+       _Static_assert(_Generic(1 ? v : u, const void*: 1, void*: 0), "lost 
qualifier");
+}
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..3304410bb96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-2.c
@@ -0,0 +1,12 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+void foo(void)
+{
+       const int (*u)[1];
+       void *v;
+       _Static_assert(_Generic(1 ? u : v, const void*: 1, void*: 0), "lost 
qualifier");        /*
{ dg-warning "pointer to array does not lose qualifier in C2X" } */
+       _Static_assert(_Generic(1 ? v : u, const void*: 1, void*: 0), "lost 
qualifier");        /*
{ dg-warning "pointer to array does not lose qualifier in C2X" } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-3.c 
b/gcc/testsuite/gcc.dg/c2x-qual-3.c
new file mode 100644
index 00000000000..58fe16fed94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-3.c
@@ -0,0 +1,9 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+void f(void)
+{
+       int (*x)[3];
+       const int (*p)[3] = x;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-4.c 
b/gcc/testsuite/gcc.dg/c2x-qual-4.c
new file mode 100644
index 00000000000..e04668eb752
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-4.c
@@ -0,0 +1,9 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+void f(void)
+{
+       int (*x)[3];
+       const int (*p)[3] = x; /* { dg-warning "pointers to arrays with 
different qualifiers are
incompatible in ISO C before C2X"  } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-5.c 
b/gcc/testsuite/gcc.dg/c2x-qual-5.c
new file mode 100644
index 00000000000..4647d0b0dfe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-5.c
@@ -0,0 +1,9 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+void f(void)
+{
+       const void* x;
+       const int (*p)[3] = x;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-qual-6.c 
b/gcc/testsuite/gcc.dg/c2x-qual-6.c
new file mode 100644
index 00000000000..dca50ac014f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-qual-6.c
@@ -0,0 +1,9 @@
+/* Test related to qualifiers and pointers to arrays in C2X, PR98397 */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+void f(void)
+{
+       const void* x;
+       const int (*p)[3] = x; /* { dg-error "array with qualifier on the 
element is not qualified
before C2X" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c 
b/gcc/testsuite/gcc.dg/pointer-array-
quals-1.c
index 921a37e9e0d..498ab223162 100644
--- a/gcc/testsuite/gcc.dg/pointer-array-quals-1.c
+++ b/gcc/testsuite/gcc.dg/pointer-array-quals-1.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* Origin: Martin Uecker <uec...@eecs.berkeley.edu> */
-/* { dg-options "-Wdiscarded-array-qualifiers" } */
+/* { dg-options "" } */
 void tvoid(void* x);
 void transpose0(double* out, const double* in) { }
 void transpose1(double out[2][2], const double in[2][2]) { }
diff --git a/gcc/testsuite/gcc.dg/pointer-array-quals-2.c 
b/gcc/testsuite/gcc.dg/pointer-array-
quals-2.c
index 30689c7312d..4c95d8a3a78 100644
--- a/gcc/testsuite/gcc.dg/pointer-array-quals-2.c
+++ b/gcc/testsuite/gcc.dg/pointer-array-quals-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wdiscarded-array-qualifiers -pedantic-errors" } */
+/* { dg-options "-pedantic-errors" } */
 /* Origin: Martin Uecker <uec...@eecs.berkeley.edu> */
 void tvoid(void* x);
 void transpose0(double* out, const double* in) { }

Reply via email to