This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/13549
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 04 Mar 2009 21:47:55 -0500
- Subject: C++ PATCH for c++/13549
We should be doing argument-dependent lookup for template-id-exprs; this
turns out to be a relatively contained change.
Tested x86_64-pc-linux-gnu, applied to trunk.
2009-03-04 Jason Merrill <jason@redhat.com>
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.
Index: cp/tree.c
===================================================================
*** cp/tree.c (revision 144617)
--- cp/tree.c (working copy)
*************** is_overloaded_fn (tree x)
*** 1175,1182 ****
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))
|| (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x)))
return 2;
return (TREE_CODE (x) == FUNCTION_DECL
--- 1175,1183 ----
x = TREE_OPERAND (x, 1);
if (BASELINK_P (x))
x = BASELINK_FUNCTIONS (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
*************** get_first_fn (tree from)
*** 1202,1207 ****
--- 1203,1210 ----
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);
}
Index: cp/semantics.c
===================================================================
*** cp/semantics.c (revision 144617)
--- cp/semantics.c (working copy)
*************** perform_koenig_lookup (tree fn, tree arg
*** 1801,1806 ****
--- 1801,1813 ----
{
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)
*************** perform_koenig_lookup (tree fn, tree arg
*** 1820,1826 ****
Do Koenig lookup -- unless any of the arguments are
type-dependent. */
! if (!any_type_dependent_arguments_p (args))
{
fn = lookup_arg_dependent (identifier, functions, args);
if (!fn)
--- 1827,1834 ----
Do Koenig lookup -- unless any of the arguments are
type-dependent. */
! if (!any_type_dependent_arguments_p (args)
! && !any_dependent_template_arguments_p (tmpl_args))
{
fn = lookup_arg_dependent (identifier, functions, args);
if (!fn)
*************** perform_koenig_lookup (tree fn, tree arg
*** 1828,1833 ****
--- 1836,1844 ----
fn = unqualified_fn_lookup_error (identifier);
}
+ if (fn && tmpl_args)
+ fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args);
+
return fn;
}
Index: cp/parser.c
===================================================================
*** cp/parser.c (revision 144618)
--- cp/parser.c (working copy)
*************** cp_parser_postfix_expression (cp_parser
*** 4732,4738 ****
}
koenig_p = false;
! if (idk == CP_ID_KIND_UNQUALIFIED)
{
if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
{
--- 4732,4739 ----
}
koenig_p = false;
! if (idk == CP_ID_KIND_UNQUALIFIED
! || idk == CP_ID_KIND_TEMPLATE_ID)
{
if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
{
Index: testsuite/g++.dg/template/koenig7.C
===================================================================
*** testsuite/g++.dg/template/koenig7.C (revision 0)
--- testsuite/g++.dg/template/koenig7.C (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ // PR c++/13549
+
+ template <typename T> int g(int);
+ class h{};
+ template <typename T> int l(){h j; return g<T>(j);}
+ template <typename T> int g(const h&);
+ class j{};
+ int jj(){return l<j>();}