According to the C++ standard, this should work: walkert@zaphod:walkert$ cat test.C template<class T> struct A { struct B { }; }; class C { template<class T> friend struct A<T>::B; }; $ g++ -o test.o -c test.C test.C:6: warning: `typename A<T>::B' is implicitly a typename test.C:6: warning: implicit typename is deprecated, please see the documentation for details test.C:6: typename type `typename A<T>::B' declared `friend'
Created attachment 102486 [details] Patch that fixes the bug This patch fixes the problem; I haven't tested it very thoroughly yet, but I'm confident it's the right fix, so I'm going ahead and posting it. The YYMALLOC change may be unnecessary for RHEL3's bison; I'm using a newer version that perhaps introduces YYMALLOC in such a way that the poisoned token malloc ends up being used.
For the record, http://gcc.gnu.org/PR13495 appears to be related with this problem. (it seems to have originally been reported as the same problem, but now it's marked for GCC 3.4, which is fixed, but the bug is still open, so I'm very confused :-)
I've run the testsuite. The patch doesn't completely fix the problem. g++.old-deja/g++.pt/crash43.C has a bug (requiring an error for well-formed code exactly as posted above), but also for another similar friend template declaration within the template class containing the friend member. This one requires delayed template resolution, so it means a similar patch elsewhere is necessary. I'm going to fix that, as well as the testcase.
Created attachment 102528 [details] Patch that adjust the testsuite I've been beating my head against the wall trying to get crash43.C to work correctly, but I'm thinking more and more that it's unfixable in 3.2/3.3. Basically, the failing test (that I've changed to bogus error in the attached patch) references the template currently being defined with different arguments, such that we don't use the original template defition, but rather create a partial specialization that we fail to instantiate because the original template is still being defined. So, when we look up X in it, we get nothing, so we end up defining a TYPENAME_TYPE for S<U>::X, instead of finding a record type. I don't think it should actually look up X within the template-dependent, but that's just the broken (and unfixable) name lookup implementation before the parser rewrite in 3.4. I'm leaving it alone, since the problem originally reported is fixed and the remaining one is probably unfixable without extensive rewrites.
An errata has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2004-442.html