From: Jason Merrill Date: Fri, 6 Jan 2012 21:39:43 +0000 (-0500) Subject: re PR c++/6057 (expression mangling doesn't work for operator new) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4b6aaa996e0d8f5abac818315b6f77cb3596db98;p=gcc.git re PR c++/6057 (expression mangling doesn't work for operator new) PR c++/6057 PR c++/48051 PR c++/50855 PR c++/51322 gcc/cp/ * mangle.c (write_expression): Support NEW_EXPR, DELETE_EXPR, THROW_EXPR, CONSTRUCTOR, OVERLOAD. Fix PREINCREMENT_EXPR and PREDECREMENT_EXPR. (write_template_arg): Fix mangling of class-scope functions and argument packs. (mangle_decl): Update suggested -fabi-version argument. * operators.def: Add DOTSTAR_EXPR, REINTERPRET_CAST_EXPR, DYNAMIC_CAST_EXPR; correct CONST_CAST_EXPR, STATIC_CAST_EXPR. * tree.c (dependent_name): No longer static. * cp-tree.h: Declare it. * pt.c (unify): Defer handling of unconverted functions. include/ * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_INITIALIZER_LIST, DEMANGLE_COMPONENT_NULLARY. libiberty/ * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_NULLARY and DEMANGLE_COMPONENT_INITIALIZER_LIST. (d_make_comp): Likewise. Allow null right arg for DEMANGLE_COMPONENT_TRINARY_ARG2. (cplus_demangle_operators): Adjust new/delete; add .*, :: and throw. (d_template_args, d_template_arg): Handle 'J' for argument packs. (d_exprlist): Add terminator parm. (d_expression, d_print_comp): Handle initializer lists, nullary expressions, prefix/suffix operators, and new. (d_print_subexpr): Avoid parens around DEMANGLE_COMPONENT_QUAL_NAME and DEMANGLE_COMPONENT_INITIALIZER_LIST. * testsuite/demangle-expected: Add tests. From-SVN: r182970 --- diff --git a/gcc/common.opt b/gcc/common.opt index 6cfe17a15d3..0544478f4e0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -782,7 +782,10 @@ Driver Undocumented ; function parameters used in other parameters and the return type. ; First selectable in G++ 4.6. ; -; 6: The version of the ABI that doesn't promote scoped enums to int. +; 6: The version of the ABI that doesn't promote scoped enums to int and +; changes the mangling of template argument packs, const/static_cast, +; prefix ++ and --, and a class scope function used as a template +; argument. ; First selectable in G++ 4.7. ; ; Additional positive integers will be assigned as new versions of diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 01480e3f9f2..041722d7179 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,21 @@ 2012-01-06 Jason Merrill + PR c++/6057 + PR c++/48051 + PR c++/50855 + PR c++/51322 + * mangle.c (write_expression): Support NEW_EXPR, DELETE_EXPR, + THROW_EXPR, CONSTRUCTOR, OVERLOAD. Fix PREINCREMENT_EXPR and + PREDECREMENT_EXPR. + (write_template_arg): Fix mangling of class-scope functions and + argument packs. + (mangle_decl): Update suggested -fabi-version argument. + * operators.def: Add DOTSTAR_EXPR, REINTERPRET_CAST_EXPR, + DYNAMIC_CAST_EXPR; correct CONST_CAST_EXPR, STATIC_CAST_EXPR. + * tree.c (dependent_name): No longer static. + * cp-tree.h: Declare it. + * pt.c (unify): Defer handling of unconverted functions. + * mangle.c (mangle_decl): Don't generate mangling aliases for maybe-in-charge [cd]tors. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6e62bd1ba50..ccad6443651 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5674,6 +5674,7 @@ extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_chain (tree, tree); extern tree build_qualified_name (tree, tree, tree, bool); extern int is_overloaded_fn (tree); +extern tree dependent_name (tree); extern tree get_fns (tree); extern tree get_first_fn (tree); extern tree ovl_cons (tree, tree); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index e5c28952df6..f4efa67cc27 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2646,6 +2646,102 @@ write_expression (tree expr) write_expression (TREE_OPERAND (expr, 0)); write_expression (TREE_OPERAND (expr, 2)); } + else if (code == NEW_EXPR || code == VEC_NEW_EXPR) + { + /* ::= [gs] nw * _ E + ::= [gs] nw * _ + ::= [gs] na * _ E + ::= [gs] na * _ + ::= pi * E */ + tree placement = TREE_OPERAND (expr, 0); + tree type = TREE_OPERAND (expr, 1); + tree nelts = TREE_OPERAND (expr, 2); + tree init = TREE_OPERAND (expr, 3); + tree t; + + gcc_assert (code == NEW_EXPR); + if (TREE_OPERAND (expr, 2)) + code = VEC_NEW_EXPR; + + if (NEW_EXPR_USE_GLOBAL (expr)) + write_string ("gs"); + + write_string (operator_name_info[(int) code].mangled_name); + + for (t = placement; t; t = TREE_CHAIN (t)) + write_expression (TREE_VALUE (t)); + + write_char ('_'); + + if (nelts) + { + tree domain; + ++processing_template_decl; + domain = compute_array_index_type (NULL_TREE, nelts, + tf_warning_or_error); + type = build_cplus_array_type (type, domain); + --processing_template_decl; + } + write_type (type); + + if (init && TREE_CODE (init) == TREE_LIST + && TREE_CODE (TREE_VALUE (init)) == CONSTRUCTOR + && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init))) + write_expression (TREE_VALUE (init)); + else + { + if (init) + write_string ("pi"); + if (init && init != void_zero_node) + for (t = init; t; t = TREE_CHAIN (t)) + write_expression (TREE_VALUE (t)); + write_char ('E'); + } + } + else if (code == DELETE_EXPR || code == VEC_DELETE_EXPR) + { + gcc_assert (code == DELETE_EXPR); + if (DELETE_EXPR_USE_VEC (expr)) + code = VEC_DELETE_EXPR; + + if (DELETE_EXPR_USE_GLOBAL (expr)) + write_string ("gs"); + + write_string (operator_name_info[(int) code].mangled_name); + + write_expression (TREE_OPERAND (expr, 0)); + } + else if (code == THROW_EXPR) + { + tree op = TREE_OPERAND (expr, 0); + if (op) + { + write_string ("tw"); + write_expression (op); + } + else + write_string ("tr"); + } + else if (code == CONSTRUCTOR) + { + VEC(constructor_elt,gc)* elts = CONSTRUCTOR_ELTS (expr); + unsigned i; tree val; + + if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + write_string ("il"); + else + { + write_string ("tl"); + write_type (TREE_TYPE (expr)); + } + FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val) + write_expression (val); + write_char ('E'); + } + else if (dependent_name (expr)) + { + write_unqualified_id (dependent_name (expr)); + } else { int i, len; @@ -2688,6 +2784,16 @@ write_expression (tree expr) /* If it wasn't any of those, recursively expand the expression. */ name = operator_name_info[(int) code].mangled_name; + + /* We used to mangle const_cast and static_cast like a C cast. */ + if (!abi_version_at_least (6) + && (code == CONST_CAST_EXPR + || code == STATIC_CAST_EXPR)) + { + name = operator_name_info[CAST_EXPR].mangled_name; + G.need_abi_warning = 1; + } + if (name == NULL) { sorry ("mangling %C", code); @@ -2734,16 +2840,21 @@ write_expression (tree expr) } break; - /* FIXME these should have a distinct mangling. */ + case DYNAMIC_CAST_EXPR: + case REINTERPRET_CAST_EXPR: 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; + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: + if (abi_version_at_least (6)) + write_char ('_'); + else + G.need_abi_warning = 1; + /* Fall through. */ default: /* In the middle-end, some expressions have more operands than @@ -2855,12 +2966,28 @@ write_template_arg (tree node) G.need_abi_warning = 1; } + if (TREE_CODE (node) == BASELINK + && !type_unknown_p (node)) + { + if (abi_version_at_least (6)) + node = BASELINK_FUNCTIONS (node); + else + /* We wrongly wrapped a class-scope function in X/E. */ + G.need_abi_warning = 1; + } + if (ARGUMENT_PACK_P (node)) { /* Expand the template argument pack. */ tree args = ARGUMENT_PACK_ARGS (node); int i, length = TREE_VEC_LENGTH (args); - write_char ('I'); + if (abi_version_at_least (6)) + write_char ('J'); + else + { + write_char ('I'); + G.need_abi_warning = 1; + } for (i = 0; i < length; ++i) write_template_arg (TREE_VEC_ELT (args, i)); write_char ('E'); @@ -3208,8 +3335,8 @@ mangle_decl (const tree decl) SET_IDENTIFIER_GLOBAL_VALUE (id, decl); if (IDENTIFIER_GLOBAL_VALUE (id) != decl) - inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=4 (or =0) " - "avoids this error with a change in vector mangling"); + inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) " + "avoids this error with a change in mangling"); #ifdef ASM_OUTPUT_DEF save_ver = flag_abi_version; diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index 20d811b812b..3dc74049952 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -101,8 +101,10 @@ DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1) /* The cast operator. */ DEF_SIMPLE_OPERATOR ("", TYPE_EXPR, "cv", 1) DEF_SIMPLE_OPERATOR ("", CAST_EXPR, "cv", 1) -DEF_SIMPLE_OPERATOR ("", CONST_CAST_EXPR, "cv", 1) -DEF_SIMPLE_OPERATOR ("", STATIC_CAST_EXPR, "cv", 1) +DEF_SIMPLE_OPERATOR ("dynamic_cast", DYNAMIC_CAST_EXPR, "dc", 1) +DEF_SIMPLE_OPERATOR ("reinterpret_cast", REINTERPRET_CAST_EXPR, "rc", 1) +DEF_SIMPLE_OPERATOR ("const_cast", CONST_CAST_EXPR, "cc", 1) +DEF_SIMPLE_OPERATOR ("static_cast", STATIC_CAST_EXPR, "sc", 1) /* Binary operators. */ DEF_SIMPLE_OPERATOR ("+", PLUS_EXPR, "pl", 2) @@ -125,6 +127,7 @@ DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", 2) DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", 2) DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", 2) DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", 2) +DEF_SIMPLE_OPERATOR (".*", DOTSTAR_EXPR, "ds", 2) DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2) DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2) DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 77e3388587b..bc3dd9713a9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16885,7 +16885,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, default: /* An unresolved overload is a nondeduced context. */ - if (type_unknown_p (parm)) + if (is_overloaded_fn (parm) || type_unknown_p (parm)) return unify_success (explain_p); gcc_assert (EXPR_P (parm)); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index dea7632d829..8ef3e2540cd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1457,7 +1457,7 @@ is_overloaded_fn (tree x) (14.6.2), return the IDENTIFIER_NODE for that name. Otherwise, return NULL_TREE. */ -static tree +tree dependent_name (tree x) { if (TREE_CODE (x) == IDENTIFIER_NODE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f46fede082..e96146d231c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,21 @@ 2012-01-06 Jason Merrill + * g++.dg/abi/mangle51.C: New. + * g++.dg/abi/mangle52.C: New. + * g++.dg/abi/mangle53.C: New. + * g++.dg/abi/mangle54.C: New. + * g++.dg/abi/mangle55.C: New. + * g++.dg/abi/mangle56.C: New. + * g++.dg/abi/mangle57.C: New. + * g++.dg/abi/mangle58.C: New. + * g++.dg/abi/mangle59.C: New. + * g++.dg/cpp0x/trailing3.C: Update mangling. + * g++.dg/cpp0x/variadic111.C: Update mangling. + * g++.dg/cpp0x/variadic4.C: Update mangling. + * g++.dg/cpp0x/variadic42.C: Pass -fabi-version=5. + * g++.dg/template/nontype22.C: Works now. + * g++.dg/template/pr35240.C: Works now. + * g++.dg/cpp0x/error7.C: New. 2012-01-06 Tobias Burnus diff --git a/gcc/testsuite/g++.dg/abi/mangle51.C b/gcc/testsuite/g++.dg/abi/mangle51.C new file mode 100644 index 00000000000..4992f1a327c --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle51.C @@ -0,0 +1,27 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +void* operator new (__SIZE_TYPE__, void *p) { return p; } +int i; + +template struct helper {}; +// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXsznw_T_EEE" } } +template void check1( helper * ) { } +// { dg-final { scan-assembler "_Z6check2IiEvP6helperIXszgsnw_T_piEEE" } } +template void check2( helper * ) { } +// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXsznwadL_Z1iE_T_piLi1EEEE" } } +template void check3( helper * ) { } +// { dg-final { scan-assembler "_Z7check3aIiEvP6helperIXsznw_T_ilLi1EEEE" } } +template void check3a( helper * ) { } +// { dg-final { scan-assembler "_Z6check4IiEvP6helperIXszna_A1_T_EEE" } } +template void check4( helper * ) { } +// { dg-final { scan-assembler "_Z6check5IiEvP6helperIXszna_A1_T_piEEE" } } +template void check5( helper * ) { } +int main() +{ + check1(0); + check2(0); + check3(0); + check3a(0); + check4(0); + check5(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle52.C b/gcc/testsuite/g++.dg/abi/mangle52.C new file mode 100644 index 00000000000..2c463415f1f --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle52.C @@ -0,0 +1,21 @@ +// { dg-options "-fabi-version=0" } + +template struct helper {}; +// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXszscT_Li1EEE" } } +template void check1( helper(1))> * ) { } +// { dg-final { scan-assembler "_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE" } } +template void check2( helper(p))> * ) { } +// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXszrcPT_Li0EEE" } } +template void check3( helper(0))> * ) { } +// { dg-final { scan-assembler "_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE" } } +template void check4( helper(p))> * ) { } + +struct A{} a; +int i; +int main() +{ + check1(0); + check2(0); + check3(0); + check4(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle53.C b/gcc/testsuite/g++.dg/abi/mangle53.C new file mode 100644 index 00000000000..b279182d8c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle53.C @@ -0,0 +1,13 @@ +// { dg-options "-std=c++0x" } + +bool b; +// { dg-final { scan-assembler "_Z1fIiEDTquL_Z1bEfp_twLi42EET_" } } +template auto f (T t) -> decltype(b?t:throw 42) { return 0; } +// { dg-final { scan-assembler "_Z2f2IiEDTquL_Z1bEfp_trET_" } } +template auto f2 (T t) -> decltype(b?t:throw) { return 0; } + +int main() +{ + f(0); + f2(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle54.C b/gcc/testsuite/g++.dg/abi/mangle54.C new file mode 100644 index 00000000000..ea98df17d36 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle54.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +int i; +// { dg-final { scan-assembler "_Z2f1IiEDTppfp_ET_" } } +template auto f1 (T t) -> decltype(t++) { return i; } +// { dg-final { scan-assembler "_Z2f2IiEDTpp_fp_ET_" } } +template auto f2 (T t) -> decltype(++t) { return i; } +// { dg-final { scan-assembler "_Z2f3IiEDTmmfp_ET_" } } +template auto f3 (T t) -> decltype(t--) { return i; } +// { dg-final { scan-assembler "_Z2f4IiEDTmm_fp_ET_" } } +template auto f4 (T t) -> decltype(--t) { return i; } + +int main() +{ + f1(0); + f2(0); + f3(0); + f4(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle55.C b/gcc/testsuite/g++.dg/abi/mangle55.C new file mode 100644 index 00000000000..72caadcc24d --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle55.C @@ -0,0 +1,14 @@ +// { dg-options "-std=c++0x" } + +struct A { int i; }; +// { dg-final { scan-assembler "_Z2f1Ii1AEDTdsfp_fp0_ET0_MS2_T_" } } +template auto f1 (U u, T U::* p) -> decltype(u.*p) { return u.*p; } +// { dg-final { scan-assembler "_Z2f2Ii1AEDTpmfp_fp0_EPT0_MS2_T_" } } +template auto f2 (U* u, T U::* p) -> decltype(u->*p) { return u->*p; } + +int main() +{ + A a = {}; + f1(a, &A::i); + f2(&a, &A::i); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle56.C b/gcc/testsuite/g++.dg/abi/mangle56.C new file mode 100644 index 00000000000..0fd270169d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle56.C @@ -0,0 +1,13 @@ +// { dg-options "-std=c++0x" } + +template T g(T t1, T t2) { return t2; } +// { dg-final { scan-assembler "_Z2f1IiEDTcl1gfp_ilEEET_" } } +template auto f1 (T t) -> decltype(g(t,{})) { return g(t,{}); } +// { dg-final { scan-assembler "_Z2f2IiEDTcl1gfp_tlT_EEES0_" } } +template auto f2 (T t) -> decltype(g(t,T{})) { return g(t,T{}); } + +int main() +{ + f1(0); + f2(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle57.C b/gcc/testsuite/g++.dg/abi/mangle57.C new file mode 100644 index 00000000000..3d9d81e55ba --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle57.C @@ -0,0 +1,16 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +template int cmp1(T a, T b); +int cmp2(char a, char b); +template struct A { }; +// { dg-final { scan-assembler "_Z1fIcEvR1AIT_X4cmp1EE" } } +template void f (A &); +// { dg-final { scan-assembler "_Z1fIcEvR1AIT_L_Z4cmp2ccEE" } } +template void f (A &); +void g() +{ + A a; + f(a); + A a2; + f(a2); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle58.C b/gcc/testsuite/g++.dg/abi/mangle58.C new file mode 100644 index 00000000000..14e5543d9f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle58.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +template struct A { }; +struct B { + template static int cmp1(T a, T b); + static int cmp2(char a, char b); + // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } } + template static void f (A &); + // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } + template static void f (A &); +}; + +void g() +{ + A a; + B::f(a); + A a2; + B::f(a2); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle59.C b/gcc/testsuite/g++.dg/abi/mangle59.C new file mode 100644 index 00000000000..3c88ec87486 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle59.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +// { dg-final { scan-assembler "_Z1fIiEDTcmdlfp_psfp_EPT_" } } +template auto f (T* p) -> decltype(delete p, +p) { return p; } +// { dg-final { scan-assembler "_Z1gIiEDTcmgsdlfp_psfp_EPT_" } } +template auto g (T* p) -> decltype(::delete p, +p) { return p; } +// { dg-final { scan-assembler "_Z1hIiEDTcmdafp_psfp_EPT_" } } +template auto h (T* p) -> decltype(delete[] p, +p) { return p; } +// { dg-final { scan-assembler "_Z1iIiEDTcmgsdafp_psfp_EPT_" } } +template auto i (T* p) -> decltype(::delete[] p, +p) { return p; } + +int main() +{ + int x; + f(&x); + g(&x); + h(&x); + i(&x); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing3.C b/gcc/testsuite/g++.dg/cpp0x/trailing3.C index 82d36f0d0d2..1c64f45731a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/trailing3.C +++ b/gcc/testsuite/g++.dg/cpp0x/trailing3.C @@ -1,5 +1,5 @@ // More auto/decltype mangling tests. -// { dg-options "-std=c++0x" } +// { dg-options "-std=c++0x -fabi-version=0" } template struct B @@ -58,6 +58,6 @@ int main() A().h(1); // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A().j(1); - // { dg-final { scan-assembler "_Z1gIIidEEDTcl1fspplfp_Li1EEEDpT_" } } + // { dg-final { scan-assembler "_Z1gIJidEEDTcl1fspplfp_Li1EEEDpT_" } } g(42, 1.0); } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic111.C b/gcc/testsuite/g++.dg/cpp0x/variadic111.C index 378162e162d..cb94ce69755 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic111.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic111.C @@ -1,5 +1,5 @@ // PR c++/48424 -// { dg-options -std=c++0x } +// { dg-options "-std=c++0x -fabi-version=0" } template struct S @@ -16,4 +16,4 @@ int main() s.f(1,2.0,false,'a'); } -// { dg-final { scan-assembler "_ZN1SIIidEE1fIIbcEEEvidDpOT_" } } +// { dg-final { scan-assembler "_ZN1SIJidEE1fIJbcEEEvidDpOT_" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic4.C b/gcc/testsuite/g++.dg/cpp0x/variadic4.C index 9257a92d5b9..1bdad3256fb 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic4.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic4.C @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++0x -fabi-version=0" } // { dg-do compile } template class tuple {}; @@ -9,7 +9,7 @@ void f_two(tuple) {} void f_nested(tuple, float>) { } -// { dg-final { scan-assembler "_Z6f_none5tupleIIEE" } } -// { dg-final { scan-assembler "_Z5f_one5tupleIIiEE" } } -// { dg-final { scan-assembler "_Z5f_two5tupleIIifEE" } } -// { dg-final { scan-assembler "_Z8f_nested5tupleIIiS_IIdcEEfEE" } } +// { dg-final { scan-assembler "_Z6f_none5tupleIJEE" } } +// { dg-final { scan-assembler "_Z5f_one5tupleIJiEE" } } +// { dg-final { scan-assembler "_Z5f_two5tupleIJifEE" } } +// { dg-final { scan-assembler "_Z8f_nested5tupleIJiS_IJdcEEfEE" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic42.C b/gcc/testsuite/g++.dg/cpp0x/variadic42.C index 47d9b66da58..3ec68e8b1ff 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic42.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic42.C @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++0x -fabi-version=5" } // { dg-do compile } template void f(Args...) { } diff --git a/gcc/testsuite/g++.dg/template/nontype22.C b/gcc/testsuite/g++.dg/template/nontype22.C index f2c8c46e9fc..44d8479af29 100644 --- a/gcc/testsuite/g++.dg/template/nontype22.C +++ b/gcc/testsuite/g++.dg/template/nontype22.C @@ -3,7 +3,7 @@ template int cmp1(T a, T b); template struct A { }; -template void f (A &); // { dg-bogus "" "" { xfail *-*-* } } +template void f (A &); void g() { A a; diff --git a/gcc/testsuite/g++.dg/template/pr35240.C b/gcc/testsuite/g++.dg/template/pr35240.C index 88e25050fda..5b945511768 100644 --- a/gcc/testsuite/g++.dg/template/pr35240.C +++ b/gcc/testsuite/g++.dg/template/pr35240.C @@ -1,12 +1,11 @@ // PR c++/35240 // { dg-do compile } - template struct A {}; -template A foo(); // { dg-message "unimplemented" } +template A foo(); void bar() { - foo<1>(); // { dg-message "required" } + foo<1>(); } diff --git a/include/ChangeLog b/include/ChangeLog index df131629f2b..4e4ca15832a 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,12 @@ +2012-01-06 Jason Merrill + + PR c++/6057 + PR c++/48051 + PR c++/50855 + PR c++/51322 + * demangle.h (enum demangle_component_type): Add + DEMANGLE_COMPONENT_INITIALIZER_LIST, DEMANGLE_COMPONENT_NULLARY. + 2011-11-07 Richard Henderson Merged from transactional-memory. diff --git a/include/demangle.h b/include/demangle.h index 98b11d796f4..34b3ed3cde9 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -344,6 +344,9 @@ enum demangle_component_type template argument, and the right subtree is either NULL or another TEMPLATE_ARGLIST node. */ DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, + /* An initializer list. The left subtree is either an explicit type or + NULL, and the right subtree is a DEMANGLE_COMPONENT_ARGLIST. */ + DEMANGLE_COMPONENT_INITIALIZER_LIST, /* An operator. This holds information about a standard operator. */ DEMANGLE_COMPONENT_OPERATOR, @@ -353,6 +356,8 @@ enum demangle_component_type /* A typecast, represented as a unary operator. The one subtree is the type to which the argument should be cast. */ DEMANGLE_COMPONENT_CAST, + /* A nullary expression. The left subtree is the operator. */ + DEMANGLE_COMPONENT_NULLARY, /* A unary expression. The left subtree is the operator, and the right subtree is the single argument. */ DEMANGLE_COMPONENT_UNARY, diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 97ea84fdc42..8587ee2eabd 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,5 +1,22 @@ 2012-01-06 Jason Merrill + PR c++/6057 + PR c++/48051 + PR c++/50855 + PR c++/51322 + * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_NULLARY and + DEMANGLE_COMPONENT_INITIALIZER_LIST. + (d_make_comp): Likewise. Allow null right arg for + DEMANGLE_COMPONENT_TRINARY_ARG2. + (cplus_demangle_operators): Adjust new/delete; add .*, :: and throw. + (d_template_args, d_template_arg): Handle 'J' for argument packs. + (d_exprlist): Add terminator parm. + (d_expression, d_print_comp): Handle initializer lists, nullary + expressions, prefix/suffix operators, and new. + (d_print_subexpr): Avoid parens around DEMANGLE_COMPONENT_QUAL_NAME + and DEMANGLE_COMPONENT_INITIALIZER_LIST. + * testsuite/demangle-expected: Add tests. + * cp-demangle.c (cplus_demangle_type): decltype, pack expansion and vector are substitutable. (cplus_demangle_operators): Sort. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 0ed83976dfa..2dfd67ceb77 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -648,9 +648,15 @@ d_dump (struct demangle_component *dc, int indent) case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: printf ("template argument list\n"); break; + case DEMANGLE_COMPONENT_INITIALIZER_LIST: + printf ("initializer list\n"); + break; case DEMANGLE_COMPONENT_CAST: printf ("cast\n"); break; + case DEMANGLE_COMPONENT_NULLARY: + printf ("nullary operator\n"); + break; case DEMANGLE_COMPONENT_UNARY: printf ("unary operator\n"); break; @@ -806,7 +812,6 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_BINARY_ARGS: case DEMANGLE_COMPONENT_TRINARY: case DEMANGLE_COMPONENT_TRINARY_ARG1: - case DEMANGLE_COMPONENT_TRINARY_ARG2: case DEMANGLE_COMPONENT_LITERAL: case DEMANGLE_COMPONENT_LITERAL_NEG: case DEMANGLE_COMPONENT_COMPOUND_NAME: @@ -843,6 +848,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_PACK_EXPANSION: case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: + case DEMANGLE_COMPONENT_NULLARY: + case DEMANGLE_COMPONENT_TRINARY_ARG2: if (left == NULL) return NULL; break; @@ -850,6 +857,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, /* This needs a right parameter, but the left parameter can be empty. */ case DEMANGLE_COMPONENT_ARRAY_TYPE: + case DEMANGLE_COMPONENT_INITIALIZER_LIST: if (right == NULL) return NULL; break; @@ -1573,15 +1581,17 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "cm", NL (","), 2 }, { "co", NL ("~"), 1 }, { "dV", NL ("/="), 2 }, - { "da", NL ("delete[]"), 1 }, + { "da", NL ("delete[] "), 1 }, { "de", NL ("*"), 1 }, - { "dl", NL ("delete"), 1 }, + { "dl", NL ("delete "), 1 }, + { "ds", NL (".*"), 2 }, { "dt", NL ("."), 2 }, { "dv", NL ("/"), 2 }, { "eO", NL ("^="), 2 }, { "eo", NL ("^"), 2 }, { "eq", NL ("=="), 2 }, { "ge", NL (">="), 2 }, + { "gs", NL ("::"), 1 }, { "gt", NL (">"), 2 }, { "ix", NL ("[]"), 2 }, { "lS", NL ("<<="), 2 }, @@ -1593,11 +1603,11 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "mi", NL ("-"), 2 }, { "ml", NL ("*"), 2 }, { "mm", NL ("--"), 1 }, - { "na", NL ("new[]"), 1 }, + { "na", NL ("new[]"), 3 }, { "ne", NL ("!="), 2 }, { "ng", NL ("-"), 1 }, { "nt", NL ("!"), 1 }, - { "nw", NL ("new"), 1 }, + { "nw", NL ("new"), 3 }, { "oR", NL ("|="), 2 }, { "oo", NL ("||"), 2 }, { "or", NL ("|"), 2 }, @@ -1614,6 +1624,8 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "rs", NL (">>"), 2 }, { "st", NL ("sizeof "), 1 }, { "sz", NL ("sizeof "), 1 }, + { "tr", NL ("throw"), 0 }, + { "tw", NL ("throw "), 1 }, { NULL, NULL, 0, 0 } }; @@ -2679,8 +2691,10 @@ d_template_args (struct d_info *di) constructor or destructor. */ hold_last_name = di->last_name; - if (! d_check_char (di, 'I')) + if (d_peek_char (di) != 'I' + && d_peek_char (di) != 'J') return NULL; + d_advance (di, 1); if (d_peek_char (di) == 'E') { @@ -2739,6 +2753,7 @@ d_template_arg (struct d_info *di) return d_expr_primary (di); case 'I': + case 'J': /* An argument pack. */ return d_template_args (di); @@ -2747,15 +2762,16 @@ d_template_arg (struct d_info *di) } } -/* Subroutine of ::= cl + E */ +/* Parse a sequence of expressions until we hit the terminator + character. */ static struct demangle_component * -d_exprlist (struct d_info *di) +d_exprlist (struct d_info *di, char terminator) { struct demangle_component *list = NULL; struct demangle_component **p = &list; - if (d_peek_char (di) == 'E') + if (d_peek_char (di) == terminator) { d_advance (di, 1); return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL); @@ -2772,7 +2788,7 @@ d_exprlist (struct d_info *di) return NULL; p = &d_right (*p); - if (d_peek_char (di) == 'E') + if (d_peek_char (di) == terminator) { d_advance (di, 1); break; @@ -2863,9 +2879,21 @@ d_expression (struct d_info *di) else return name; } + else if ((peek == 'i' || peek == 't') + && d_peek_next_char (di) == 'l') + { + /* Brace-enclosed initializer list, untyped or typed. */ + struct demangle_component *type = NULL; + if (peek == 't') + type = cplus_demangle_type (di); + d_advance (di, 2); + return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST, + type, d_exprlist (di, 'E')); + } else { struct demangle_component *op; + const char *code = NULL; int args; op = d_operator_name (di); @@ -2873,12 +2901,13 @@ d_expression (struct d_info *di) return NULL; if (op->type == DEMANGLE_COMPONENT_OPERATOR) - di->expansion += op->u.s_operator.op->len - 2; - - if (op->type == DEMANGLE_COMPONENT_OPERATOR - && strcmp (op->u.s_operator.op->code, "st") == 0) - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - cplus_demangle_type (di)); + { + code = op->u.s_operator.op->code; + di->expansion += op->u.s_operator.op->len - 2; + if (strcmp (code, "st") == 0) + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + cplus_demangle_type (di)); + } switch (op->type) { @@ -2897,26 +2926,43 @@ d_expression (struct d_info *di) switch (args) { + case 0: + return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL); + case 1: { struct demangle_component *operand; + int suffix = 0; + + if (code && (code[0] == 'p' || code[0] == 'm') + && code[1] == code[0]) + /* pp_ and mm_ are the prefix variants. */ + suffix = !d_check_char (di, '_'); + if (op->type == DEMANGLE_COMPONENT_CAST && d_check_char (di, '_')) - operand = d_exprlist (di); + operand = d_exprlist (di, 'E'); else operand = d_expression (di); - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - operand); + + if (suffix) + /* Indicate the suffix variant for d_print_comp. */ + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + d_make_comp (di, + DEMANGLE_COMPONENT_BINARY_ARGS, + operand, operand)); + else + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + operand); } case 2: { struct demangle_component *left; struct demangle_component *right; - const char *code = op->u.s_operator.op->code; left = d_expression (di); if (!strcmp (code, "cl")) - right = d_exprlist (di); + right = d_exprlist (di, 'E'); else if (!strcmp (code, "dt") || !strcmp (code, "pt")) { right = d_unqualified_name (di); @@ -2936,17 +2982,50 @@ d_expression (struct d_info *di) { struct demangle_component *first; struct demangle_component *second; + struct demangle_component *third; - first = d_expression (di); - second = d_expression (di); + if (!strcmp (code, "qu")) + { + /* ?: expression. */ + first = d_expression (di); + second = d_expression (di); + third = d_expression (di); + } + else if (code[0] == 'n') + { + /* new-expression. */ + if (code[1] != 'w' && code[1] != 'a') + return NULL; + first = d_exprlist (di, '_'); + second = cplus_demangle_type (di); + if (d_peek_char (di) == 'E') + { + d_advance (di, 1); + third = NULL; + } + else if (d_peek_char (di) == 'p' + && d_peek_next_char (di) == 'i') + { + /* Parenthesized initializer. */ + d_advance (di, 2); + third = d_exprlist (di, 'E'); + } + else if (d_peek_char (di) == 'i' + && d_peek_next_char (di) == 'l') + /* initializer-list. */ + third = d_expression (di); + else + return NULL; + } + else + return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op, d_make_comp (di, DEMANGLE_COMPONENT_TRINARY_ARG1, first, d_make_comp (di, DEMANGLE_COMPONENT_TRINARY_ARG2, - second, - d_expression (di)))); + second, third))); } default: return NULL; @@ -3666,6 +3745,8 @@ d_print_subexpr (struct d_print_info *dpi, int options, { int simple = 0; if (dc->type == DEMANGLE_COMPONENT_NAME + || dc->type == DEMANGLE_COMPONENT_QUAL_NAME + || dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM) simple = 1; if (!simple) @@ -4261,6 +4342,19 @@ d_print_comp (struct d_print_info *dpi, int options, } return; + case DEMANGLE_COMPONENT_INITIALIZER_LIST: + { + struct demangle_component *type = d_left (dc); + struct demangle_component *list = d_right (dc); + + if (type) + d_print_comp (dpi, options, type); + d_append_char (dpi, '{'); + d_print_comp (dpi, options, list); + d_append_char (dpi, '}'); + } + return; + case DEMANGLE_COMPONENT_OPERATOR: { char c; @@ -4284,55 +4378,59 @@ d_print_comp (struct d_print_info *dpi, int options, d_print_cast (dpi, options, dc); return; + case DEMANGLE_COMPONENT_NULLARY: + d_print_expr_op (dpi, options, d_left (dc)); + return; + case DEMANGLE_COMPONENT_UNARY: - if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR - && d_left (dc)->u.s_operator.op->len == 1 - && d_left (dc)->u.s_operator.op->name[0] == '&' - && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME - && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME - && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) - { - /* Address of a function (therefore in an expression context) must - have its argument list suppressed. - - unary operator ... dc - operator & ... d_left (dc) - typed name ... d_right (dc) - qualified name ... d_left (d_right (dc)) - - function type ... d_right (d_right (dc)) - argument list - */ - - d_print_expr_op (dpi, options, d_left (dc)); - d_print_comp (dpi, options, d_left (d_right (dc))); - return; - } - else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR - && d_left (dc)->u.s_operator.op->len == 1 - && d_left (dc)->u.s_operator.op->name[0] == '&' - && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME) - { - /* Keep also already processed variant without the argument list. + { + struct demangle_component *op = d_left (dc); + struct demangle_component *operand = d_right (dc); + const char *code = NULL; - unary operator ... dc - operator & ... d_left (dc) - qualified name ... d_right (dc) - */ + if (op->type == DEMANGLE_COMPONENT_OPERATOR) + { + code = op->u.s_operator.op->code; + if (!strcmp (code, "ad")) + { + /* Don't print the argument list for the address of a + function. */ + if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME + && d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME + && d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + operand = d_left (operand); + } + if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS) + { + /* This indicates a suffix operator. */ + operand = d_left (operand); + d_print_subexpr (dpi, options, operand); + d_print_expr_op (dpi, options, op); + return; + } + } - d_print_expr_op (dpi, options, d_left (dc)); - d_print_comp (dpi, options, d_right (dc)); - return; - } - else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST) - d_print_expr_op (dpi, options, d_left (dc)); - else - { - d_append_char (dpi, '('); - d_print_cast (dpi, options, d_left (dc)); - d_append_char (dpi, ')'); - } - d_print_subexpr (dpi, options, d_right (dc)); + if (op->type != DEMANGLE_COMPONENT_CAST) + d_print_expr_op (dpi, options, op); + else + { + d_append_char (dpi, '('); + d_print_cast (dpi, options, op); + d_append_char (dpi, ')'); + } + if (code && !strcmp (code, "gs")) + /* Avoid parens after '::'. */ + d_print_comp (dpi, options, operand); + else if (code && !strcmp (code, "st")) + /* Always print parens for sizeof (type). */ + { + d_append_char (dpi, '('); + d_print_comp (dpi, options, operand); + d_append_char (dpi, ')'); + } + else + d_print_subexpr (dpi, options, operand); + } return; case DEMANGLE_COMPONENT_BINARY: @@ -4397,11 +4495,33 @@ d_print_comp (struct d_print_info *dpi, int options, d_print_error (dpi); return; } - d_print_subexpr (dpi, options, d_left (d_right (dc))); - d_print_expr_op (dpi, options, d_left (dc)); - d_print_subexpr (dpi, options, d_left (d_right (d_right (dc)))); - d_append_string (dpi, " : "); - d_print_subexpr (dpi, options, d_right (d_right (d_right (dc)))); + { + struct demangle_component *op = d_left (dc); + struct demangle_component *first = d_left (d_right (dc)); + struct demangle_component *second = d_left (d_right (d_right (dc))); + struct demangle_component *third = d_right (d_right (d_right (dc))); + + if (!strcmp (op->u.s_operator.op->code, "qu")) + { + d_print_subexpr (dpi, options, first); + d_print_expr_op (dpi, options, op); + d_print_subexpr (dpi, options, second); + d_append_string (dpi, " : "); + d_print_subexpr (dpi, options, third); + } + else + { + d_append_string (dpi, "new "); + if (d_left (first) != NULL) + { + d_print_subexpr (dpi, options, first); + d_append_char (dpi, ' '); + } + d_print_comp (dpi, options, second); + if (third) + d_print_subexpr (dpi, options, third); + } + } return; case DEMANGLE_COMPONENT_TRINARY_ARG1: diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 642fe1427ed..3f3960a4093 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3935,7 +3935,7 @@ _Z1tIlEDTplcvT_Li5EclL_Z1qsELi6EEEv decltype (((long)(5))+(q(6))) t() # test for expansion of function parameter pack --format=gnu-v3 -_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_ +_Z1gIJidEEDTclL_Z1fEspplfp_Li1EEEDpT_ decltype (f(({parm#1}+(1))...)) g(int, double) # lambda tests --format=gnu-v3 @@ -4030,6 +4030,45 @@ decltype ((int)()) f(int, int) --format=gnu-v3 _Z1fDv4_iS_ f(int __vector(4), int __vector(4)) +--format=gnu-v3 +_Z2f1Ii1AEDTdsfp_fp0_ET0_MS2_T_ +decltype ({parm#1}.*{parm#2}) f1(A, int A::*) +--format=gnu-v3 +_Z2f2IiEDTquL_Z1bEfp_trET_ +decltype (b?{parm#1} : (throw)) f2(int) +--format=gnu-v3 +_Z6check1IiEvP6helperIXsznw_T_EEE +void check1(helper*) +--format=gnu-v3 +_Z6check2IiEvP6helperIXszgsnw_T_piEEE +void check2(helper*) +--format=gnu-v3 +_Z6check3IiEvP6helperIXsznwadL_Z1iE_T_piLi1EEEE +void check3(helper*) +--format=gnu-v3 +_Z6check4IiEvP6helperIXszna_A1_T_EEE +void check4(helper*) +--format=gnu-v3 +_Z6check5IiEvP6helperIXszna_A1_T_piEEE +void check5(helper*) +--format=gnu-v3 +_Z1fIiEDTcmgsdlfp_psfp_EPT_ +decltype ((::delete {parm#1}),(+{parm#1})) f(int*) +--format=gnu-v3 +_Z1fIiEDTcmdafp_psfp_EPT_ +decltype ((delete[] {parm#1}),(+{parm#1})) f(int*) +--format=gnu-v3 +_Z2f1IiEDTppfp_ET_ +decltype ({parm#1}++) f1(int) +--format=gnu-v3 +_Z2f1IiEDTpp_fp_ET_ +decltype (++{parm#1}) f1(int) +--format=gnu-v3 +_Z2f1IiEDTcl1gfp_ilEEET_ +decltype (g({parm#1}, {})) f1(int) +--format=gnu-v3 +_Z2f1IiEDTnw_T_ilEES0_ +decltype (new int{}) f1(int) # # Ada (GNAT) tests. # diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e0b3bc8566d..f2e68c5dc8f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2012-01-06 Jason Merrill + + * testsuite/abi/demangle/regression/cw-16.cc (main): Adjust + expected demangling. + 2012-01-06 Jonathan Wakely PR libstdc++/51504 diff --git a/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc b/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc index 49d44bc22d7..12fa6fe40ef 100644 --- a/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc +++ b/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc @@ -39,7 +39,7 @@ verify_demangle("_Z1fPFYPFiiEiE", verify_demangle("_Z1fI1XENT_1tES2_", "X::t f(X::t)"); verify_demangle("_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE", - "void f<5, A>(C::q)"); + "void f<5, A>(C::q)"); // 2003/12/03, libstdc++/13045 verify_demangle("_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE", "void f<1, (char)120>(A<(1)+((int)((double)[4028ae147ae147ae]))>)");