PR c++/13549
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Mar 2009 02:49:13 +0000 (02:49 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Mar 2009 02:49:13 +0000 (02:49 +0000)
        * 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
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/koenig7.C [new file with mode: 0644]

index 5d9f328..187ade4 100644 (file)
@@ -1,5 +1,12 @@
 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
index f07df91..5c5c912 100644 (file)
@@ -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)
                  {
index 840b0e0..5f01a83 100644 (file)
@@ -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;
 }
 
index 456abfc..82f3b89 100644 (file)
@@ -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);
 }
 
index a2f28bb..dfeb6fd 100644 (file)
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/g++.dg/template/koenig7.C b/gcc/testsuite/g++.dg/template/koenig7.C
new file mode 100644 (file)
index 0000000..07f2fca
--- /dev/null
@@ -0,0 +1,11 @@
+// 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>();}