mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
d022c55a4b
commit
34bbc4c502
|
@ -882,6 +882,9 @@ Driver Undocumented
|
|||
; identity, such as ia32 calling convention attributes (stdcall, etc.)
|
||||
; Default in G++ 6 (set in c_common_post_options).
|
||||
;
|
||||
; 11: The version of the ABI that corrects mangling of sizeof... expressions.
|
||||
; Default in G++ 7.
|
||||
;
|
||||
; Additional positive integers will be assigned as new versions of
|
||||
; the ABI become the default version of the ABI.
|
||||
fabi-version=
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// Test for sZ mangling.
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-final { scan-assembler "_Z1fIJidEEv1AIXsZT_EE" } }
|
||||
|
||||
template <int I> struct A { };
|
||||
template <typename... Ts> void f(A<sizeof...(Ts)>);
|
||||
|
||||
int main()
|
||||
{
|
||||
f<int,double>(A<2>());
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Test for sZ mangling.
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-final { scan-assembler "_Z1fIJidEEv1AIXstDpT_EE" } }
|
||||
// { dg-options -fabi-version=9 }
|
||||
|
||||
template <int I> struct A { };
|
||||
template <typename... Ts> void f(A<sizeof...(Ts)>);
|
||||
|
||||
int main()
|
||||
{
|
||||
f<int,double>(A<2>());
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Testcase from cxx-abi-dev.
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A {
|
||||
template<int...T> using N = int[sizeof...(T)];
|
||||
template<int...A> void f(N<A...> &);
|
||||
|
||||
template<typename...T> using M = int[sizeof...(T)];
|
||||
template<typename...A> void g(M<A...> &);
|
||||
};
|
||||
void g(A a)
|
||||
{
|
||||
int arr[3];
|
||||
// { dg-final { scan-assembler "_ZN1A1fIJLi1ELi2ELi3EEEEvRAsZT__i" } }
|
||||
a.f<1,2,3>(arr);
|
||||
// { dg-final { scan-assembler "_ZN1A1gIJiiiEEEvRAsZT__i" } }
|
||||
a.g<int,int,int>(arr);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Testcase from cxx-abi-dev.
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-fabi-version=9" }
|
||||
|
||||
struct A {
|
||||
template<int...T> using N = int[sizeof...(T)];
|
||||
template<int...A> void f(N<A...> &);
|
||||
|
||||
template<typename...T> using M = int[sizeof...(T)];
|
||||
template<typename...A> void g(M<A...> &);
|
||||
};
|
||||
void g(A a)
|
||||
{
|
||||
int arr[3];
|
||||
// { dg-final { scan-assembler "_ZN1A1fIJLi1ELi2ELi3EEEEvRAszspT__i" } }
|
||||
a.f<1,2,3>(arr);
|
||||
// { dg-final { scan-assembler "_ZN1A1gIJiiiEEEvRAstDpT__i" } }
|
||||
a.g<int,int,int>(arr);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// Testcase from cxx-abi-dev.
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_" } }
|
||||
|
||||
struct A {
|
||||
template<typename...T> using N = int[sizeof...(T)];
|
||||
template<typename...A, typename B, typename...C>
|
||||
void f(N<A..., B, C...> &, B, C...);
|
||||
};
|
||||
void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
|
|
@ -0,0 +1,11 @@
|
|||
// Testcase from cxx-abi-dev.
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options -fabi-version=9 }
|
||||
// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAstDpT1__iT0_S2_" } }
|
||||
|
||||
struct A {
|
||||
template<typename...T> using N = int[sizeof...(T)];
|
||||
template<typename...A, typename B, typename...C>
|
||||
void f(N<A..., B, C...> &, B, C...);
|
||||
};
|
||||
void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
|
|
@ -1,3 +1,10 @@
|
|||
2016-07-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2016-07-13 Marcel BÃhme <boehme.marcel@gmail.com>
|
||||
|
||||
PR c++/70926
|
||||
|
|
|
@ -466,6 +466,7 @@ static struct demangle_component *
|
|||
d_template_param (struct d_info *);
|
||||
|
||||
static struct demangle_component *d_template_args (struct d_info *);
|
||||
static struct demangle_component *d_template_args_1 (struct d_info *);
|
||||
|
||||
static struct demangle_component *
|
||||
d_template_arg (struct d_info *);
|
||||
|
@ -1795,6 +1796,8 @@ const struct demangle_operator_info cplus_demangle_operators[] =
|
|||
{ "rc", NL ("reinterpret_cast"), 2 },
|
||||
{ "rm", NL ("%"), 2 },
|
||||
{ "rs", NL (">>"), 2 },
|
||||
{ "sP", NL ("sizeof..."), 1 },
|
||||
{ "sZ", NL ("sizeof..."), 1 },
|
||||
{ "sc", NL ("static_cast"), 2 },
|
||||
{ "st", NL ("sizeof "), 1 },
|
||||
{ "sz", NL ("sizeof "), 1 },
|
||||
|
@ -2994,6 +2997,19 @@ d_template_param (struct d_info *di)
|
|||
|
||||
static struct demangle_component *
|
||||
d_template_args (struct d_info *di)
|
||||
{
|
||||
if (d_peek_char (di) != 'I'
|
||||
&& d_peek_char (di) != 'J')
|
||||
return NULL;
|
||||
d_advance (di, 1);
|
||||
|
||||
return d_template_args_1 (di);
|
||||
}
|
||||
|
||||
/* <template-arg>* E */
|
||||
|
||||
static struct demangle_component *
|
||||
d_template_args_1 (struct d_info *di)
|
||||
{
|
||||
struct demangle_component *hold_last_name;
|
||||
struct demangle_component *al;
|
||||
|
@ -3004,11 +3020,6 @@ d_template_args (struct d_info *di)
|
|||
constructor or destructor. */
|
||||
hold_last_name = di->last_name;
|
||||
|
||||
if (d_peek_char (di) != 'I'
|
||||
&& d_peek_char (di) != 'J')
|
||||
return NULL;
|
||||
d_advance (di, 1);
|
||||
|
||||
if (d_peek_char (di) == 'E')
|
||||
{
|
||||
/* An argument pack can be empty. */
|
||||
|
@ -3270,6 +3281,8 @@ d_expression_1 (struct d_info *di)
|
|||
if (op->type == DEMANGLE_COMPONENT_CAST
|
||||
&& d_check_char (di, '_'))
|
||||
operand = d_exprlist (di, 'E');
|
||||
else if (code && !strcmp (code, "sP"))
|
||||
operand = d_template_args_1 (di);
|
||||
else
|
||||
operand = d_expression_1 (di);
|
||||
|
||||
|
@ -4289,6 +4302,30 @@ d_pack_length (const struct demangle_component *dc)
|
|||
return count;
|
||||
}
|
||||
|
||||
/* Returns the number of template args in DC, expanding any pack expansions
|
||||
found there. */
|
||||
|
||||
static int
|
||||
d_args_length (struct d_print_info *dpi, const struct demangle_component *dc)
|
||||
{
|
||||
int count = 0;
|
||||
for (; dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST;
|
||||
dc = d_right (dc))
|
||||
{
|
||||
struct demangle_component *elt = d_left (dc);
|
||||
if (elt == NULL)
|
||||
break;
|
||||
if (elt->type == DEMANGLE_COMPONENT_PACK_EXPANSION)
|
||||
{
|
||||
struct demangle_component *a = d_find_pack (dpi, d_left (elt));
|
||||
count += d_pack_length (a);
|
||||
}
|
||||
else
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* DC is a component of a mangled expression. Print it, wrapped in parens
|
||||
if needed. */
|
||||
|
||||
|
@ -5125,6 +5162,21 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
|
|||
}
|
||||
}
|
||||
|
||||
/* For sizeof..., just print the pack length. */
|
||||
if (code && !strcmp (code, "sZ"))
|
||||
{
|
||||
struct demangle_component *a = d_find_pack (dpi, operand);
|
||||
int len = d_pack_length (a);
|
||||
d_append_num (dpi, len);
|
||||
return;
|
||||
}
|
||||
else if (code && !strcmp (code, "sP"))
|
||||
{
|
||||
int len = d_args_length (dpi, operand);
|
||||
d_append_num (dpi, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op->type != DEMANGLE_COMPONENT_CAST)
|
||||
d_print_expr_op (dpi, options, op);
|
||||
else
|
||||
|
|
|
@ -4536,6 +4536,12 @@ void baz<int>(A<sizeof (foo((int)(), (floatcomplex )00000000_00000000))>*)
|
|||
--format=gnu-v3
|
||||
_Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv
|
||||
X<sizeof ((P(((F)())())).array)>::Type foo<F>()
|
||||
|
||||
_Z1fIJidEEv1AIXsZT_EE
|
||||
void f<int, double>(A<2>)
|
||||
|
||||
_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_
|
||||
void A::f<int, int, int, int, int, int>(int (&) [6], int, int, int, int)
|
||||
#
|
||||
# Tests a use-after-free problem PR70481
|
||||
|
||||
|
|
Loading…
Reference in New Issue