diff options
author | Martin Sebor <msebor@gmail.com> | 2020-04-22 02:27:54 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-22 02:27:54 -0400 |
commit | 587970215f4681def390e2a791aa3ba6adb65158 (patch) | |
tree | 7fa9b0fe0ce7efd2a32648ee5a9accf301858ea5 /gcc/cp/mangle.c | |
parent | 0fe9eaaa083b6cc032cbd3ad1286b1dd73ccdf54 (diff) | |
download | gcc-587970215f4681def390e2a791aa3ba6adb65158.zip gcc-587970215f4681def390e2a791aa3ba6adb65158.tar.gz gcc-587970215f4681def390e2a791aa3ba6adb65158.tar.bz2 |
c++: reject scalar array initialization with nullptr [PR94510]
The change committed to GCC 9 to allow string literals as template arguments
caused the compiler to prune away, and thus miss diagnosing, conversion from
nullptr to int in an array initializer. After looking at various approaches
to improving the pruning, we realized that the only place the pruning is
necessary is in the mangler.
gcc/cp/ChangeLog
2020-04-22 Martin Sebor <msebor@redhat.com>
Jason Merrill <jason@redhat.com>
PR c++/94510
* decl.c (reshape_init_array_1): Avoid stripping redundant trailing
zero initializers...
* mangle.c (write_expression): ...and handle them here even for
pointers to members by calling zero_init_expr_p.
* cp-tree.h (zero_init_expr_p): Declare.
* tree.c (zero_init_expr_p): Define.
(type_initializer_zero_p): Remove.
* pt.c (tparm_obj_values): New hash_map.
(get_template_parm_object): Store to it.
(tparm_object_argument): New.
gcc/testsuite/ChangeLog
2020-04-22 Martin Sebor <msebor@redhat.com>
PR c++/94510
* g++.dg/init/array58.C: New test.
* g++.dg/init/array59.C: New test.
* g++.dg/cpp2a/nontype-class34.C: New test.
* g++.dg/cpp2a/nontype-class35.C: New test.
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r-- | gcc/cp/mangle.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 9e39cfd..090fb52 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3176,7 +3176,8 @@ write_expression (tree expr) write_type (etype); } - if (!initializer_zerop (expr) || !trivial_type_p (etype)) + bool nontriv = !trivial_type_p (etype); + if (nontriv || !zero_init_expr_p (expr)) { /* Convert braced initializer lists to STRING_CSTs so that A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while @@ -3187,19 +3188,22 @@ write_expression (tree expr) if (TREE_CODE (expr) == CONSTRUCTOR) { vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr); - unsigned last_nonzero = -1, i; + unsigned last_nonzero = UINT_MAX, i; tree val; - FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) - if (!initializer_zerop (val)) - last_nonzero = i; + if (!nontriv) + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + if (!zero_init_expr_p (val)) + last_nonzero = i; - FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) - { - if (i > last_nonzero) - break; - write_expression (val); - } + if (nontriv || last_nonzero != UINT_MAX) + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + { + if (i > last_nonzero) + break; + /* FIXME handle RANGE_EXPR */ + write_expression (val); + } } else { @@ -3525,7 +3529,7 @@ write_template_arg (tree node) if (template_parm_object_p (node)) /* We want to mangle the argument, not the var we stored it in. */ - node = DECL_INITIAL (node); + node = tparm_object_argument (node); /* Strip a conversion added by convert_nontype_argument. */ if (TREE_CODE (node) == IMPLICIT_CONV_EXPR) |