summaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-14 17:27:19 -0400
committerJason Merrill <jason@redhat.com>2021-04-16 01:16:03 -0400
commit89c863488bc8c7315596bcb753173aa2fd8be727 (patch)
tree23f643de494414e8cbb18cf5d22fc3007daac151 /gcc/cp/tree.c
parentee351f7fdbd82f8947fe9a0e74cea65d216a8549 (diff)
downloadgcc-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.c28
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;
}