diff options
author | Jason Merrill <jason@redhat.com> | 2021-04-14 17:27:19 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-04-16 01:16:03 -0400 |
commit | 89c863488bc8c7315596bcb753173aa2fd8be727 (patch) | |
tree | 23f643de494414e8cbb18cf5d22fc3007daac151 /gcc/cp/tree.c | |
parent | ee351f7fdbd82f8947fe9a0e74cea65d216a8549 (diff) | |
download | gcc-89c863488bc8c7315596bcb753173aa2fd8be727.tar.gz |
c++: C++20 class NTTP trailing zero-init [PR100079]
The new testcase was breaking because constexpr evaluation was simplifying
Bar{Baz<42>{}} to Bar{empty}, but then we weren't treating them as
equivalent. Poking at this revealed that the code for eliding trailing
zero-initialization in class non-type template argument mangling was pretty
broken, including the test, mangle71.
I dealt with the FIXME to support RANGE_EXPR, and fixed the confusion
between a list-initialized temporary mangled as written (i.e. in the
signature of a function template) and a template parameter object mangled as
the value representation of the object. I'm distinguishing between these
using COMPOUND_LITERAL_P. A later patch will adjust the use of
COMPOUND_LITERAL_P to be more useful for this distinction, but it works now
for distinguishing these cases in mangling.
gcc/cp/ChangeLog:
PR c++/100079
* cp-tree.h (first_field): Declare.
* mangle.c (range_expr_nelts): New.
(write_expression): Improve class NTTP mangling.
* pt.c (get_template_parm_object): Clear TREE_HAS_CONSTRUCTOR.
* tree.c (zero_init_expr_p): Improve class NTTP handling.
* decl.c: Adjust comment.
gcc/testsuite/ChangeLog:
PR c++/100079
* g++.dg/abi/mangle71.C: Fix expected mangling.
* g++.dg/abi/mangle77.C: New test.
* g++.dg/cpp2a/nontype-class-union1.C: Likewise.
* g++.dg/cpp2a/nontype-class-equiv1.C: Removed.
* g++.dg/cpp2a/nontype-class44.C: New test.
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r-- | gcc/cp/tree.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index dca947bf52a..a8bfd5fc053 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -4680,20 +4680,30 @@ zero_init_expr_p (tree t) tree type = TREE_TYPE (t); if (!type || uses_template_parms (type)) return false; - if (zero_init_p (type)) - return initializer_zerop (t); if (TYPE_PTRMEM_P (type)) return null_member_pointer_value_p (t); - if (TREE_CODE (t) == CONSTRUCTOR - && CP_AGGREGATE_TYPE_P (type)) + if (TREE_CODE (t) == CONSTRUCTOR) { - tree elt_init; - unsigned HOST_WIDE_INT i; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, elt_init) - if (!zero_init_expr_p (elt_init)) - return false; + if (CONSTRUCTOR_IS_DEPENDENT (t) + || BRACE_ENCLOSED_INITIALIZER_P (t)) + /* Undigested, conversions might change the zeroness. + + Other COMPOUND_LITERAL_P in template context are also undigested, + but there isn't currently a way to distinguish between them and + COMPOUND_LITERAL_P from non-template context that are digested. */ + return false; + for (constructor_elt &elt : CONSTRUCTOR_ELTS (t)) + { + if (TREE_CODE (type) == UNION_TYPE + && elt.index != first_field (type)) + return false; + if (!zero_init_expr_p (elt.value)) + return false; + } return true; } + if (zero_init_p (type)) + return initializer_zerop (t); return false; } |