Consider the following code #include <algorithm> int main() { int a[10] = {0} ; struct T { void operator()(int) const { } }; std::for_each(a, a + 10, T()); } GCC-3.3.x used to say: t.C: In function `int main()': t.C:11: error: type `main()::T' composed from a local class is not a valid template-argument t.C:11: error: trying to instantiate `template<class _InputIter, class _Function> _Function std::for_each(_InputIter, _InputIter, _Function)' t.C:11: error: no matching function for call to `for_each(int[10], int*, main()::T)' Now, GCC-3.4.x says: t.C: In function `int main()': t.C:11: error: no matching function for call to `for_each(int[10], int*, main()\ ::T)' Notice that the most informative part of the diagnostic had been dropped, leaving only the most cryptic, uninformative one.
This is related to the substitution-failure-is-not-an-error thingy: we realize that a local class cannot be matched against a template argument, so we drop the template function std::for_each from the overload list -- and end up with an empty list, thus the error message. We probably need to special-case the overload resolution process to handle this case: when we end up with an empty overload list but there is a function that would match were it not for a local class, we should report so. Whether this kind of special-casing is desirable is another matter. Reduced testcase is this: ------------------- template <typename T> void foo() {}; int main () { struct S {}; foo<S> (); } ----------------- g/x> /home/bangerth/bin/gcc-3.3.4-pre/bin/c++ -c x.cc x.cc: In function `int main()': x.cc:5: error: template-argument `main()::S' uses local type `main()::S' x.cc:5: error: no matching function for call to `foo()' g/x> g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc x.cc: In function `int main()': x.cc:5: error: no matching function for call to `foo()' g/x> g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc x.cc: In function `int main()': x.cc:5: error: no matching function for call to `foo()' W.
Subject: Re: [3.4/4.0 regression] local classes as template argument "bangerth at dealii dot org" <gcc-bugzilla@gcc.gnu.org> writes: | This is related to the substitution-failure-is-not-an-error thingy: we | realize that a local class cannot be matched against a template argument, | so we drop the template function std::for_each from the overload list -- | and end up with an empty list, thus the error message. Indeed, the whole problem is in pt.c:check_instantiated_args(). It contains code for proper diagnostic tree nt = no_linkage_check (t, /*relaxed_p=*/false); if (nt) { if (!(complain & tf_error)) /*OK*/; else if (TYPE_ANONYMOUS_P (nt)) error ("`%T' uses anonymous type", t); else error ("`%T' uses local type `%T'", t, nt); result = true; } But the diagnostic is not emitted because tf_error is not set in complain. | We probably need to special-case the overload resolution process to handle | this case: when we end up with an empty overload list but there is a | function that would match were it not for a local class, we should report | so. Whether this kind of special-casing is desirable is another matter. I would say it is a Suboptimal implementation of SFINAE. In the phase where the overload-set is constructed, indeed SFINAE is applied -- if something is invalid, just bail out without spitting any diagnostic. However, once the overload-set is constructed, any error is an error. Notice that Comeau online really does give an informative diagnostic "ComeauTest.c", line 11: error: a template argument may not reference a local type std::for_each(a, a + 10, T()); ^ -- Gaby
I agree that an error would be nice. I just meant to point out the reason why we don't get one. W.
Subject: Re: [3.4/4.0 regression] local classes as template argument "bangerth at dealii dot org" <gcc-bugzilla@gcc.gnu.org> writes: | I agree that an error would be nice. I just meant to point out the reason | why we don't get one. I did not mean to say you're wrong. I'm sorry if my rant gave you the impression that I was saying you're wrong. GCC is giving me headaches these days :-/ -- Gaby
Will not be fixed in GCC 3.4.x; postponed until GCC 4.0, at least.
The bug here is that we are checking complain at all. SFINAE does not say that when given a set of overload candidates you perform type deduction and then discard any candiates for which an any error occurs. Instead, you perform type deduction and discard any candidates for which type deduction fails, which is a defined term in [temp.deduct]. Type deduction fails only under precise circumstances; using a local class as a template argument is not a case in which type deduction fails. It looks like people have been throwing around "complain & tf_error" checks too freely in pt.c. The question is then what happens after type deduction succeeds. Should we emit an error before doing overload resolution, or only if the invalid function is selected from the overload set? DR 415 is a related issue and the proposed resolution suggests that errors about invalid substitutions may be issued before overload resolution.
Subject: Re: [3.4/4.0 regression] local classes as template argument "mmitchel at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: | The bug here is that we are checking complain at all. | | SFINAE does not say that when given a set of overload candidates you perform | type deduction and then discard any candiates for which an any error occurs. | Instead, you perform type deduction and discard any candidates for which type | deduction fails, which is a defined term in [temp.deduct]. Type | deduction fails only under precise circumstances; using a local | class as a template argument is not a case in which type deduction fails. Absolutely. | It looks like people have been throwing around "complain & tf_error" | checks too freely in pt.c. Amen. | The question is then what happens after type deduction succeeds. | Should we emit an error before doing overload resolution, or only if | the invalid function is selected from the overload set? DR 415 is a | related issue and the proposed resolution suggests that errors about | invalid substitutions may be issued before overload resolution. My inclination is to emit the error only if the invalid function is selected from the overload set. I can see where DR 415 is heading, and I think its general concern will no doubt be discussed in Redmond or following as it affects large part of C++ evolution. In the mean time, I would recommend we emit the error only if the invalid function is selected. -- Gaby
As in the discussion of DR 415, it's not feasible to postpone all error messages until overload resolution has succeeded. The example in DR 415 is that you might need to instantiate a class type to do type deduction. If the class has an invalid member upon instantiation, it makes sense to complain then, not later when the function that required that instantiation is selected. The language (which John Spicer is trying to clarify) leads to another complication. [temp.over] says: template argument deduction (_temp.deduct_) and checking of any explicit template arguments (_temp.arg_) are per- formed for each function template to find the template argument values (if any) that can be used with that function template to instantiate a function template specialization that can be invoked with the call arguments. For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to instantiate a single function template specialization which is added to the candidate functions set to be used in overload resolution. If, for a given function template, argument deduction fails, no such function is added to the set of candidate functions for that template. This section does not clearly specify what happens if argument deduction succeeds, but the checking of explict template arguments (as per [temp.arg]) fails. Consider: template <typename T> void f(T *); void g() { struct S; S* p; f (p); // #1 f<S> (p); // #2 } If we treated deduction and explicit arguments differently, then we would put the template in the overload set at #1 (deduction succeeds) but not at #2 (checking of explicit arguments fails). That's odd. John (and I) think that "instantiate" is the wrong term in the passage quoted above, in the sense that this should not be a point-of-instantiation, I do think, however, that the compiler must generate a declaration of the function template, after instantiation, for use during overload resolution. That is the natural time to issue errors about the function. Otherwise, you must queue a possibly arbitrary error or set of errors to issue later, iff the template is instantiated. It's not reasonable to ask that of the implementation. For all these reasons, I intend to fix this by issuing an error message before overload resolution.
Subject: Re: [3.4/4.0 regression] local classes as template argument "mmitchel at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes: [...] | Consider: | | template <typename T> | void f(T *); | | void g() { | struct S; | S* p; | f (p); // #1 | f<S> (p); // #2 | } | | If we treated deduction and explicit arguments differently, then we would put | the template in the overload set at #1 (deduction succeeds) but not at #2 | (checking of explicit arguments fails). That's odd. The difference between deduction and explicit arguments are already deep; there is no thing odd about it. They are just not the same thing and they don't work the same way. Explicit arguments in general constructs different overload sets than deduction. Furthermore, the former allows implicit conversion and the later does not. Consider template<class> struct X { } template<class T> f(T*); template<class T> f(X<T>*); void g() { struct S : X<int> { }; S* p; f(p); f<S>(p); f<int>(p); }; | John (and I) think that "instantiate" is the wrong term in the passage quoted | above, in the sense that this should not be a point-of-instantiation, I do | think, however, that the compiler must generate a declaration of the function | template, after instantiation, for use during overload resolution. That is the | natural time to issue errors about the function. Otherwise, you must queue a | possibly arbitrary error or set of errors to issue later, iff the template is | instantiated. It's not reasonable to ask that of the implementation. | | For all these reasons, I intend to fix this by issuing an error message before | overload resolution. I understand your point of view, but I don't think I agree with it. I suppose we'll have plenty time to review this point in Redmond or later. -- Gaby
Subject: Bug 17413 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-12-22 03:34:59 Modified files: gcc/cp : ChangeLog call.c decl.c parser.c tree.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/ext: packed8.C gcc/testsuite/g++.dg/template: crash31.C crash30.C Log message: PR c++/18378 * call.c (convert_like_real): Do not permit the use of a copy constructor to copy a packed field. PR c++/17413 * decl.c (grokdeclarator): Return error_mark_node, not void_type_node, to indicate errors. * parser.c (cp_parser_template_parameter_list): Robustify. (cp_parser_template_parameter): Likewise. PR c++/19034 * tree.c (cp_tree_equal): Handle OVERLOAD. PR c++/18378 * g++.dg/ext/packed8.C: New test. PR c++/13268 * g++.dg/template/crash31.C: New test. PR c++/19034 * g++.dg/template/crash30.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4550&r2=1.4551 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&r1=1.523&r2=1.524 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1345&r2=1.1346 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&r1=1.296&r2=1.297 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&r1=1.420&r2=1.421 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed8.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/crash31.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/crash30.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4796&r2=1.4797
The patch is the previous comment does not actually apply to this PR.
The code in the PR is clearly invalid, as it explicitly uses a local class as an explicit template arugment. However, the broader question is how to perform overload resolution when argument deduction has deduced a local class as a template argument. The pluasible choices are one of (a) that function being excluded from the set of overloaded function candidates, (b) an error when deduction is being performed, or (c) an error only if that function is selected. GCC presently implements (a), but that means that the set of overloaded candidates considered changes depending merely on whether or not one of the function arguments happens to be a local class. That seems undesirable. Furthermore, it's a clear violation of the standard, which lists clearly the cases in which SFINAE applies; using a local class as an argument is not one of them. Here is a test case that distinguishes (a) from the other other choices: struct A {}; A* a; void f(A*); template <typename T> void f(T*); void g() { f(a); // Calls the non-template function. struct B : public A {}; B* b = 0; f(b); // Overload resolution will select f<B*>(B*) if the template // candidate is included in the overload set. As a local type // cannot be a template argument, that will result in an error // message. If the template candidate is not included in the // overload set, then the non-template function will be // accepted. } G++ presently accepts this code. The previous debate has centered on whether (b) or (c) is a better choice. However, I do not think there is an actual difference between (b) or (c). If template argument deduction succeeds, overload resolution is guaranteed to find that function to be a viable function. So, the only question is whether it will be the best. It will be better than any non-template function, because non-template functions cannot possibly involve local classes as argument types. And any template function which was more specialized would also have to involve the local class in its argument types. For example, I do not think there is any other overload of "f" that can be added above that would be selected over the template version, but which would not also involve a local class type.
Subject: Bug 17413 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-12-23 19:54:09 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog pt.c gcc/testsuite/g++.dg/template: crash19.C Added files: gcc/testsuite/g++.dg/template: local4.C Log message: PR c++/17413 * pt.c (check_instantiated_args): Remove bogus SFINAE code. PR c++/17413 * g++.dg/template/local4.C: New test. * g++.dg/template/crash19.C: Add dg-error marker. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4808&r2=1.4809 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4557&r2=1.4558 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.961&r2=1.962 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/local4.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/crash19.C.diff?cvsroot=gcc&r1=1.2&r2=1.3
Fixed in G++ 4.0.
Subject: Re: [3.4/4.0 regression] local classes as template argument I agree with your analysis. Thanks for the time you put into this. I record it for future references in EWG. -- Gaby
Subject: Bug 17413 CVSROOT: /cvs/gcc Module name: gcc Changes by: reichelt@gcc.gnu.org 2005-02-02 21:58:46 Modified files: gcc/cp : ChangeLog pt.c gcc/testsuite : ChangeLog gcc/testsuite/g++.dg/template: local4.C Log message: PR c++/17413 * pt.c (check_instantiated_args): Improve error message. Fix logic when to print its second part. PR c++/17413 * g++.dg/template/local4.C: Tweak. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4612&r2=1.4613 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.971&r2=1.972 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4984&r2=1.4985 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/local4.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
Subject: [3.4 regression] local classes as template argument Hi Mark, Consider this code: struct Attribute { }; template <class T> void fun (const Attribute &attr, const T &value); extern void fun (int attr, int value); enum { anon = 666 }; void test(int foo) { fun (foo, anon); } I believe this is valid C++. Template argument deduction will fail when it compares the type of the *first* parameter of fun(), since no value of T can be found that will make the first parameter match. Unfortunately, this code produces an error: /Users/geoffk/Desktop/test.cpp:8: error: '<anonymous enum>' is/uses anonymous type /Users/geoffk/Desktop/test.cpp:8: error: trying to instantiate 'template<class T> void fun(const Attribute&, const T&)' I think the problem is this code in type_unification_real: if (strict == DEDUCE_EXACT) { if (same_type_p (parm, type)) continue; } else /* It might work; we shouldn't check now, because we might get into infinite recursion. Overload resolution will handle it. */ continue; I will see what happens if I just try to say '== DEDUCE_EXACT || strict == DEDUCE_CALL'. I'm not hopeful, though...
Created attachment 8986 [details] smime.p7s
Subject: Re: [3.4 regression] local classes as template argument Geoffrey Keating wrote: > Hi Mark, > > Consider this code: > > struct Attribute { }; > template <class T> void fun (const Attribute &attr, const T &value); > extern void fun (int attr, int value); > enum { anon = 666 }; > > void test(int foo) > { fun (foo, anon); } > > I believe this is valid C++. Template argument deduction will fail > when it compares the type of the *first* parameter of fun(), since no > value of T can be found that will make the first parameter match. As you've discovered, we don't perform template argument deduction on arguments that do not involve template types. I agree that there's nothing in the standard to support that behavior. However, there are a lot of DRs in this area, and we should check the behavior of other compilers before making any changes here. Those checks should be done without using anonymous enums, since there's additional controversy around that particular issue; instead, some way to isolate what set of template functions can be deduced is required. I don't remember the origin of the comment in the code that refers to infinite recursion. I don't think adding DEDUCE_CALL to the condition makes sense, though; either we should always do the comparsion, or only when DEDUCE_EXACT. Furthermore, your change is not correct, in that deduction permits non-exact matches for calls; see [temp.deduct.call].
Subject: Re: [3.4 regression] local classes as template argument On 29/05/2005, at 10:18 AM, mark at codesourcery dot com wrote: > > ------- Additional Comments From mark at codesourcery dot com > 2005-05-29 17:18 ------- > Subject: Re: [3.4 regression] local classes as template argument > > Geoffrey Keating wrote: > >> Hi Mark, >> >> Consider this code: >> >> struct Attribute { }; >> template <class T> void fun (const Attribute &attr, const T &value); >> extern void fun (int attr, int value); >> enum { anon = 666 }; >> >> void test(int foo) >> { fun (foo, anon); } >> >> I believe this is valid C++. Template argument deduction will fail >> when it compares the type of the *first* parameter of fun(), since no >> value of T can be found that will make the first parameter match. >> > > As you've discovered, we don't perform template argument deduction on > arguments that do not involve template types. I agree that there's > nothing in the standard to support that behavior. However, there > are a > lot of DRs in this area, and we should check the behavior of other > compilers before making any changes here. Those checks should be done > without using anonymous enums, since there's additional controversy > around that particular issue; instead, some way to isolate what set of > template functions can be deduced is required. I don't think there's any way to separate this from anonymous enums. The only reason we can tell that template argument deduction is being performed is because of the interpretation we've chosen for when error messages are emitted with anonymous enums. If there was no error message being emitted, it wouldn't matter; even if a template function was added to the list of candidates, it would be considered non-viable by function overloading. I do think that this code ought to be valid C++. The original example had 'fun' actually being 'operator =='; it seems unreasonable that if someone defines a template 'operator ==' you suddenly can't compare integers and anonymous enumeration constants any more. > I don't remember the origin of the comment in the code that refers to > infinite recursion. I don't think adding DEDUCE_CALL to the condition > makes sense, though; either we should always do the comparsion, or > only > when DEDUCE_EXACT. Furthermore, your change is not correct, in that > deduction permits non-exact matches for calls; see [temp.deduct.call]. Yes, I noticed that pretty quickly; the patch I'm testing now looks like: --- pt.c 27 May 2005 23:17:17 -0000 1.1000 +++ pt.c 29 May 2005 21:17:18 -0000 @@ -9344,17 +9344,12 @@ type_unification_real (tree tparms, else type = arg; - if (strict == DEDUCE_EXACT) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ + if (same_type_p (parm, type)) continue; - + if (strict != DEDUCE_EXACT + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + continue; + return 1; } A previous test of a similar patch but with only DEDUCE_CALL being changed didn't trigger infinite recursion anywhere in the C++ testsuite. I think the only way you can get recursion is if can_convert_arg tries to instantiate a template to make a conversion and that feeds back into this code, which I am not sure is possible--- what kinds of conversion functions are template functions but have non-dependent arguments?
Created attachment 8996 [details] smime.p7s
Subject: Bug 17413 CVSROOT: /cvs/gcc Module name: gcc Changes by: geoffk@gcc.gnu.org 2005-06-17 22:13:36 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog pt.c Added files: gcc/testsuite/g++.dg/template: local5.C Log message: 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * pt.c (type_unification_real): Apply template type deduction even to procedure parameters that are not dependent on a template parameter. Index: testsuite/ChangeLog 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * g++.dg/template/local5.C: New. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5649&r2=1.5650 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/local5.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4794&r2=1.4795 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.1007&r2=1.1008
Subject: Bug 17413 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: giovannibajo@gcc.gnu.org 2005-07-28 10:22:23 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog call.c parser.c pt.c gcc/testsuite/g++.dg/parse: crash11.C crash13.C Added files: gcc/testsuite/g++.dg/ext: packed8.C gcc/testsuite/g++.dg/parse: error18.C gcc/testsuite/g++.dg/template: crash25.C local5.C typedef2.C Log message: Backport: 2004-09-16 Mark Mitchell <mark@codesourcery.com> PR c++/16002 * parser.c (cp_parser_simple_declaration): Commit to tentative parses after seeing a decl-specifier. (cp_parser_simple_declaration): Eliminate spurious message. (cp_parser_init_declarator): Adjust error message. 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * pt.c (type_unification_real): Apply template type deduction even to procedure parameters that are not dependent on a template parameter. 2004-11-02 Mark Mitchell <mark@codesourcery.com> PR c++/18124 * parser.c (cp_parser_type_parameter): Robustify. PR c++/18155 * parser.c (cp_parser_single_declaration): Disallow template typedefs. (cp_parser_typedef_p): New function. 2004-12-21 Mark Mitchell <mark@codesourcery.com> PR c++/18378 * call.c (convert_like_real): Do not permit the use of a copy constructor to copy a packed field. Backport: 2004-09-16 Mark Mitchell <mark@codesourcery.com> PR c++/16002 * g++.dg/parse/error18.C: New test. * g++.dg/parse/crash11.C: Adjust error markers. 2005-06-17 Geoffrey Keating <geoffk@apple.com> PR c++/17413 * g++.dg/template/local5.C: New. 2004-11-02 Mark Mitchell <mark@codesourcery.com> PR c++/18124 * g++.dg/template/crash25.C: New test. PR c++/18155 * g++.dg/template/typedef2.C: New test. * g++.dg/parse/crash13.C: Adjust error markers. 2004-12-21 Mark Mitchell <mark@codesourcery.com> PR c++/18378 * g++.dg/ext/packed8.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.411&r2=1.3389.2.412 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.228&r2=1.3892.2.229 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.452.2.26&r2=1.452.2.27 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.157.2.57&r2=1.157.2.58 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.816.2.56&r2=1.816.2.57 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed8.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.42.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/error18.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1.12.3&r2=1.1.12.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash11.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.2&r2=1.2.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash13.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.14.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/crash25.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.38.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/local5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.14.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/typedef2.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.38.1
Fixed also for GCC 3.4.5.