PR c++/11808
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2003 17:32:30 +0000 (17:32 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2003 17:32:30 +0000 (17:32 +0000)
* cp-tree.h (KOENIG_LOOKUP_P): New macro.
(finish_call_expr): Change prototype.
* parser.c (cp_parser_postfix_expression): Adjust call to
finish_call_expr.
* pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P.
* semantics.c (finish_call_expr): Add koenig_p parameter.

PR c++/11808
* g++.dg/expr/call1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70998 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/call1.C [new file with mode: 0644]

index 326da4b..e28ff5b 100644 (file)
@@ -1,3 +1,13 @@
+2003-09-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11808
+       * cp-tree.h (KOENIG_LOOKUP_P): New macro.
+       (finish_call_expr): Change prototype.
+       * parser.c (cp_parser_postfix_expression): Adjust call to
+       finish_call_expr.
+       * pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P.
+       * semantics.c (finish_call_expr): Add koenig_p parameter.
+
 2003-09-01  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/12114
index f17b67c..cf4b8ce 100644 (file)
@@ -46,6 +46,7 @@ struct diagnostic_context;
       PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
       PARMLIST_ELLIPSIS_P (in PARMLIST)
       DECL_PRETTY_FUNCTION_P (in VAR_DECL)
+      KOENIG_LOOKUP_P (in CALL_EXPR)
    1: IDENTIFIER_VIRTUAL_P.
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -2293,6 +2294,10 @@ struct lang_decl GTY(())
 #define DELETE_EXPR_USE_GLOBAL(NODE)   TREE_LANG_FLAG_0 (NODE)
 #define DELETE_EXPR_USE_VEC(NODE)      TREE_LANG_FLAG_1 (NODE)
 
+/* In a CALL_EXPR appearing in a template, true if Koenig lookup
+   should be performed at instantiation time.  */
+#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0(NODE)
+
 /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
    constructor call, rather than an ordinary function call.  */
 #define AGGR_INIT_VIA_CTOR_P(NODE) \
@@ -4105,7 +4110,7 @@ extern tree begin_stmt_expr                     (void);
 extern tree finish_stmt_expr_expr              (tree);
 extern tree finish_stmt_expr                    (tree, bool);
 extern tree perform_koenig_lookup               (tree, tree);
-extern tree finish_call_expr                    (tree, tree, bool);
+extern tree finish_call_expr                    (tree, tree, bool, bool);
 extern tree finish_increment_expr               (tree, enum tree_code);
 extern tree finish_this_expr                    (void);
 extern tree finish_object_call_expr             (tree, tree, tree);
index 735d592..01d6dba 100644 (file)
@@ -3506,6 +3506,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
        case CPP_OPEN_PAREN:
          /* postfix-expression ( expression-list [opt] ) */
          {
+           bool koenig_p;
            tree args = (cp_parser_parenthesized_expression_list 
                         (parser, false, /*non_constant_p=*/NULL));
 
@@ -3524,14 +3525,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
                parser->non_constant_expression_p = true;
              }
 
+           koenig_p = false;
            if (idk == CP_ID_KIND_UNQUALIFIED)
              {
                if (args
                    && (is_overloaded_fn (postfix_expression)
                        || DECL_P (postfix_expression)
                        || TREE_CODE (postfix_expression) == IDENTIFIER_NODE))
-                 postfix_expression 
-                   = perform_koenig_lookup (postfix_expression, args);
+                 {
+                   koenig_p = true;
+                   postfix_expression 
+                     = perform_koenig_lookup (postfix_expression, args);
+                 }
                else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
                  postfix_expression
                    = unqualified_fn_lookup_error (postfix_expression);
@@ -3570,12 +3575,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
                 function.  */
              postfix_expression
                = finish_call_expr (postfix_expression, args,
-                                   /*disallow_virtual=*/true);
+                                   /*disallow_virtual=*/true,
+                                   koenig_p);
            else
              /* All other function calls.  */
              postfix_expression 
                = finish_call_expr (postfix_expression, args, 
-                                   /*disallow_virtual=*/false);
+                                   /*disallow_virtual=*/false,
+                                   koenig_p);
 
            /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
            idk = CP_ID_KIND_NONE;
index 8cf8d15..ae47b60 100644 (file)
@@ -8090,18 +8090,9 @@ tsubst_copy_and_build (tree t,
        bool koenig_p;
 
        function = TREE_OPERAND (t, 0);
-       /* To determine whether or not we should perform Koenig lookup
-          we must look at the form of the FUNCTION.  */
-       koenig_p = !(/* Koenig lookup does not apply to qualified
-                       names.  */
-                    TREE_CODE (function) == SCOPE_REF
-                    /* Or to references to members of classes.  */
-                    || TREE_CODE (function) == COMPONENT_REF
-                    /* If it is a FUNCTION_DECL or a baselink, then
-                       the name was already resolved when the
-                       template was parsed.  */
-                    || TREE_CODE (function) == FUNCTION_DECL
-                    || TREE_CODE (function) == BASELINK);
+       /* When we parsed the expression,  we determined whether or
+          not Koenig lookup should be performed.  */
+       koenig_p = KOENIG_LOOKUP_P (t);
        if (TREE_CODE (function) == SCOPE_REF)
          {
            qualified_p = true;
@@ -8117,23 +8108,22 @@ tsubst_copy_and_build (tree t,
            function = tsubst_copy_and_build (function, args, complain, 
                                              in_decl,
                                              !qualified_p);
+           if (BASELINK_P (function))
+             qualified_p = true;
          }
 
        call_args = RECUR (TREE_OPERAND (t, 1));
          
-       if (BASELINK_P (function))
-         qualified_p = 1;
-
        if (koenig_p
-           && TREE_CODE (function) != TEMPLATE_ID_EXPR
            && (is_overloaded_fn (function)
                || DECL_P (function)
                || TREE_CODE (function) == IDENTIFIER_NODE))
+         function = perform_koenig_lookup (function, call_args);
+
+       if (TREE_CODE (function) == IDENTIFIER_NODE)
          {
-           if (call_args)
-             function = perform_koenig_lookup (function, call_args);
-           else if (TREE_CODE (function) == IDENTIFIER_NODE)
-             function = unqualified_name_lookup_error (function);
+           unqualified_name_lookup_error (function);
+           return error_mark_node;
          }
 
        /* Remember that there was a reference to this entity.  */
@@ -8151,7 +8141,8 @@ tsubst_copy_and_build (tree t,
                   call_args, NULL_TREE, 
                   qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
        return finish_call_expr (function, call_args, 
-                                /*disallow_virtual=*/qualified_p);
+                                /*disallow_virtual=*/qualified_p,
+                                koenig_p);
       }
 
     case COND_EXPR:
index c9f3675..8670f8b 100644 (file)
@@ -1585,7 +1585,7 @@ perform_koenig_lookup (tree fn, tree args)
    Returns code for the call.  */
 
 tree 
-finish_call_expr (tree fn, tree args, bool disallow_virtual)
+finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
 {
   tree result;
   tree orig_fn;
@@ -1605,7 +1605,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
     {
       if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (args))
-       return build_nt (CALL_EXPR, fn, args);
+       {
+         result = build_nt (CALL_EXPR, fn, args);
+         KOENIG_LOOKUP_P (result) = koenig_p;
+         return result;
+       }
       if (!BASELINK_P (fn)
          && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
          && TREE_TYPE (fn) != unknown_type_node)
@@ -1707,7 +1711,10 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
     result = build_function_call (fn, args);
 
   if (processing_template_decl)
-    return build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+    {
+      result = build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+      KOENIG_LOOKUP_P (result) = koenig_p;
+    }
   return result;
 }
 
index b62f69c..f2d74d8 100644 (file)
@@ -1,3 +1,8 @@
+2003-09-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11808
+       * g++.dg/expr/call1.C: New test.
+
 2003-09-01  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/12114
diff --git a/gcc/testsuite/g++.dg/expr/call1.C b/gcc/testsuite/g++.dg/expr/call1.C
new file mode 100644 (file)
index 0000000..42d18db
--- /dev/null
@@ -0,0 +1,16 @@
+namespace NS_1 {
+  struct A {};
+  struct foo {};
+}
+
+namespace NS_2 {
+  template <typename T> void foo(T);
+  
+  template <typename T>
+  void bar() {
+    NS_1::A a;
+    NS_2::foo(a);
+  }
+
+  template void bar<int>();
+}