From 32f71e4fd1d721a557c473ff7942e5bf6ed334c9 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 5 Mar 2009 02:49:13 +0000 Subject: [PATCH] PR c++/13549 * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR. * parser.c (cp_parser_postfix_expression): Call it for TEMPLATE_ID_EXPR. * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR. (get_first_fn): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@144636 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/parser.c | 3 ++- gcc/cp/semantics.c | 13 ++++++++++++- gcc/cp/tree.c | 7 +++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/koenig7.C | 11 +++++++++++ 6 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/koenig7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d9f328..187ade4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2009-03-04 Jason Merrill + PR c++/13549 + * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR. + * parser.c (cp_parser_postfix_expression): Call it for + TEMPLATE_ID_EXPR. + * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR. + (get_first_fn): Likewise. + PR c++/9634 PR c++/29469 PR c++/29607 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f07df91..5c5c912 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4732,7 +4732,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } koenig_p = false; - if (idk == CP_ID_KIND_UNQUALIFIED) + if (idk == CP_ID_KIND_UNQUALIFIED + || idk == CP_ID_KIND_TEMPLATE_ID) { if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 840b0e0..5f01a83 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1801,6 +1801,13 @@ perform_koenig_lookup (tree fn, tree args) { tree identifier = NULL_TREE; tree functions = NULL_TREE; + tree tmpl_args = NULL_TREE; + + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + { + tmpl_args = TREE_OPERAND (fn, 1); + fn = TREE_OPERAND (fn, 0); + } /* Find the name of the overloaded function. */ if (TREE_CODE (fn) == IDENTIFIER_NODE) @@ -1820,7 +1827,8 @@ perform_koenig_lookup (tree fn, tree args) Do Koenig lookup -- unless any of the arguments are type-dependent. */ - if (!any_type_dependent_arguments_p (args)) + if (!any_type_dependent_arguments_p (args) + && !any_dependent_template_arguments_p (tmpl_args)) { fn = lookup_arg_dependent (identifier, functions, args); if (!fn) @@ -1828,6 +1836,9 @@ perform_koenig_lookup (tree fn, tree args) fn = unqualified_fn_lookup_error (identifier); } + if (fn && tmpl_args) + fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args); + return fn; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 456abfc..82f3b89 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1175,8 +1175,9 @@ is_overloaded_fn (tree x) x = TREE_OPERAND (x, 1); if (BASELINK_P (x)) x = BASELINK_FUNCTIONS (x); - if (TREE_CODE (x) == TEMPLATE_ID_EXPR - || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) + if (TREE_CODE (x) == TEMPLATE_ID_EXPR) + x = TREE_OPERAND (x, 0); + if (DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) || (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x))) return 2; return (TREE_CODE (x) == FUNCTION_DECL @@ -1202,6 +1203,8 @@ get_first_fn (tree from) from = TREE_OPERAND (from, 1); if (BASELINK_P (from)) from = BASELINK_FUNCTIONS (from); + if (TREE_CODE (from) == TEMPLATE_ID_EXPR) + from = TREE_OPERAND (from, 0); return OVL_CURRENT (from); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a2f28bb..dfeb6fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-04 Jason Merrill + + PR c++/13549 + * g++.dg/template/koenig7.C: New test. + 2009-03-04 Nathan Sidwell * g++.dg/torture/predcom-1.C: New test. diff --git a/gcc/testsuite/g++.dg/template/koenig7.C b/gcc/testsuite/g++.dg/template/koenig7.C new file mode 100644 index 0000000..07f2fca --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig7.C @@ -0,0 +1,11 @@ +// PR c++/13549 +// We need to do arg-dep lookup for g(j) at instantiation time because +// g is dependent, even though (j) is not; at that point we can find +// g(h). + +template int g(int); +class h{}; +template int l(){h j; return g(j);} +template int g(const h&); +class j{}; +int jj(){return l();} -- 2.7.4