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); +}