diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-15 14:38:15 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-15 14:38:15 -0400 |
commit | 34bbc4c502157fb08e6eba1d09380e2599ec3720 (patch) | |
tree | 1ee707547ea5521e317e522ed83b170324ec4a05 /gcc/cp | |
parent | d022c55a4b8bdac385efadf42ba2a374c5960418 (diff) | |
download | gcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.zip gcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.tar.gz gcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.tar.bz2 |
PR c++/71814 - mangling sizeof... (sP and sZ)
gcc/cp/
* mangle.c (write_expression): Handle sizeof... an argument pack.
libiberty/
* cp-demangle.c (cplus_demangle_operators): Add sP and sZ.
(d_print_comp_inner): Handle them.
(d_template_args_1): Split out from d_template_args.
(d_args_length): New.
From-SVN: r238389
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 71 |
2 files changed, 64 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1ef3812..eb4f0b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2016-07-15 Jason Merrill <jason@redhat.com> + PR c++/71814 + * mangle.c (write_expression): Handle sizeof... an argument pack. + PR c++/71718 * pt.c (push_tinst_level_loc): Set at_eof before fatal_error. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 0e44409..8205da9 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2767,17 +2767,67 @@ write_expression (tree expr) write_mangled_name (expr, false); write_char ('E'); } - else if (TREE_CODE (expr) == SIZEOF_EXPR - && SIZEOF_EXPR_TYPE_P (expr)) + else if (TREE_CODE (expr) == SIZEOF_EXPR) { - write_string ("st"); - write_type (TREE_TYPE (TREE_OPERAND (expr, 0))); - } - else if (TREE_CODE (expr) == SIZEOF_EXPR - && TYPE_P (TREE_OPERAND (expr, 0))) - { - write_string ("st"); - write_type (TREE_OPERAND (expr, 0)); + tree op = TREE_OPERAND (expr, 0); + + if (PACK_EXPANSION_P (op)) + { + if (abi_warn_or_compat_version_crosses (11)) + G.need_abi_warning = true; + if (abi_version_at_least (11)) + { + /* sZ rather than szDp. */ + write_string ("sZ"); + write_expression (PACK_EXPANSION_PATTERN (op)); + return; + } + } + + if (SIZEOF_EXPR_TYPE_P (expr)) + { + write_string ("st"); + write_type (TREE_TYPE (op)); + } + else if (ARGUMENT_PACK_P (op)) + { + tree args = ARGUMENT_PACK_ARGS (op); + int length = TREE_VEC_LENGTH (args); + if (abi_warn_or_compat_version_crosses (10)) + G.need_abi_warning = true; + if (abi_version_at_least (10)) + { + /* sP <template-arg>* E # sizeof...(T), size of a captured + template parameter pack from an alias template */ + write_string ("sP"); + for (int i = 0; i < length; ++i) + write_template_arg (TREE_VEC_ELT (args, i)); + write_char ('E'); + } + else + { + /* In GCC 5 we represented this sizeof wrong, with the effect + that we mangled it as the last element of the pack. */ + tree arg = TREE_VEC_ELT (args, length-1); + if (TYPE_P (op)) + { + write_string ("st"); + write_type (arg); + } + else + { + write_string ("sz"); + write_expression (arg); + } + } + } + else if (TYPE_P (TREE_OPERAND (expr, 0))) + { + write_string ("st"); + write_type (TREE_OPERAND (expr, 0)); + } + else + goto normal_expr; } else if (TREE_CODE (expr) == ALIGNOF_EXPR && TYPE_P (TREE_OPERAND (expr, 0))) @@ -2947,6 +2997,7 @@ write_expression (tree expr) } else { + normal_expr: int i, len; const char *name; |