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