This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++/libiberty PATCH for mangling updates
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 17 Mar 2009 19:28:49 -0400
- Subject: C++/libiberty PATCH for mangling updates
As it turns out, my clever idea about using type stubs to simplify the
mangling of decltype types was a bit too clever; it can create symbol
collisions between function templates that can be distinguished with
SFINAE. So we're back to mangling the expressions as written. This
required me to set DECL_CONTEXT on the parms so I can tell what their
position is in the list of parms...and then deal with updating
DECL_CONTEXT when we smash decls together, which was enough of a
headache before that it motivated me to come up with type stubs so that
I wouldn't have to. But there it is.
This patch also adds new manglings for alignof and functional casts with
0 or more than 1 argument.
Tested x86_64-pc-linux-gnu. I'm applying now because it affects the ABI.
2009-03-17 Jason Merrill <jason@redhat.com>
cp/:
* decl.c (grokfndecl): Set DECL_CONTEXT on parms.
(duplicate_decls): Adjust DECL_CONTEXT of newdecl's parms.
* pt.c (check_explicit_specialization): Likewise.
(tsubst_copy) [PARM_DECL]: Return a dummy parm if we don't have a
local specialization.
* tree.c (cp_tree_equal) [PARM_DECL]: Check type and index, not name.
* decl2.c (parm_index): New fn.
* semantics.c (finish_decltype_type): Don't use describable_type.
* mangle.c (write_expression): Likewise. Mangle ALIGNOF_EXPR.
Give a sorry for unsupported codes rather than crash. Mangle
conversions with other than 1 operand. New mangling for PARM_DECL.
* operators.def (ALIGNOF_EXPR): Mangle as "az".
* include/demangle.h (enum demangle_component_type): Add
DEMANGLE_COMPONENT_FUNCTION_PARAM.
* libiberty/cp-demangle.c (d_make_function_param): new fn.
(cplus_demangle_mangled_name): Work around abi v2 bug.
(d_expr_primary): Likewise.
(cplus_demangle_operators): Add alignof ops.
(d_expression): Handle function parameters and conversions
with other than 1 operand.
(d_print_comp): Handle function parameters. Fix bug with
function used in type of function.
Index: gcc/cp/mangle.c
===================================================================
*** gcc/cp/mangle.c (revision 144771)
--- gcc/cp/mangle.c (working copy)
*************** write_expression (tree expr)
*** 2143,2169 ****
{
enum tree_code code = TREE_CODE (expr);
- /* Inside decltype we can simplify some expressions, since we're only
- interested in the type. */
- if (skip_evaluation)
- {
- tree type = describable_type (expr);
- if (type == NULL_TREE)
- ;
- else if (TREE_CODE (type) == REFERENCE_TYPE)
- {
- write_string ("sT");
- write_type (TREE_TYPE (type));
- return;
- }
- else
- {
- write_string ("sR");
- write_type (type);
- return;
- }
- }
-
/* Skip NOP_EXPRs. They can occur when (say) a pointer argument
is converted (via qualification conversions) to another
type. */
--- 2143,2148 ----
*************** write_expression (tree expr)
*** 2210,2219 ****
write_template_arg_literal (expr);
else if (code == PARM_DECL)
{
! /* A function parameter used under decltype in a late-specified
! return type. Represented with a type placeholder. */
! write_string ("sT");
! write_type (non_reference (TREE_TYPE (expr)));
}
else if (DECL_P (expr))
{
--- 2189,2200 ----
write_template_arg_literal (expr);
else if (code == PARM_DECL)
{
! /* A function parameter used in a late-specified return type. */
! int index = parm_index (expr);
! write_string ("fp");
! if (index > 1)
! write_unsigned_number (index - 2);
! write_char ('_');
}
else if (DECL_P (expr))
{
*************** write_expression (tree expr)
*** 2231,2236 ****
--- 2212,2223 ----
write_string ("st");
write_type (TREE_OPERAND (expr, 0));
}
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF)
{
tree scope = TREE_OPERAND (expr, 0);
*************** write_expression (tree expr)
*** 2298,2306 ****
--- 2285,2300 ----
write_template_args (template_args);
}
}
+ else if (TREE_CODE (expr) == INDIRECT_REF
+ && TREE_TYPE (TREE_OPERAND (expr, 0))
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
+ {
+ write_expression (TREE_OPERAND (expr, 0));
+ }
else
{
int i;
+ const char *name;
/* When we bind a variable or function to a non-type template
argument with reference type, we create an ADDR_EXPR to show
*************** write_expression (tree expr)
*** 2338,2344 ****
}
/* If it wasn't any of those, recursively expand the expression. */
! write_string (operator_name_info[(int) code].mangled_name);
switch (code)
{
--- 2332,2345 ----
}
/* If it wasn't any of those, recursively expand the expression. */
! name = operator_name_info[(int) code].mangled_name;
! if (name == NULL)
! {
! sorry ("mangling %C", code);
! return;
! }
! else
! write_string (name);
switch (code)
{
*************** write_expression (tree expr)
*** 2351,2373 ****
case CAST_EXPR:
write_type (TREE_TYPE (expr));
! /* There is no way to mangle a zero-operand cast like
! "T()". */
! if (!TREE_OPERAND (expr, 0))
! sorry ("zero-operand casts cannot be mangled due to a defect "
! "in the C++ ABI");
! else if (list_length (TREE_OPERAND (expr, 0)) > 1)
! sorry ("mangling function-style cast with more than one argument");
! else
write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
break;
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
write_type (TREE_TYPE (expr));
write_expression (TREE_OPERAND (expr, 0));
break;
/* Handle pointers-to-members specially. */
case SCOPE_REF:
write_type (TREE_OPERAND (expr, 0));
--- 2352,2380 ----
case CAST_EXPR:
write_type (TREE_TYPE (expr));
! if (list_length (TREE_OPERAND (expr, 0)) == 1)
write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
+ else
+ {
+ tree args = TREE_OPERAND (expr, 0);
+ write_char ('_');
+ for (; args; args = TREE_CHAIN (args))
+ write_expression (TREE_VALUE (args));
+ write_char ('E');
+ }
break;
+ /* FIXME these should have a distinct mangling. */
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
write_type (TREE_TYPE (expr));
write_expression (TREE_OPERAND (expr, 0));
break;
+ case NEW_EXPR:
+ sorry ("mangling new-expression");
+ break;
+
/* Handle pointers-to-members specially. */
case SCOPE_REF:
write_type (TREE_OPERAND (expr, 0));
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c (revision 144771)
--- gcc/cp/decl.c (working copy)
*************** duplicate_decls (tree newdecl, tree oldd
*** 1684,1691 ****
= DECL_SOURCE_LOCATION (newdecl);
DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
! DECL_ARGUMENTS (old_result)
! = DECL_ARGUMENTS (new_result);
}
return olddecl;
--- 1684,1697 ----
= DECL_SOURCE_LOCATION (newdecl);
DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
! {
! tree parm;
! DECL_ARGUMENTS (old_result)
! = DECL_ARGUMENTS (new_result);
! for (parm = DECL_ARGUMENTS (old_result); parm;
! parm = TREE_CHAIN (parm))
! DECL_CONTEXT (parm) = old_result;
! }
}
return olddecl;
*************** duplicate_decls (tree newdecl, tree oldd
*** 1918,1923 ****
--- 1924,1931 ----
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
+ tree parm;
+
if (DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_TEMPLATE_INSTANTIATION (newdecl))
{
*************** duplicate_decls (tree newdecl, tree oldd
*** 1974,1979 ****
--- 1982,1992 ----
/* Preserve abstractness on cloned [cd]tors. */
DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
+ /* Update newdecl's parms to point at olddecl. */
+ for (parm = DECL_ARGUMENTS (newdecl); parm;
+ parm = TREE_CHAIN (parm))
+ DECL_CONTEXT (parm) = olddecl;
+
if (! types_match)
{
SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
*************** duplicate_decls (tree newdecl, tree oldd
*** 2006,2012 ****
}
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
! /* Don't clear out the arguments if we're redefining a function. */
if (DECL_ARGUMENTS (olddecl))
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
}
--- 2019,2026 ----
}
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
! /* Don't clear out the arguments if we're just redeclaring a
! function. */
if (DECL_ARGUMENTS (olddecl))
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
}
*************** grokfndecl (tree ctype,
*** 6555,6560 ****
--- 6569,6576 ----
parms = parm;
}
DECL_ARGUMENTS (decl) = parms;
+ for (t = parms; t; t = TREE_CHAIN (t))
+ DECL_CONTEXT (t) = decl;
/* Propagate volatile out from type to decl. */
if (TYPE_VOLATILE (type))
TREE_THIS_VOLATILE (decl) = 1;
Index: gcc/cp/operators.def
===================================================================
*** gcc/cp/operators.def (revision 144771)
--- gcc/cp/operators.def (working copy)
*************** DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_
*** 94,100 ****
DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
/* These are extensions. */
! DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "v17alignof", 1)
DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
--- 94,100 ----
DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
/* These are extensions. */
! DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", 1)
DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
Index: gcc/cp/tree.c
===================================================================
*** gcc/cp/tree.c (revision 144771)
--- gcc/cp/tree.c (working copy)
*************** cp_tree_equal (tree t1, tree t2)
*** 1881,1889 ****
case PARM_DECL:
/* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */
! if ((!DECL_CONTEXT (t1) || !DECL_CONTEXT (t2))
! && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! && DECL_NAME (t1) == DECL_NAME (t2))
return true;
else
return false;
--- 1881,1888 ----
case PARM_DECL:
/* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */
! if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! && parm_index (t1) == parm_index (t2))
return true;
else
return false;
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c (revision 144771)
--- gcc/cp/pt.c (working copy)
*************** check_explicit_specialization (tree decl
*** 2217,2233 ****
the specialization of it. */
if (tsk == tsk_template)
{
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
! DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE;
if (have_def)
{
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
! DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl))
= DECL_SOURCE_LOCATION (decl);
/* We want to use the argument list specified in the
definition, not in the original declaration. */
! DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl))
! = DECL_ARGUMENTS (decl);
}
return tmpl;
}
--- 2217,2237 ----
the specialization of it. */
if (tsk == tsk_template)
{
+ tree result = DECL_TEMPLATE_RESULT (tmpl);
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
! DECL_INITIAL (result) = NULL_TREE;
if (have_def)
{
+ tree parm;
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
! DECL_SOURCE_LOCATION (result)
= DECL_SOURCE_LOCATION (decl);
/* We want to use the argument list specified in the
definition, not in the original declaration. */
! DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl);
! for (parm = DECL_ARGUMENTS (result); parm;
! parm = TREE_CHAIN (parm))
! DECL_CONTEXT (parm) = result;
}
return tmpl;
}
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 9898,9913 ****
if (r == NULL)
{
/* This can happen for a parameter name used later in a function
! declaration (such as in a late-specified return type).
! Replace it with an arbitrary expression with the same type
! (*(T*)0). This should only occur in an unevaluated context
! (i.e. decltype). */
! gcc_assert (skip_evaluation);
! r = non_reference (TREE_TYPE (t));
! r = tsubst (r, args, complain, in_decl);
! r = build_pointer_type (r);
! r = build_c_cast (r, null_node);
! return cp_build_indirect_ref (r, NULL, tf_warning_or_error);
}
if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
--- 9902,9915 ----
if (r == NULL)
{
/* This can happen for a parameter name used later in a function
! declaration (such as in a late-specified return type). Just
! make a dummy decl, since it's only used for its type. */
! gcc_assert (skip_evaluation);
! r = tsubst_decl (t, args, complain);
! /* Give it the template pattern as its context; its true context
! hasn't been instantiated yet and this is good enough for
! mangling. */
! DECL_CONTEXT (r) = DECL_CONTEXT (t);
}
if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c (revision 144771)
--- gcc/cp/semantics.c (working copy)
*************** finish_decltype_type (tree expr, bool id
*** 4585,4592 ****
break;
}
}
- else
- type = describable_type (expr);
if (type && !type_uses_auto (type))
return type;
--- 4585,4590 ----
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c (revision 144771)
--- gcc/cp/decl2.c (working copy)
*************** mark_used (tree decl)
*** 3907,3910 ****
--- 3907,3933 ----
processing_template_decl = saved_processing_template_decl;
}
+ /* Given function PARM_DECL PARM, return its index in the function's list
+ of parameters, beginning with 1. */
+
+ int
+ parm_index (tree parm)
+ {
+ int index;
+ tree arg;
+
+ for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm));
+ arg;
+ ++index, arg = TREE_CHAIN (arg))
+ {
+ if (DECL_NAME (parm) == DECL_NAME (arg))
+ break;
+ if (DECL_ARTIFICIAL (arg))
+ --index;
+ }
+
+ gcc_assert (arg);
+ return index;
+ }
+
#include "gt-cp-decl2.h"
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h (revision 144771)
--- gcc/cp/cp-tree.h (working copy)
*************** extern bool decl_needed_p (tree);
*** 4436,4441 ****
--- 4436,4442 ----
extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
extern bool possibly_inlined_p (tree);
+ extern int parm_index (tree);
/* in error.c */
extern void init_error (void);
Index: include/demangle.h
===================================================================
*** include/demangle.h (revision 144771)
--- include/demangle.h (working copy)
*************** enum demangle_component_type
*** 221,226 ****
--- 221,228 ----
/* A template parameter. This holds a number, which is the template
parameter index. */
DEMANGLE_COMPONENT_TEMPLATE_PARAM,
+ /* A function parameter. This holds a number, which is the index. */
+ DEMANGLE_COMPONENT_FUNCTION_PARAM,
/* A constructor. This holds a name and the kind of
constructor. */
DEMANGLE_COMPONENT_CTOR,
*************** struct demangle_component
*** 466,475 ****
int len;
} s_string;
! /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM. */
struct
{
! /* Template parameter index. */
long number;
} s_number;
--- 468,477 ----
int len;
} s_string;
! /* For DEMANGLE_COMPONENT_*_PARAM. */
struct
{
! /* Parameter index. */
long number;
} s_number;
Index: libiberty/cp-demangle.c
===================================================================
*** libiberty/cp-demangle.c (revision 144771)
--- libiberty/cp-demangle.c (working copy)
*************** d_make_template_param (struct d_info *di
*** 964,969 ****
--- 964,985 ----
return p;
}
+ /* Add a new function parameter. */
+
+ static struct demangle_component *
+ d_make_function_param (struct d_info *di, long i)
+ {
+ struct demangle_component *p;
+
+ p = d_make_empty (di);
+ if (p != NULL)
+ {
+ p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
+ p->u.s_number.number = i;
+ }
+ return p;
+ }
+
/* Add a new standard substitution component. */
static struct demangle_component *
*************** CP_STATIC_IF_GLIBCPP_V3
*** 989,995 ****
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
! if (! d_check_char (di, '_'))
return NULL;
if (! d_check_char (di, 'Z'))
return NULL;
--- 1005,1015 ----
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
! if (! d_check_char (di, '_')
! /* Allow missing _ if not at toplevel to work around a
! bug in G++ abi-version=2 mangling; see the comment in
! write_template_arg. */
! && top_level)
return NULL;
if (! d_check_char (di, 'Z'))
return NULL;
*************** const struct demangle_operator_info cplu
*** 1481,1486 ****
--- 1501,1508 ----
{ "rs", NL (">>"), 2 },
{ "st", NL ("sizeof "), 1 },
{ "sz", NL ("sizeof "), 1 },
+ { "at", NL ("alignof "), 1 },
+ { "az", NL ("alignof "), 1 },
{ NULL, NULL, 0, 0 }
};
*************** d_expression (struct d_info *di)
*** 2564,2575 ****
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di)));
}
! else if (peek == 's'
! && (d_peek_next_char (di) == 'T' || d_peek_next_char (di) == 'R'))
{
! /* Just demangle a parameter placeholder as its type. */
d_advance (di, 2);
! return cplus_demangle_type (di);
}
else if (IS_DIGIT (peek))
{
--- 2586,2610 ----
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
d_template_args (di)));
}
! else if (peek == 'f' && d_peek_next_char (di) == 'p')
{
! /* Function parameter used in a late-specified return type. */
! int index;
d_advance (di, 2);
! if (d_peek_char (di) == '_')
! index = 1;
! else
! {
! index = d_number (di);
! if (index < 0)
! return NULL;
! index += 2;
! }
!
! if (! d_check_char (di, '_'))
! return NULL;
!
! return d_make_function_param (di, index);
}
else if (IS_DIGIT (peek))
{
*************** d_expression (struct d_info *di)
*** 2619,2626 ****
switch (args)
{
case 1:
! return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
! d_expression (di));
case 2:
{
struct demangle_component *left;
--- 2654,2669 ----
switch (args)
{
case 1:
! {
! struct demangle_component *operand;
! if (op->type == DEMANGLE_COMPONENT_CAST
! && d_check_char (di, '_'))
! operand = d_exprlist (di);
! else
! operand = d_expression (di);
! return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
! operand);
! }
case 2:
{
struct demangle_component *left;
*************** d_expr_primary (struct d_info *di)
*** 2671,2677 ****
if (! d_check_char (di, 'L'))
return NULL;
! if (d_peek_char (di) == '_')
ret = cplus_demangle_mangled_name (di, 0);
else
{
--- 2714,2722 ----
if (! d_check_char (di, 'L'))
return NULL;
! if (d_peek_char (di) == '_'
! /* Workaround for G++ bug; see comment in write_template_arg. */
! || d_peek_char (di) == 'Z')
ret = cplus_demangle_mangled_name (di, 0);
else
{
*************** d_print_comp (struct d_print_info *dpi,
*** 3293,3298 ****
--- 3338,3344 ----
the right place for the type. We also have to pass down
any CV-qualifiers, which apply to the this parameter. */
hold_modifiers = dpi->modifiers;
+ dpi->modifiers = 0;
i = 0;
typed_name = d_left (dc);
while (typed_name != NULL)
*************** d_print_comp (struct d_print_info *dpi,
*** 3981,3986 ****
--- 4027,4041 ----
}
return;
+ case DEMANGLE_COMPONENT_FUNCTION_PARAM:
+ {
+ char buf[25];
+ d_append_string (dpi, "parm#");
+ sprintf(buf,"%ld", dc->u.s_number.number);
+ d_append_string (dpi, buf);
+ return;
+ }
+
default:
d_print_error (dpi);
return;
Index: gcc/testsuite/g++.dg/cpp0x/auto6.C
===================================================================
*** gcc/testsuite/g++.dg/cpp0x/auto6.C (revision 144771)
--- gcc/testsuite/g++.dg/cpp0x/auto6.C (working copy)
*************** A<int> a, *p;
*** 95,115 ****
int main()
{
! // { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
auto i = add(1, 2.0);
! // { dg-final { scan-assembler "_Z4add4IidEDTplsTT_sTT0_ES0_S1_" } }
auto i4 = add4(1, 2.0);
! // { dg-final { scan-assembler "_Z4add2IidEDTplsRT_sRT0_ES0_S1_" } }
auto i2 = add2(1, 2.0);
! // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } }
auto i3 = add3(1, 2.0);
! // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptsTPT_1fEES3_" } }
f(p);
! // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtsTT_1fEES2_" } }
g(a);
! // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_" } }
h(a,1.0);
! // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } }
k( C(), A<int>(), D() );
// { dg-final { scan-assembler "_Z1lIiET_S0_" } }
l(1);
--- 95,115 ----
int main()
{
! // { dg-final { scan-assembler "_Z3addIidEDTplfp_fp0_ET_T0_" } }
auto i = add(1, 2.0);
! // { dg-final { scan-assembler "_Z4add4IidEDTpldecvPT_Li0EdecvPT0_Li0EES0_S2_" } }
auto i4 = add4(1, 2.0);
! // { dg-final { scan-assembler "_Z4add2IidEDTplcvT__EcvT0__EES0_S1_" } }
auto i2 = add2(1, 2.0);
! // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEfp_fp0_EET_T0_" } }
auto i3 = add3(1, 2.0);
! // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptfp_1fEEPT_" } }
f(p);
! // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtfp_1fEET_" } }
g(a);
! // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_" } }
h(a,1.0);
! // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtfp_srNT0_1BIT1_EE3MEMET_S4_S6_" } }
k( C(), A<int>(), D() );
// { dg-final { scan-assembler "_Z1lIiET_S0_" } }
l(1);
Index: gcc/testsuite/g++.dg/cpp0x/auto12.C
===================================================================
*** gcc/testsuite/g++.dg/cpp0x/auto12.C (revision 144771)
--- gcc/testsuite/g++.dg/cpp0x/auto12.C (working copy)
*************** auto A<T>::f(U u) -> decltype (u + i)
*** 37,52 ****
int main()
{
! // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplsTT_sTiES2_" } }
A<int>().f(1);
! // { dg-final { scan-assembler "_ZN1AIiE2frIiEEDTplsTT_sTiES2_" } }
A<int>().fr(1);
! // { dg-final { scan-assembler "_ZN1AIiE3frrIiEEDTplsTT_sTiES2_" } }
A<int>().frr(1);
! // { dg-final { scan-assembler "_ZN1AIiE1gIiEEDTplsTT_sR.ES2_" } }
A<int>().g(1);
! // { dg-final { scan-assembler "_ZN1AIiE1hIiEEDTplsTT_sr1BIS2_E1iES2_" } }
A<int>().h(1);
! // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplsTT_sRiES2_" } }
A<int>().j(1);
}
--- 37,52 ----
int main()
{
! // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } }
A<int>().f(1);
! // { dg-final { scan-assembler "_ZN1AIiE2frIiEEDTplfp_L_ZNS0_2irEEET_" } }
A<int>().fr(1);
! // { dg-final { scan-assembler "_ZN1AIiE3frrIiEEDTplfp_L_ZNS0_3irrEEET_" } }
A<int>().frr(1);
! // { dg-final { scan-assembler "_ZN1AIiE1gIiEEDTplfp_szL_ZNS0_1iEEET_" } }
A<int>().g(1);
! // { dg-final { scan-assembler "_ZN1AIiE1hIiEEDTplfp_sr1BIT_E1iES3_" } }
A<int>().h(1);
! // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } }
A<int>().j(1);
}
Index: libiberty/testsuite/demangle-expected
===================================================================
*** libiberty/testsuite/demangle-expected (revision 144771)
--- libiberty/testsuite/demangle-expected (working copy)
*************** foo<int (*) [3]>
*** 3723,3729 ****
# This used to crash the demangler--PR 16240
--format=gnu-v3 --no-params
_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
! _ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue
#
# This used to cause the demangler to walk into undefined memory--PR 22268
--- 3723,3729 ----
# This used to crash the demangler--PR 16240
--format=gnu-v3 --no-params
_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
! PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue(PatternDriver::ConflateStringScalarValue const&, PatternDriver::AbstractStringScalarValue const&, PatternDriver::TemplateEnum<PatternDriver::pdcomplement, PatternDriver::complement_names, PatternDriver::COMPLEMENTENUM> const&)
PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue
#
# This used to cause the demangler to walk into undefined memory--PR 22268
*************** _ZGr32_java$Sutil$Siso4217$_properties
*** 3884,3895 ****
java resource java/util/iso4217.properties
# decltype/param placeholder test
--format=gnu-v3
! _Z3addIidEDTplsTT_sTT0_ES0_S1_
! decltype ((int)+(double)) add<int, double>(int, double)
# decltype/fn call test
--format=gnu-v3
! _Z4add3IidEDTclL_Z1gEsTT_sTT0_EES0_S1_
! decltype (g(int, double)) add3<int, double>(int, double)
# new (2008) built in types test
--format=gnu-v3
_Z1fDfDdDeDhDsDi
--- 3884,3895 ----
java resource java/util/iso4217.properties
# decltype/param placeholder test
--format=gnu-v3
! _Z3addIidEDTplfp_fp0_ET_T0_
! decltype ((parm#1)+(parm#2)) add<int, double>(int, double)
# decltype/fn call test
--format=gnu-v3
! _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
! decltype (g(parm#1, parm#2)) add3<int, double>(int, double)
# new (2008) built in types test
--format=gnu-v3
_Z1fDfDdDeDhDsDi
*************** _Z1fIIPiPfPdEEvDpT_
*** 3900,3904 ****
void f<int*, float*, double*>(int*, float*, double*)
# '.' test
--format=gnu-v3
! _Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_
! decltype (((A<int>).(g<double>))()) h<A<int>, double>(A<int>, double)
--- 3900,3908 ----
void f<int*, float*, double*>(int*, float*, double*)
# '.' test
--format=gnu-v3
! _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_
! decltype (((parm#1).(g<double>))()) h<A<int>, double>(A<int>, double)
! # test for typed function in decltype
! --format=gnu-v3
! _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_
! decltype ((parm#1)+((x())())) A<int>::j<int>(int)