This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: c++/9298: [3.4 regression] [new parser] ICE with function-pointer-typetemplate args
- From: Wolfgang Bangerth <bangerth at ticam dot utexas dot edu>
- To: nobody at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 15 Jan 2003 21:36:03 -0000
- Subject: Re: c++/9298: [3.4 regression] [new parser] ICE with function-pointer-typetemplate args
- Reply-to: Wolfgang Bangerth <bangerth at ticam dot utexas dot edu>
The following reply was made to PR c++/9298; it has been noted by GNATS.
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
Cc: gcc-bugs@gcc.gnu.org, <gcc-gnats@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 <int*> 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 <pfun> static void bar() {}
> };
>
> template <int> 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/