aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-04-02 18:37:57 +0000
committerJason Merrill <jason@redhat.com>2009-04-02 18:37:57 +0000
commit41b9fbb93c27190847b7ababff9910dd324336ab (patch)
tree8128c941196d2e4ee81a46dff34e2c2cda58f9ad
parentadd5e1ebf498ff7afd4745a8663b42a37303550b (diff)
* 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
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/mangle.c26
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/pt.c24
-rw-r--r--gcc/cp/semantics.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto12.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto6.C2
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 <jason@redhat.com>
+
+ * 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 <jakub@redhat.com>
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 <jason@redhat.com>
+
+ * g++.dg/cpp0x/auto6.C: Adjust expected mangling.
+ * g++.dg/cpp0x/auto12.C: Likewise.
+
2009-04-02 Ira Rosen <irar@il.ibm.com>
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<int>().h(1);
// { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } }
A<int>().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);