diff options
author | Jason Merrill <jason@redhat.com> | 2012-01-06 16:39:43 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2012-01-06 16:39:43 -0500 |
commit | 4b6aaa996e0d8f5abac818315b6f77cb3596db98 (patch) | |
tree | a4fb9016edd51d789295648c2f9d497fc2a85eb3 /gcc | |
parent | 49f2da1a16b6336cbc8f5273a3dc835625fbf23f (diff) | |
download | gcc-4b6aaa996e0d8f5abac818315b6f77cb3596db98.zip gcc-4b6aaa996e0d8f5abac818315b6f77cb3596db98.tar.gz gcc-4b6aaa996e0d8f5abac818315b6f77cb3596db98.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/common.opt | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 141 | ||||
-rw-r--r-- | gcc/cp/operators.def | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle51.C | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle52.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle53.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle54.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle55.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle56.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle57.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle58.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle59.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/trailing3.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic111.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic4.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic42.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nontype22.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr35240.C | 5 |
23 files changed, 352 insertions, 26 deletions
diff --git a/gcc/common.opt b/gcc/common.opt index 6cfe17a..0544478 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 01480e3..041722d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,21 @@ 2012-01-06 Jason Merrill <jason@redhat.com> + 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 6e62bd1..ccad644 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 e5c2895..f4efa67 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 <expression>* _ <type> E + ::= [gs] nw <expression>* _ <type> <initializer> + ::= [gs] na <expression>* _ <type> E + ::= [gs] na <expression>* _ <type> <initializer> + <initializer> ::= pi <expression>* 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 20d811b..3dc7404 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 77e3388..bc3dd97 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 dea7632..8ef3e25 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 3f46fed..e96146d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,21 @@ 2012-01-06 Jason Merrill <jason@redhat.com> + * 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 <burnus@net-b.de> diff --git a/gcc/testsuite/g++.dg/abi/mangle51.C b/gcc/testsuite/g++.dg/abi/mangle51.C new file mode 100644 index 0000000..4992f1a --- /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 <unsigned int> struct helper {}; +// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXsznw_T_EEE" } } +template <class T> void check1( helper<sizeof(new T)> * ) { } +// { dg-final { scan-assembler "_Z6check2IiEvP6helperIXszgsnw_T_piEEE" } } +template <class T> void check2( helper<sizeof(::new T())> * ) { } +// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXsznwadL_Z1iE_T_piLi1EEEE" } } +template <class T> void check3( helper<sizeof(new (&i) T(1))> * ) { } +// { dg-final { scan-assembler "_Z7check3aIiEvP6helperIXsznw_T_ilLi1EEEE" } } +template <class T> void check3a( helper<sizeof(new T{1})> * ) { } +// { dg-final { scan-assembler "_Z6check4IiEvP6helperIXszna_A1_T_EEE" } } +template <class T> void check4( helper<sizeof(new T[1])> * ) { } +// { dg-final { scan-assembler "_Z6check5IiEvP6helperIXszna_A1_T_piEEE" } } +template <class T> void check5( helper<sizeof(new T[1]())> * ) { } +int main() +{ + check1<int>(0); + check2<int>(0); + check3<int>(0); + check3a<int>(0); + check4<int>(0); + check5<int>(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle52.C b/gcc/testsuite/g++.dg/abi/mangle52.C new file mode 100644 index 0000000..2c46341 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle52.C @@ -0,0 +1,21 @@ +// { dg-options "-fabi-version=0" } + +template <unsigned int> struct helper {}; +// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXszscT_Li1EEE" } } +template <class T> void check1( helper<sizeof(static_cast<T>(1))> * ) { } +// { dg-final { scan-assembler "_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE" } } +template <class T, T* p> void check2( helper<sizeof(const_cast<T*>(p))> * ) { } +// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXszrcPT_Li0EEE" } } +template <class T> void check3( helper<sizeof(reinterpret_cast<T*>(0))> * ) { } +// { dg-final { scan-assembler "_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE" } } +template <class T, T* p> void check4( helper<sizeof(dynamic_cast<T*>(p))> * ) { } + +struct A{} a; +int i; +int main() +{ + check1<int>(0); + check2<int,&i>(0); + check3<int>(0); + check4<A,&a>(0); +} diff --git a/gcc/testsuite/g++.dg/abi/mangle53.C b/gcc/testsuite/g++.dg/abi/mangle53.C new file mode 100644 index 0000000..b279182 --- /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 <class T> auto f (T t) -> decltype(b?t:throw 42) { return 0; } +// { dg-final { scan-assembler "_Z2f2IiEDTquL_Z1bEfp_trET_" } } +template <class T> 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 0000000..ea98df1 --- /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 <class T> auto f1 (T t) -> decltype(t++) { return i; } +// { dg-final { scan-assembler "_Z2f2IiEDTpp_fp_ET_" } } +template <class T> auto f2 (T t) -> decltype(++t) { return i; } +// { dg-final { scan-assembler "_Z2f3IiEDTmmfp_ET_" } } +template <class T> auto f3 (T t) -> decltype(t--) { return i; } +// { dg-final { scan-assembler "_Z2f4IiEDTmm_fp_ET_" } } +template <class T> 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 0000000..72caadc --- /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 <class T, class U> auto f1 (U u, T U::* p) -> decltype(u.*p) { return u.*p; } +// { dg-final { scan-assembler "_Z2f2Ii1AEDTpmfp_fp0_EPT0_MS2_T_" } } +template <class T, class U> 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 0000000..0fd2701 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle56.C @@ -0,0 +1,13 @@ +// { dg-options "-std=c++0x" } + +template <class T> T g(T t1, T t2) { return t2; } +// { dg-final { scan-assembler "_Z2f1IiEDTcl1gfp_ilEEET_" } } +template <class T> auto f1 (T t) -> decltype(g(t,{})) { return g(t,{}); } +// { dg-final { scan-assembler "_Z2f2IiEDTcl1gfp_tlT_EEES0_" } } +template <class T> 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 0000000..3d9d81e --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle57.C @@ -0,0 +1,16 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +template<typename T> int cmp1(T a, T b); +int cmp2(char a, char b); +template<typename T, int (*cmp)(T, T)> struct A { }; +// { dg-final { scan-assembler "_Z1fIcEvR1AIT_X4cmp1EE" } } +template <typename T> void f (A<T,cmp1> &); +// { dg-final { scan-assembler "_Z1fIcEvR1AIT_L_Z4cmp2ccEE" } } +template <typename T> void f (A<T,cmp2> &); +void g() +{ + A<char,cmp1> a; + f(a); + A<char,cmp2> 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 0000000..14e5543 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle58.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++0x -fabi-version=0" } + +template<typename T, int (*cmp)(T, T)> struct A { }; +struct B { + template<typename T> static int cmp1(T a, T b); + static int cmp2(char a, char b); + // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } } + template <typename T> static void f (A<T,cmp1> &); + // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } } + template <typename T> static void f (A<T,cmp2> &); +}; + +void g() +{ + A<char,B::cmp1> a; + B::f(a); + A<char,B::cmp2> 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 0000000..3c88ec8 --- /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 <class T> auto f (T* p) -> decltype(delete p, +p) { return p; } +// { dg-final { scan-assembler "_Z1gIiEDTcmgsdlfp_psfp_EPT_" } } +template <class T> auto g (T* p) -> decltype(::delete p, +p) { return p; } +// { dg-final { scan-assembler "_Z1hIiEDTcmdafp_psfp_EPT_" } } +template <class T> auto h (T* p) -> decltype(delete[] p, +p) { return p; } +// { dg-final { scan-assembler "_Z1iIiEDTcmgsdafp_psfp_EPT_" } } +template <class T> 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 82d36f0..1c64f45 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 <class T> struct B @@ -58,6 +58,6 @@ int main() A<int>().h(1); // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A<int>().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 378162e..cb94ce6 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<typename... Args1> 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 9257a92..1bdad32 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<typename... Args> class tuple {}; @@ -9,7 +9,7 @@ void f_two(tuple<int, float>) {} void f_nested(tuple<int, tuple<double, char>, 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 47d9b66..3ec68e8 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<typename... Args> void f(Args...) { } diff --git a/gcc/testsuite/g++.dg/template/nontype22.C b/gcc/testsuite/g++.dg/template/nontype22.C index f2c8c46..44d8479 100644 --- a/gcc/testsuite/g++.dg/template/nontype22.C +++ b/gcc/testsuite/g++.dg/template/nontype22.C @@ -3,7 +3,7 @@ template<typename T> int cmp1(T a, T b); template<typename T, int (*cmp)(T, T) = cmp1> struct A { }; -template <typename T> void f (A<T> &); // { dg-bogus "" "" { xfail *-*-* } } +template <typename T> void f (A<T> &); void g() { A<char> a; diff --git a/gcc/testsuite/g++.dg/template/pr35240.C b/gcc/testsuite/g++.dg/template/pr35240.C index 88e2505..5b94551 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<int> struct A {}; -template<int N> A<sizeof(new int[N][N])> foo(); // { dg-message "unimplemented" } +template<int N> A<sizeof(new int[N][N])> foo(); void bar() { - foo<1>(); // { dg-message "required" } + foo<1>(); } |