Bug 14534

Summary: Unrecognizing static function as a template parameter when its return value is also templated
Product: gcc Reporter: SATo <sato>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, reichelt
Priority: P2 Keywords: monitored, rejects-valid
Version: 3.3.1   
Target Milestone: 3.4.3   
Host: Target:
Build: Known to work: 3.4.3 4.0.0
Known to fail: 2.95.3 3.2.3 3.3.3 3.4.0 Last reconfirmed: 2004-09-09 03:57:03

Description SATo 2004-03-11 13:08:14 UTC
avr-gcc.EXE (GCC) 3.3.1

Reading specs from C:\WinAVR\bin\..\lib\gcc-lib\avr\3.3.1\specs
Configured with: ../configure --prefix=/e/avrdev/install --target=avr --enable-
languages=c,c++ --disable-nls --enable-win32-registry=WinAVR
Thread model: single
gcc version 3.3.1

mingw32-gcc.EXE (GCC) 3.2 (mingw special 20020817-1)

Reading specs from c:/mingw/bin/../lib/gcc-lib/mingw32/3.2/specs
Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --
host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --
enable-languages=f77,c++,objc,ada --disable-win32-registry --disable-shared
Thread model: win32
gcc version 3.2 (mingw special 20020817-1)

> avr-gcc test.cpp
test.cpp:10: error: invalid use of undefined type `class Boo'
test.cpp:6: error: forward declaration of `class Boo'
test.cpp:10: error: template argument 2 is invalid
test.cpp:10: error: ISO C++ forbids declaration of `far_type' with no type

test.cpp: -------------------------

template <class Val, Val func()>
class Far {};

class Boo
{
public:
	static int some();

	typedef Far<int, some> far_type; // error
};

int main()
{
}
----------------------------------

BUT this file will be compiled successfully

test.cpp: -------------------------

template <class Val, Val func()>
class Far {};

class Boo
{
public:
	static int some();

	typedef Far<int, Boo::some> far_type; // ok (explicit scope specifier)
};

int main()
{
}
----------------------------------
Comment 1 Andrew Pinski 2004-03-11 15:58:35 UTC
Confirmed.
Comment 2 Wolfgang Bangerth 2004-03-11 16:05:33 UTC
Confirmed indeed. This never worked, and still doesn't. 
 
One rather confusing thing: for this code snippet 
------------- 
template <int (*)()> class Far {}; 
struct Boo { 
        static int some(); 
        typedef Far<some> far_type; 
}; 
------------- 
we get  
g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc 
x.cc:4: error: `static int Boo::some()' cannot appear in a constant-expression 
x.cc:4: error: template argument 1 is invalid 
x.cc:4: error: ISO C++ forbids declaration of `far_type' with no type 
(which I find particularly confusing because the error message refers to 
Boo::some -- which I didn't write this way, and as the submitter correctly 
noticed: had I written it in this way, the compiler had accepted it. 
 
However, it gets worse: if I don't use the automatic decay to a function 
pointer and write the address-of explicitly, i.e. 
------------------ 
template <int (*)()> class Far {}; 
struct Boo { 
        static int some(); 
        typedef Far<&some> far_type; 
}; 
------------------ 
then the error message changes to the even more unreadable 
g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc 
x.cc:4: error: missing `>' to terminate the template argument list 
x.cc:4: error: template argument 1 is invalid 
x.cc:4: error: ISO C++ forbids declaration of `some' with no type 
x.cc:4: error: expected `;' before '>' token 
 
Which is totally bogus. 
 
W. 
Comment 3 Volker Reichelt 2004-09-28 11:09:02 UTC
Fixed by Mark's patch for PR 17585:
http://gcc.gnu.org/ml/gcc-cvs/2004-09/msg01289.html