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.
+
PR c++/9634
PR c++/29469
PR c++/29607
}
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)
{
{
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)
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)
fn = unqualified_fn_lookup_error (identifier);
}
+ if (fn && tmpl_args)
+ fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args);
+
return fn;
}
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
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);
}
+2009-03-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/13549
+ * g++.dg/template/koenig7.C: New test.
+
2009-03-04 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/torture/predcom-1.C: New test.
--- /dev/null
+// PR c++/13549
+// We need to do arg-dep lookup for g<T>(j) at instantiation time because
+// g<T> is dependent, even though (j) is not; at that point we can find
+// g(h).
+
+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>();}