diff options
author | Joseph Myers <joseph@codesourcery.com> | 2023-02-10 00:42:47 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2023-02-10 00:42:47 +0000 |
commit | b9f8935e110c392c21460db838b4209c32f070c2 (patch) | |
tree | 329ad18e382724a5d148e1cb74b5f66fec86d69e /gcc/c | |
parent | 41015797ad14bc9030a87d102e4ab1ad891345f6 (diff) | |
download | gcc-b9f8935e110c392c21460db838b4209c32f070c2.zip gcc-b9f8935e110c392c21460db838b4209c32f070c2.tar.gz gcc-b9f8935e110c392c21460db838b4209c32f070c2.tar.bz2 |
c: Allow conversions of null pointer constants to nullptr_t
WG14 has agreed to allow conversions (explicit and implicit) from null
pointer constants to nullptr_t; update GCC's nullptr_t implementation
to match.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/c/
* c-convert.cc (c_convert): Allow conversion of a null pointer
constant to nullptr_t.
* c-typeck.cc (null_pointer_constant_p): Remove static.
(convert_for_assignment): Allow conversion of a null pointer
constant to nullptr_t.
(digest_init): Handle NULLPTR_TYPE among scalar conversions.
* c-tree.h (null_pointer_constant_p): Declare.
gcc/testsuite/
* gcc.dg/c2x-nullptr-1.c: Test conversion of null pointer
constants to nullptr_t.
* gcc.dg/c2x-nullptr-3.c: Do not expect errors for conversion of
null pointer constants to nullptr_t. Do test errors for
conversion of other values to nullptr_t and for unary '+' on
nullptr_t.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-convert.cc | 21 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 1 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 7 |
3 files changed, 23 insertions, 6 deletions
diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc index dccd245..0f35dc4 100644 --- a/gcc/c/c-convert.cc +++ b/gcc/c/c-convert.cc @@ -157,6 +157,19 @@ c_convert (tree type, tree expr, bool init_const) ret = convert_to_pointer (type, e); goto maybe_fold; + case NULLPTR_TYPE: + /* A null pointer constant or value of type nullptr_t may be + converted to nullptr_t. The latter case has already been + handled. build_c_cast will create an additional NOP_EXPR to + ensure the result of the conversion is not itself a null + pointer constant. */ + if (null_pointer_constant_p (expr)) + { + ret = build_int_cst (type, 0); + goto maybe_fold; + } + break; + case REAL_TYPE: ret = convert_to_real (type, e); goto maybe_fold; @@ -201,12 +214,14 @@ c_convert (tree type, tree expr, bool init_const) } /* If we are converting to nullptr_t, don't say "non-scalar type" because - the nullptr_t type is a scalar type. Only nullptr_t shall be converted - to nullptr_t. */ + the nullptr_t type is a scalar type. Only nullptr_t or a null pointer + constant shall be converted to nullptr_t. */ if (code == NULLPTR_TYPE) { error ("conversion from %qT to %qT", TREE_TYPE (e), type); - inform (input_location, "only %qT can be converted to %qT", type, type); + inform (input_location, + "only %qT or a null pointer constant can be converted to %qT", + type, type); } else error ("conversion to non-scalar type requested"); diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 00ccf87..e5eefe6 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -728,6 +728,7 @@ extern location_t c_last_sizeof_loc; extern struct c_switch *c_switch_stack; +extern bool null_pointer_constant_p (const_tree); extern bool char_type_p (tree); extern tree c_objc_common_truthvalue_conversion (location_t, tree); extern tree require_complete_type (location_t, tree); diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 157b77e..e37b097 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -89,7 +89,6 @@ static bool require_constant_value; static bool require_constant_elements; static bool require_constexpr_value; -static bool null_pointer_constant_p (const_tree); static tree qualify_type (tree, tree); static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *, bool *); @@ -130,7 +129,7 @@ static int comptypes_internal (const_tree, const_tree, bool *, bool *); /* Return true if EXP is a null pointer constant, false otherwise. */ -static bool +bool null_pointer_constant_p (const_tree expr) { /* This should really operate on c_expr structures, but they aren't @@ -7837,6 +7836,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, in_late_binary_op = save; return ret; } + else if (codel == NULLPTR_TYPE && null_pointer_constant) + return convert (type, rhs); switch (errtype) { @@ -8596,7 +8597,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, if (code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE - || code == COMPLEX_TYPE || code == VECTOR_TYPE) + || code == COMPLEX_TYPE || code == VECTOR_TYPE || code == NULLPTR_TYPE) { tree unconverted_init = inside_init; if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE |