[PATCH] reject scalar array initialization with nullptr [PR94510]
Marek Polacek
polacek@redhat.com
Tue Apr 7 19:50:51 GMT 2020
On Tue, Apr 07, 2020 at 12:50:48PM -0600, Martin Sebor via Gcc-patches wrote:
> Among the numerous regressions introduced by the change committed
> to GCC 9 to allow string literals as template arguments is a failure
> to recognize the C++ nullptr and GCC's __null constants as pointers.
> For one, I didn't realize that nullptr, being a null pointer constant,
> doesn't have a pointer type, and two, I didn't think of __null (which
> is a special integer constant that NULL sometimes expands to).
>
> The attached patch adjusts the special handling of trailing zero
> initializers in reshape_init_array_1 to recognize both kinds of
> constants and avoid treating them as zeros of the array integer
> element type. This restores the expected diagnostics when either
> constant is used in the initializer list.
>
> Martin
> PR c++/94510 - nullptr_t implicitly cast to zero twice in std::array
>
> gcc/cp/ChangeLog:
>
> PR c++/94510
> * decl.c (reshape_init_array_1): Exclude mismatches with all kinds
> of pointers.
>
> gcc/testsuite/ChangeLog:
>
> PR c++/94510
> * g++.dg/init/array57.C: New test.
> * g++.dg/init/array58.C: New test.
>
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index a127734af69..692c8ed73f4 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -6041,9 +6041,14 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
> TREE_CONSTANT (new_init) = false;
>
> /* Pointers initialized to strings must be treated as non-zero
> - even if the string is empty. */
> + even if the string is empty. Handle all kinds of pointers,
> + including std::nullptr and GCC's __nullptr, neither of which
> + has a pointer type. */
> tree init_type = TREE_TYPE (elt_init);
> - if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
> + bool init_is_ptr = (POINTER_TYPE_P (init_type)
> + || NULLPTR_TYPE_P (init_type)
> + || null_node_p (elt_init));
> + if (POINTER_TYPE_P (elt_type) != init_is_ptr
> || !type_initializer_zero_p (elt_type, elt_init))
> last_nonzero = index;
It looks like this still won't handle e.g. pointers to member functions,
e.g.
struct S { };
int arr[3] = { (void (S::*) ()) 0, 0, 0 };
would still be accepted. You could use TYPE_PTR_OR_PTRMEM_P instead of
POINTER_TYPE_P to catch this case.
Marek
More information about the Gcc-patches
mailing list