15542 – [3.4/4.0 Regression] operator & and template definitions (original) (raw)

Description Jeff Downs 2004-05-19 15:51:40 UTC

Attached below is a simple C++ source file to demonstrate what appears to be a name lookupor template generation bug in the new parser scheme. It has to do with directly supplying the result of the application of the operator '&' to a templated function, from within a template definition, when operator '&' is overloaded in a templated class.

A call like this succeeds when the object whose & operator is invoked depends on a templated parameter of the enclosing template definition. It fails when the the object whose & operator is invoked is independent of the enclosing template parameters. I am aware of the 3.4.0 changes regarding template definition dependence and such, but I don't think any of that should apply here; it should be able to find and generate the appropriate template instantiation.

The comments inline with the code explain further; the behavior seems very inconsistent as exhibited by the examples. I believe the code to be valid. At the very least I expect that the compiler would treat all provided scenarios equally.

There is some preprocessor guarded code in the test code that, when included, causes the entire thing to compile, seemingly by forceing the required template instantiation.

Cmd Line for basic issue: g++ -c file.cpp

Cmd Line to see external template generation causing compilation to succeed: g++ -DTEST_TWO -c file.cpp

Errors produced during compilation using first cmd line, above: file.cpp: In function void templateTest(T&)': file.cpp:56: error: no matching function for call to templatedFunc(Opr&)' file.cpp:57: error: cannot convert Opr<const char>*' to const char' for argument 1' to void templatedFunc(T*) [with T = const char]'

This all worked in gcc 3.3.3.

gcc details: Reading specs from /usr/local/lib/gcc/sparc-sun-solaris2.8/3.4.0/specs Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls Thread model: posix gcc version 3.4.0

Comment 2 Drea Pinski 2004-05-19 15:59:28 UTC

Confirmed, this looks like the case where gcc is not looking up non-dependent functions at parse time right.

Comment 3 Wolfgang Bangerth 2004-05-19 17:29:58 UTC

Indeed, here is a smaller example:

struct S { const char** operator & (); }; template struct S_T { const char** operator & (); }; template void foo(T **) {} template void templateTest() { S s; foo(&s);
S_T s_t; foo(&s_t); }

g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc x.cc: In function void templateTest()': x.cc:16: error: no matching function for call to foo(S_T*&)'

The call foo(&s) goes through, but the call to foo(&s_t) doesn't. This may indicate that gcc thinks that it is somehow dependent, even though it is not (all template arguments are actually fixed).

W.

Comment 4 Jeff Downs 2004-05-19 18:07:47 UTC

Indeed. I also noticed that I only observed this behavior with the templated class overriding operator &.

What really baffled me (and relieved, at the same time since it allowed me to work-around) is that doing a static_cast (in the original example) forced it to find the template. Similarly, a case I didn't include was naming a const char ** local and assigning it the result of the & operator. This also works, probably for the same internal reasons as static_cast does.

Comment 5 Mark Mitchell 2004-05-22 18:19:32 UTC

Working on a fix.

Comment 8 Mark Mitchell 2004-05-22 19:30:31 UTC

Fixed in GCC 3.4.1.