From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19856 invoked by alias); 28 May 2005 22:47:38 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 19811 invoked by uid 22791); 28 May 2005 22:47:26 -0000 Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (199.232.76.164) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Sat, 28 May 2005 22:47:26 +0000 Received: from monty-python.gnu.org ([199.232.76.173]) by fencepost.gnu.org with esmtp (Exim 4.34) id 1DcA4x-0005tT-C6 for gcc@gnu.org; Sat, 28 May 2005 18:46:51 -0400 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.34) id 1DcA6Q-00055X-4k for gcc@gnu.org; Sat, 28 May 2005 18:48:22 -0400 Received: from [64.233.162.192] (helo=zproxy.gmail.com) by monty-python.gnu.org with esmtp (Exim 4.34) id 1DcA6P-00055C-Qo for gcc@gnu.org; Sat, 28 May 2005 18:48:22 -0400 Received: by zproxy.gmail.com with SMTP id 18so1831342nzp for ; Sat, 28 May 2005 15:47:07 -0700 (PDT) Received: by 10.36.224.43 with SMTP id w43mr97662nzg; Sat, 28 May 2005 15:47:07 -0700 (PDT) Received: from ?192.168.0.5? ([68.76.222.16]) by mx.gmail.com with ESMTP id 10sm1317765nzo.2005.05.28.15.47.07; Sat, 28 May 2005 15:47:07 -0700 (PDT) From: Douglas Gregor To: gcc-patches@gcc.gnu.org, gcc@gnu.org Subject: C++ PATCH: PR 2922 Date: Sat, 28 May 2005 23:57:00 -0000 User-Agent: KMail/1.7 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_3APmCg2CzbhVrds" Message-Id: <200505281727.03854.doug.gregor@gmail.com> X-SW-Source: 2005-05/txt/msg01554.txt.bz2 --Boundary-00=_3APmCg2CzbhVrds Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1866 Hello, This amusingly small patch fixes PR 2922 (two-stage lookup for unqualified function calls with type-dependent arguments). We need only keep the set of functions we found in the first stage, and it will be augmented by those functions found using argument-dependent lookup at the second stage. Also, we explicitly deal with DR 164 by not optimizing away checks for functions found via ADL in the namespace of the template. Note that this only fixes two-stage lookup for function names. Operations are still handled improperly. I've reported PR c++/21802 that illustrates this problem. The testcase from that PR is included in this testsuite patch. Tested i686-pc-linux-gnu. No new regressions on the g++ or libstdc++ test suites. The new tests (from PR 2922) pass; the new one from PR 21802 is XFAIL'd; some tests needed tweaking because error-messages changed or the test should not have been passing in the first place. Okay for mainline? Doug Gregor 2005-05-28 Douglas Gregor PR c++/2922 * semantics.c (perform_koenig_lookup): For dependent calls, just return the set of functions we've found so far. Later, it will be augmented by those found through argument-dependent lookup. * name-lookup.c (lookup_arg_dependent): 2005-05-28 Douglas Gregor PR c++/2922 * g++.dg/lookup/two-stage2.C: New. * g++.dg/lookup/two-stage3.C: New. * g++.dg/lookup/two-stage4.C: New. Illustrates how we have not yet fixed two-stage name lookup for operators. * g++.dg/template/call3.C: Compiler now produces an appropriate error message. * g++.dg/template/crash37.C: Compiler now describes bla() on line 14 as a candidate. * g++.dg/template/ptrmem4.C: Compiler produces different error message. * g++.old-deja/g++.other/pmf3.C: Compiler now describes connect_to_method as a candidate. --Boundary-00=_3APmCg2CzbhVrds Content-Type: text/x-diff; charset="us-ascii"; name="2922-cp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="2922-cp.patch" Content-length: 3017 Index: name-lookup.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v retrieving revision 1.120 diff -c -3 -p -r1.120 name-lookup.c *** name-lookup.c 25 May 2005 04:17:36 -0000 1.120 --- name-lookup.c 28 May 2005 19:57:48 -0000 *************** tree *** 4452,4485 **** lookup_arg_dependent (tree name, tree fns, tree args) { struct arg_lookup k; - tree fn = NULL_TREE; timevar_push (TV_NAME_LOOKUP); k.name = name; k.functions = fns; k.classes = NULL_TREE; ! /* We've already looked at some namespaces during normal unqualified ! lookup -- but we don't know exactly which ones. If the functions ! we found were brought into the current namespace via a using ! declaration, we have not really checked the namespace from which ! they came. Therefore, we check all namespaces here -- unless the ! function we have is from the current namespace. Even then, we ! must check all namespaces if the function is a local ! declaration; any other declarations present at namespace scope ! should be visible during argument-dependent lookup. */ ! if (fns) ! fn = OVL_CURRENT (fns); ! if (fn && TREE_CODE (fn) == FUNCTION_DECL ! && (CP_DECL_CONTEXT (fn) != current_decl_namespace () ! || DECL_LOCAL_FUNCTION_P (fn))) ! k.namespaces = NULL_TREE; ! else ! /* Setting NAMESPACES is purely an optimization; it prevents ! adding functions which are already in FNS. Adding them would ! be safe -- "joust" will eliminate the duplicates -- but ! wasteful. */ ! k.namespaces = build_tree_list (current_decl_namespace (), NULL_TREE); arg_assoc_args (&k, args); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions); --- 4452,4469 ---- lookup_arg_dependent (tree name, tree fns, tree args) { struct arg_lookup k; timevar_push (TV_NAME_LOOKUP); k.name = name; k.functions = fns; k.classes = NULL_TREE; ! /* We previously performed an optimization here by setting ! NAMESPACES to the current namespace when it was safe. However, DR ! 164 says that namespaces that were already searched in the first ! stage of template processing are searched again (potentially ! picking up later definitions) in the second stage. */ ! k.namespaces = NULL_TREE; arg_assoc_args (&k, args); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions); Index: semantics.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v retrieving revision 1.473 diff -c -3 -p -r1.473 semantics.c *** semantics.c 28 May 2005 01:38:11 -0000 1.473 --- semantics.c 28 May 2005 19:57:50 -0000 *************** perform_koenig_lookup (tree fn, tree arg *** 1739,1746 **** /* The unqualified name could not be resolved. */ fn = unqualified_fn_lookup_error (identifier); } - else - fn = identifier; return fn; } --- 1739,1744 ---- --Boundary-00=_3APmCg2CzbhVrds Content-Type: text/x-diff; charset="us-ascii"; name="2922-testsuite.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="2922-testsuite.patch" Content-length: 5266 Index: g++.dg/lookup/two-stage2.C =================================================================== RCS file: g++.dg/lookup/two-stage2.C diff -N g++.dg/lookup/two-stage2.C *** /dev/null 1 Jan 1970 00:00:00 -0000 --- g++.dg/lookup/two-stage2.C 28 May 2005 19:58:08 -0000 *************** *** 0 **** --- 1,19 ---- + // { dg-do compile } + // PR c++/2922 + + char& f(char); + + template + void g(T t) + { + char& c1 = f(1); // not dependent + char& c2 = f(t); // dependent + } + + int&f (int); + + int main() + { + g(2); // f(char) followed by f(int) + g('a'); // two f(char) + } Index: g++.dg/lookup/two-stage3.C =================================================================== RCS file: g++.dg/lookup/two-stage3.C diff -N g++.dg/lookup/two-stage3.C *** /dev/null 1 Jan 1970 00:00:00 -0000 --- g++.dg/lookup/two-stage3.C 28 May 2005 19:58:08 -0000 *************** *** 0 **** --- 1,22 ---- + // { dg-do compile } + // PR c++/2922 + + namespace tpl_ { + + template + char test(T); + + template + struct check + { + static T const t; + enum { value = 1 == sizeof(test(t)) }; + }; + + double test(int); + + } + + bool const two_phase_lookup_supported = tpl_::check::value; + + int compile_time_assert[two_phase_lookup_supported ? 1 : -1]; Index: g++.dg/lookup/two-stage4.C =================================================================== RCS file: g++.dg/lookup/two-stage4.C diff -N g++.dg/lookup/two-stage4.C *** /dev/null 1 Jan 1970 00:00:00 -0000 --- g++.dg/lookup/two-stage4.C 28 May 2005 19:58:08 -0000 *************** *** 0 **** --- 1,20 ---- + PR c++/21802 + // Contributed by Douglas Gregor + + template struct wrap {}; + + template bool& operator==(wrap, wrap); + + template + void g(T, wrap > x) + { + bool& b = x == x; // { dg-bogus "invalid initialization of reference" "" { xfail *-*-*} } + } + + template int& operator==(wrap >, wrap >); + + void h() + { + wrap > x; + g(17, x); + } Index: g++.dg/template/call3.C =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/call3.C,v retrieving revision 1.1 diff -c -3 -p -r1.1 call3.C *** g++.dg/template/call3.C 12 Nov 2004 21:47:13 -0000 1.1 --- g++.dg/template/call3.C 28 May 2005 19:58:09 -0000 *************** struct A *** 9,15 **** template struct B : T { ! B() { foo(T()); } }; B b; --- 9,15 ---- template struct B : T { ! B() { foo(T()); } // { dg-error "cannot convert" } }; B b; Index: g++.dg/template/crash37.C =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/crash37.C,v retrieving revision 1.1 diff -c -3 -p -r1.1 crash37.C *** g++.dg/template/crash37.C 5 May 2005 19:08:12 -0000 1.1 --- g++.dg/template/crash37.C 28 May 2005 19:58:09 -0000 *************** struct coperator_stack *** 11,17 **** struct helper {}; template ! void bla(F f) { } --- 11,17 ---- struct helper {}; template ! void bla(F f) // { dg-error "candidates" } { } *************** struct definition *** 20,26 **** { definition() { ! bla(coperator_stack::push3); // { dg-error "" } } }; --- 20,26 ---- { definition() { ! bla(coperator_stack::push3); // { dg-error "" } } }; Index: g++.dg/template/ptrmem4.C =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/ptrmem4.C,v retrieving revision 1.2 diff -c -3 -p -r1.2 ptrmem4.C *** g++.dg/template/ptrmem4.C 7 Oct 2003 07:07:07 -0000 1.2 --- g++.dg/template/ptrmem4.C 28 May 2005 19:58:09 -0000 *************** *** 6,12 **** // Pointer to member function template argument deduction ICE. ! template void queryAliases(CONT& fill_me); // { dg-error "argument" } struct SpyExample { --- 6,12 ---- // Pointer to member function template argument deduction ICE. ! template void queryAliases(CONT& fill_me); // { dg-error "candidates" } struct SpyExample { *************** struct SpyExample *** 16,20 **** void SpyExample::ready() { ! queryAliases(inputs); // { dg-error "" } } --- 16,20 ---- void SpyExample::ready() { ! queryAliases(inputs); // { dg-error "" } } Index: g++.old-deja/g++.other/pmf3.C =================================================================== RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/pmf3.C,v retrieving revision 1.3 diff -c -3 -p -r1.3 pmf3.C *** g++.old-deja/g++.other/pmf3.C 1 May 2003 02:02:50 -0000 1.3 --- g++.old-deja/g++.other/pmf3.C 28 May 2005 19:58:12 -0000 *************** *** 5,15 **** template void connect_to_method( T *receiver, ! void (T::*method)()) {} class Gtk_Base ! { public: void expose(); void show(); --- 5,15 ---- template void connect_to_method( T *receiver, ! void (T::*method)()) // { dg-error "candidates are" } {} class Gtk_Base ! { public: void expose(); void show(); --Boundary-00=_3APmCg2CzbhVrds--