Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-08-22 Thread Uecker, Martin
Am Donnerstag, den 12.08.2021, 16:58 + schrieb Joseph Myers:
> On Mon, 24 May 2021, Uecker, Martin wrote:
> 
> > -  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
> 
> Here you're unifying the two cases where one argument is (not a null 
> pointer constant and) a pointer to qualified or unqualified void (and the 
> other argument is not a pointer to qualified or unqualified void).  The 
> !TYPE_ATOMIC checks are because of the general rule that _Atomic is a type 
> qualifier only syntactically, so _Atomic void doesn't count as qualified 
> void for this purpose.
> 
> > +   {
> > + tree t1 = TREE_TYPE (type1);
> > + tree t2 = TREE_TYPE (type2);
> > + if (!VOID_TYPE_P (t1))
> > +  {
> > +/* roles are swapped */
> > +t1 = t2;
> > +t2 = TREE_TYPE (type1);
> > +  }
> 
> But here you don't have a TYPE_ATOMIC check before swapping.  So if t1 is 
> _Atomic void and t2 is void, the types don't get swapped.
> 
> > + /* for array, use qualifiers of element type */
> > + if (flag_isoc2x)
> > +   t2 = t2_stripped;
> > + result_type = build_pointer_type (qualify_type (t1, t2));
> 
> And then it looks to me like this will end up with _Atomic void * as the 
> result type, when a conditional expression between _Atomic void * and 
> void * should actually have type void *.
> 
> If that's indeed the case, I think the swapping needs to occur whenever t1 
> is not *non-atomic* void, so that the condition for swapping matches the 
> condition checked in the outer if.  (And of course there should be a 
> testcase for that.)
> 
> I didn't see any other issues in this version of the patch.

Committed with this change and the additional test.

Martin

> 


Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-08-12 Thread Joseph Myers
On Mon, 24 May 2021, Uecker, Martin wrote:

> -  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

Here you're unifying the two cases where one argument is (not a null 
pointer constant and) a pointer to qualified or unqualified void (and the 
other argument is not a pointer to qualified or unqualified void).  The 
!TYPE_ATOMIC checks are because of the general rule that _Atomic is a type 
qualifier only syntactically, so _Atomic void doesn't count as qualified 
void for this purpose.

> + {
> +   tree t1 = TREE_TYPE (type1);
> +   tree t2 = TREE_TYPE (type2);
> +   if (!VOID_TYPE_P (t1))
> +{
> +  /* roles are swapped */
> +  t1 = t2;
> +  t2 = TREE_TYPE (type1);
> +}

But here you don't have a TYPE_ATOMIC check before swapping.  So if t1 is 
_Atomic void and t2 is void, the types don't get swapped.

> +   /* for array, use qualifiers of element type */
> +   if (flag_isoc2x)
> + t2 = t2_stripped;
> +   result_type = build_pointer_type (qualify_type (t1, t2));

And then it looks to me like this will end up with _Atomic void * as the 
result type, when a conditional expression between _Atomic void * and 
void * should actually have type void *.

If that's indeed the case, I think the swapping needs to occur whenever t1 
is not *non-atomic* void, so that the condition for swapping matches the 
condition checked in the outer if.  (And of course there should be a 
testcase for that.)

I didn't see any other issues in this version of the patch.

-- 
Joseph S. Myers
jos...@codesourcery.com


PING^2 [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-08-01 Thread Uecker, Martin
Am Freitag, den 11.06.2021, 21:25 +0200 schrieb Martin Uecker:
> (PING. In case you missed this. Sorry, forgot to CC you.)
> 
> Am Montag, den 24.05.2021, 08:05 +0200 schrieb Martin Uecker:
> > Hi Joseph,
> > 
> > I found some time to update this patch. The only real change
> > of the patch is the qualifier in the conditional expression for
> > pointer to arrays in C2X. All the rest are the warnings,
> > which were wrong in the last version.
> > 
> > I hope I got this correct this time in combination with
> > -pedantic-errors and -Wc11-c2x-compat. 
> > 
> > Martin
> > 
> > 
> > 2021-05-16  Martin Uecker  
> > 
> > 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. Update warnings.
> >  (convert_for_assignment): Update warnings for C2X when converting from
> >  void* with qualifiers to a pointer to array with the same qualifiers.
> > 
> > gcc/testsuite/
> >  PR c/98397
> >  * gcc.dg/c11-qual-1.c: New test.
> >  * gcc.dg/c2x-qual-1.c: New test.
> >  * gcc.dg/c2x-qual-2.c: New test.
> >  * gcc.dg/c2x-qual-3.c: New test.
> >  * gcc.dg/c2x-qual-4.c: New test.
> >  * gcc.dg/c2x-qual-5.c: New test.
> >  * gcc.dg/c2x-qual-6.c: New test.
> >  * gcc.dg/pointer-array-quals-1.c: Remove unnecessary flag.
> >  * gcc.dg/pointer-array-quals-2.c: Remove unnecessary flag.
> > 
> > 
> > diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> > index fc64ef96fb8..5b13656c090 100644
> > --- a/gcc/c/c-typeck.c
> > +++ b/gcc/c/c-typeck.c
> > @@ -1328,8 +1328,8 @@ comp_target_types (location_t location, tree ttl, 
> > tree ttr)
> >val = comptypes_check_enum_int (mvl, mvr, _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, "invalid use of pointers to 
> > arrays with different
> > qualifiers "
> > + "in ISO C before C2X");
> >  
> >if (val == 2)
> >  pedwarn (location, OPT_Wpedantic, "types are not quite compatible");
> > @@ -5396,39 +5396,40 @@ 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 loses qualifier "
> > +   "in conditional expression in ISO C before C2X");
> > +   }
> > + if (TREE_CODE (t2) == FUNCTION_TYPE)
> > pedwarn (colon_loc, OPT_Wpedantic,
> >  "ISO C forbids conditional expr between "
> >  "% 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,
> > 

Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-06-11 Thread Uecker, Martin

(PING. In case you missed this. Sorry, forgot to CC you.)

Am Montag, den 24.05.2021, 08:05 +0200 schrieb Martin Uecker:
> Hi Joseph,
> 
> I found some time to update this patch. The only real change
> of the patch is the qualifier in the conditional expression for
> pointer to arrays in C2X. All the rest are the warnings,
> which were wrong in the last version.
> 
> I hope I got this correct this time in combination with
> -pedantic-errors and -Wc11-c2x-compat. 
> 
> Martin
> 
> 
> 2021-05-16  Martin Uecker  
> 
> 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. Update warnings.
>  (convert_for_assignment): Update warnings for C2X when converting from
>  void* with qualifiers to a pointer to array with the same qualifiers.
> 
> gcc/testsuite/
>  PR c/98397
>  * gcc.dg/c11-qual-1.c: New test.
>  * gcc.dg/c2x-qual-1.c: New test.
>  * gcc.dg/c2x-qual-2.c: New test.
>  * gcc.dg/c2x-qual-3.c: New test.
>  * gcc.dg/c2x-qual-4.c: New test.
>  * gcc.dg/c2x-qual-5.c: New test.
>  * gcc.dg/c2x-qual-6.c: New test.
>  * gcc.dg/pointer-array-quals-1.c: Remove unnecessary flag.
>  * gcc.dg/pointer-array-quals-2.c: Remove unnecessary flag.
> 
> 
> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index fc64ef96fb8..5b13656c090 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -1328,8 +1328,8 @@ comp_target_types (location_t location, tree ttl, tree 
> ttr)
>val = comptypes_check_enum_int (mvl, mvr, _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, "invalid use of pointers to arrays 
> with different
> qualifiers "
> +   "in ISO C before C2X");
>  
>if (val == 2)
>  pedwarn (location, OPT_Wpedantic, "types are not quite compatible");
> @@ -5396,39 +5396,40 @@ 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 loses qualifier "
> + "in conditional expression in ISO C before C2X");
> + }
> +   if (TREE_CODE (t2) == FUNCTION_TYPE)
>   pedwarn (colon_loc, OPT_Wpedantic,
>"ISO C forbids conditional expr between "
>"% 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)
> - 

[C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-05-24 Thread Uecker, Martin

Hi Joseph,

I found some time to update this patch. The only real change
of the patch is the qualifier in the conditional expression for
pointer to arrays in C2X. All the rest are the warnings,
which were wrong in the last version.

I hope I got this correct this time in combination with
-pedantic-errors and -Wc11-c2x-compat. 

Martin


2021-05-16  Martin Uecker  

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. Update warnings.
 (convert_for_assignment): Update warnings for C2X when converting from
 void* with qualifiers to a pointer to array with the same qualifiers.

gcc/testsuite/
 PR c/98397
 * gcc.dg/c11-qual-1.c: New test.
 * gcc.dg/c2x-qual-1.c: New test.
 * gcc.dg/c2x-qual-2.c: New test.
 * gcc.dg/c2x-qual-3.c: New test.
 * gcc.dg/c2x-qual-4.c: New test.
 * gcc.dg/c2x-qual-5.c: New test.
 * gcc.dg/c2x-qual-6.c: New test.
 * gcc.dg/pointer-array-quals-1.c: Remove unnecessary flag.
 * gcc.dg/pointer-array-quals-2.c: Remove unnecessary flag.


diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index fc64ef96fb8..5b13656c090 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -1328,8 +1328,8 @@ comp_target_types (location_t location, tree ttl, tree 
ttr)
   val = comptypes_check_enum_int (mvl, mvr, _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, "invalid use of pointers to arrays 
with different qualifiers "
+ "in ISO C before C2X");
 
   if (val == 2)
 pedwarn (location, OPT_Wpedantic, "types are not quite compatible");
@@ -5396,39 +5396,40 @@ 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 loses qualifier "
+   "in conditional expression in ISO C before C2X");
+   }
+ if (TREE_CODE (t2) == FUNCTION_TYPE)
pedwarn (colon_loc, OPT_Wpedantic,
 "ISO C forbids conditional expr between "
 "% 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 "
-"% and function pointer");
- result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
-

Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-01-18 Thread Joseph Myers
On Sun, 17 Jan 2021, Uecker, Martin wrote:

> 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...

If something is already warned about by default in C11 mode, 
-Wc11-c2x-compat doesn't need to produce extra warnings.

> + int (*x)[3];
> + const int (*p)[3] = x; /* { dg-warning "pointers to arrays with 
> different qualifiers are
> incompatible in ISO C before C2X"  } */

"incompatible" doesn't seem the right wording for the diagnostic.  The 
types are incompatible (i.e. not compatible types) regardless of standard 
version; the issue in this case is the rules for assignment.

> 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 000..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" } */

This is showing a bug in the compiler implementation.  In C2X mode, this 
message should be a warning not a pedwarn because the code is not a 
constraint violation.  -Wc11-c2x-compat should produce a warning 
(independent of -pedantic), but -pedantic-errors should not turn it into 
an error.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2021-01-17 Thread Uecker, Martin
Am Freitag, den 01.01.2021, 00:01 + 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, _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 "
     "% 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,
- 

Re: [C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2020-12-31 Thread Joseph Myers
On Mon, 21 Dec 2020, Uecker, Martin wrote:

> 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 000..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;
> +}

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.

-- 
Joseph S. Myers
jos...@codesourcery.com


[C PATCH] qualifiers of pointers to arrays in C2X [PR 98397]

2020-12-21 Thread Uecker, Martin

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  

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, _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 "
-    "% 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 "
     "% 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 000..058a840e04c
---