From 41b9fbb93c27190847b7ababff9910dd324336ab Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 2 Apr 2009 18:37:57 +0000 Subject: * mangle.c (write_expression): Mangle dependent name as source-name. PR c++/38030, 38850, 39070 * pt.c (type_dependent_expression_p_push): New fn. (tsubst_copy_and_build) [CALL_EXPR]: Only do arg-dep lookup when the substitution makes the call non-dependent. Preserve koenig_p. * parser.c (cp_parser_postfix_expression): Only do arg-dep lookup for non-dependent calls. * semantics.c (finish_call_expr): Revert earlier changes. * cp-tree.h: Revert change to finish_call_expr prototype. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_4-branch@145468 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 14 ++++++++++++++ gcc/cp/cp-tree.h | 3 ++- gcc/cp/mangle.c | 26 +++++++++++++++++++------- gcc/cp/parser.c | 10 ++++++---- gcc/cp/pt.c | 24 +++++++++++++++++++----- gcc/cp/semantics.c | 14 ++++---------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp0x/auto12.C | 2 +- gcc/testsuite/g++.dg/cpp0x/auto6.C | 2 +- 9 files changed, 71 insertions(+), 29 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7d539a30665..df27d7cecc9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2009-04-02 Jason Merrill + + * mangle.c (write_expression): Mangle dependent name as + source-name. + + PR c++/38030, 38850, 39070 + * pt.c (type_dependent_expression_p_push): New fn. + (tsubst_copy_and_build) [CALL_EXPR]: Only do arg-dep lookup when the + substitution makes the call non-dependent. Preserve koenig_p. + * parser.c (cp_parser_postfix_expression): Only do arg-dep lookup + for non-dependent calls. + * semantics.c (finish_call_expr): Revert earlier changes. + * cp-tree.h: Revert change to finish_call_expr prototype. + 2009-03-30 Jakub Jelinek Revert diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6b67d2dd62c..b0052c256f4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4605,6 +4605,7 @@ extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); extern bool type_dependent_expression_p (tree); extern bool any_type_dependent_arguments_p (const_tree); +extern bool type_dependent_expression_p_push (tree); extern bool value_dependent_expression_p (tree); extern bool any_value_dependent_elements_p (const_tree); extern bool dependent_omp_for_p (tree, tree, tree, tree); @@ -4764,7 +4765,7 @@ extern tree finish_stmt_expr_expr (tree, tree); extern tree finish_stmt_expr (tree, bool); extern tree stmt_expr_value_expr (tree); extern tree perform_koenig_lookup (tree, tree); -extern tree finish_call_expr (tree, tree, bool, int, +extern tree finish_call_expr (tree, tree, bool, bool, tsubst_flags_t); extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_this_expr (void); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index eabab7fb510..5f2ace0cbb1 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2159,12 +2159,6 @@ write_expression (tree expr) code = TREE_CODE (expr); } - if (code == OVERLOAD) - { - expr = OVL_FUNCTION (expr); - code = TREE_CODE (expr); - } - /* Handle pointers-to-members by making them look like expression nodes. */ if (code == PTRMEM_CST) @@ -2344,7 +2338,25 @@ write_expression (tree expr) switch (code) { case CALL_EXPR: - write_expression (CALL_EXPR_FN (expr)); + { + tree fn = CALL_EXPR_FN (expr); + + if (TREE_CODE (fn) == ADDR_EXPR) + fn = TREE_OPERAND (fn, 0); + + /* Mangle a dependent name as the name, not whatever happens to + be the first function in the overload set. */ + if ((TREE_CODE (fn) == FUNCTION_DECL + || TREE_CODE (fn) == OVERLOAD) + && type_dependent_expression_p_push (expr)) + fn = DECL_NAME (get_first_fn (fn)); + + if (TREE_CODE (fn) == IDENTIFIER_NODE) + write_source_name (fn); + else + write_expression (fn); + } + for (i = 0; i < call_expr_nargs (expr); ++i) write_expression (CALL_EXPR_ARG (expr, i)); write_char ('E'); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index bbd89d19c72..26d6678d1d7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4739,8 +4739,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (args) { koenig_p = true; - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + if (!any_type_dependent_arguments_p (args)) + postfix_expression + = perform_koenig_lookup (postfix_expression, args); } else postfix_expression @@ -4762,8 +4763,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (!DECL_FUNCTION_MEMBER_P (fn)) { koenig_p = true; - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + if (!any_type_dependent_arguments_p (args)) + postfix_expression + = perform_koenig_lookup (postfix_expression, args); } } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5092c72b177..c3873cd7ea3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11450,7 +11450,11 @@ tsubst_copy_and_build (tree t, not appropriate, even if an unqualified-name was used to denote the function. */ && !DECL_FUNCTION_MEMBER_P (get_first_fn (function))) - || TREE_CODE (function) == IDENTIFIER_NODE)) + || TREE_CODE (function) == IDENTIFIER_NODE) + /* Only do this when substitution turns a dependent call + into a non-dependent call. */ + && type_dependent_expression_p_push (t) + && !any_type_dependent_arguments_p (call_args)) function = perform_koenig_lookup (function, call_args); if (TREE_CODE (function) == IDENTIFIER_NODE) @@ -11481,12 +11485,9 @@ tsubst_copy_and_build (tree t, /*fn_p=*/NULL, complain)); } - /* Pass -1 for koenig_p so that build_new_function_call will - allow hidden friends found by arg-dependent lookup at template - parsing time. */ return finish_call_expr (function, call_args, /*disallow_virtual=*/qualified_p, - /*koenig_p*/-1, + koenig_p, complain); } @@ -16454,6 +16455,19 @@ type_dependent_expression_p (tree expression) return (dependent_type_p (TREE_TYPE (expression))); } +/* Like type_dependent_expression_p, but it also works while not processing + a template definition, i.e. during substitution or mangling. */ + +bool +type_dependent_expression_p_push (tree expr) +{ + bool b; + ++processing_template_decl; + b = type_dependent_expression_p (expr); + --processing_template_decl; + return b; +} + /* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call) contains a type-dependent expression. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 71fc43e855a..53570775042 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1836,14 +1836,10 @@ perform_koenig_lookup (tree fn, tree args) qualified. For example a call to `X::f' never generates a virtual call.) - KOENIG_P is 1 if we want to perform argument-dependent lookup, - -1 if we don't, but we want to accept functions found by previous - argument-dependent lookup, and 0 if we want nothing to do with it. - Returns code for the call. */ tree -finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, +finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p, tsubst_flags_t complain) { tree result; @@ -1866,7 +1862,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, || any_type_dependent_arguments_p (args)) { result = build_nt_call_list (fn, args); - KOENIG_LOOKUP_P (result) = koenig_p > 0; + KOENIG_LOOKUP_P (result) = koenig_p; if (cfun) { do @@ -1956,7 +1952,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, if (!result) /* A call to a namespace-scope function. */ - result = build_new_function_call (fn, args, koenig_p != 0, complain); + result = build_new_function_call (fn, args, koenig_p, complain); } else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) { @@ -1982,9 +1978,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, if (processing_template_decl) { result = build_call_list (TREE_TYPE (result), orig_fn, orig_args); - /* Don't repeat arg-dependent lookup at instantiation time if this call - is not type-dependent. */ - KOENIG_LOOKUP_P (result) = 0; + KOENIG_LOOKUP_P (result) = koenig_p; } return result; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index abc6f0e6e43..ef1ae816640 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-04-02 Jason Merrill + + * g++.dg/cpp0x/auto6.C: Adjust expected mangling. + * g++.dg/cpp0x/auto12.C: Likewise. + 2009-04-02 Ira Rosen PR tree-optimization/39595 diff --git a/gcc/testsuite/g++.dg/cpp0x/auto12.C b/gcc/testsuite/g++.dg/cpp0x/auto12.C index 34dc8c90b84..82d36f0d0d2 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto12.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto12.C @@ -58,6 +58,6 @@ int main() A().h(1); // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A().j(1); - // { dg-final { scan-assembler "_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_" } } + // { dg-final { scan-assembler "_Z1gIIidEEDTcl1fspplfp_Li1EEEDpT_" } } g(42, 1.0); } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto6.C b/gcc/testsuite/g++.dg/cpp0x/auto6.C index dfd6a202698..11e73d2e716 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto6.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto6.C @@ -101,7 +101,7 @@ int main() 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_" } } + // { dg-final { scan-assembler "_Z4add3IidEDTcl2agfp_fp0_EET_T0_" } } auto i3 = add3(1, 2.0); // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptfp_1fEEPT_" } } f(p); -- cgit v1.2.3