From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30096 invoked by alias); 15 Jan 2003 21:36:03 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 30080 invoked by uid 71); 15 Jan 2003 21:36:03 -0000 Date: Wed, 15 Jan 2003 21:36:00 -0000 Message-ID: <20030115213603.30079.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: Wolfgang Bangerth Subject: Re: c++/9298: [3.4 regression] [new parser] ICE with function-pointer-type template args Reply-To: Wolfgang Bangerth X-SW-Source: 2003-01/txt/msg00979.txt.bz2 List-Id: The following reply was made to PR c++/9298; it has been noted by GNATS. From: Wolfgang Bangerth To: Volker Reichelt Cc: gcc-bugs@gcc.gnu.org, Subject: Re: c++/9298: [3.4 regression] [new parser] ICE with function-pointer-type template args Date: Wed, 15 Jan 2003 15:35:39 -0600 (CST) > sorry for the confusion, I was *quite* wrong. No problem :-) You're hereby sentenced to three days in the C++ testcase diction jail: struct bars { bool behind (); }; ... if (bars().behind()) printf("foo :-)"); > Let's have another look at the code: > > The declaration of foo as a static template function is of course legal. > But I disagree with you when you say > > > It's illegal, though, to use its address as a template parameter! > > Why should it be illegal? You can use the address of a static variable as > a template parameter, too: > > ------------snip here------------- > int i; > template void foo() {} > template void foo<&i> (); > ---------------------------------- Values for pointer- or reference-type template arguments need to have _external_ linkage. "int i" does have that, "static void foo()" doesn't. > Given that, the following code should compile IMHO (the EDG front-end > thinks so, too): > > ----------------------snip here------------------- > struct A > { > typedef void (*pfun)(); > > template static void bar() {} > }; > > template static void foo() {} > > template void A::bar< &foo<0> >(); > ----------------------snip here------------------- > > Alas, each gcc version since 2.95.x rejects the code with a message similar to > > bug.cc:10: `&foo<0>' is not a valid template argument > bug.cc:10: template-id `bar<(&foo<0>)>' for `void A::bar()' does not match any > template declaration EDG is wrong (surprisingly), and gcc is right: foo has internal linkage, and its address is therefore not a valid one for a template parameter. Once you remove the static from the declaration of foo, it compiles cleanly. It's just too bad that here the error message is not really good: GCC2.96: tmp/g> gcc -c x.cc x.cc:10: `&foo<0>' is not a valid template argument x.cc:10: template-id `bar<(&foo<0>)>' for `A::bar ()' does not match any template declaration PRESENT CVS: tmp/g> ../build-gcc/gcc-install/bin/gcc -c x.cc x.cc:10: error: template-id `bar<(&foo<0>)>' for `void A::bar()' does not match any template declaration It's particularly bad since gcc-CVS knows about this. If I take your example from above, and make it invalid by adding "static" to the declaration of "int i", then I get: x.cc:3: error: address of non-extern `i' cannot be used as template argument x.cc:3: error: template-id `foo<(&i)>' for `void foo()' does not match any template declaration Regards Wolfgang ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ticam.utexas.edu www: http://www.ticam.utexas.edu/~bangerth/