The following reduced program produces an ICE when compiled with -std=c++0x -O2 -g. ===================================================== struct X { void func() {} }; template<typename T, typename U = decltype(&T::func)> void b(T) {} int main() { b(X()); /* line 9 */ X().func(); return 0; } ===================================================== 1.cc: In function 'void b(T) [with T = X, U = void (X::*)()]': 1.cc:9:9: internal compiler error: in build_ptrmem_type, at cp/decl.c:7202 And the following variation produces a different ICE. =================================================== struct X { void func() {} }; template<typename T, typename = decltype(&T::func)> struct A {}; template<typename T> void b(T) {} int main() { b(A<X>()); X().func(); return 0; } =================================================== Internal compiler error: Error reporting routines re-entered.
This one happens *only* with -O2 and -g, should be recategorized as debug and/or optimization? Thanks for any help triaging it...
To be more specific, it happens only with -O -fipa-sra -finline-small-functions -g
I suspect this is the same bug as 42225.
Ok, thanks, I'll track that one instead...
FYI, I have checked, however, that the last posted patch for 42225 http://gcc.gnu.org/ml/gcc-patches/2009-12/msg00755.html doesn't fix this one at once.
Subject: Re: [c++0x] ICE with pointer-to-member-function decltype argument in template function > FYI, I have checked, however, that the last posted patch for 42225 > doesn't fix this one at once. To be honest, I am not sure to understand how these two bugs would be linked, but I haven't looked at this one in depth yet.
You're right, they probably aren't; this doesn't involve typedefs.
The problem here is that after we're done parsing the translation unit, we do IPA optimizations, and IPA decides to change the type of X::func from a METHOD_TYPE to a FUNCTION_TYPE. Then later we're emitting debug information about b<X>, and ask the compiler for that name. So we try to substitute X into decltype(&T::func) to see if the argument we have is the same as the default argument. But at this point T::func resolves to a function with FUNCTION_TYPE, whereas we were expecting one with METHOD_TYPE, and boom. I suppose we can't do any tsubsting after IPA runs.
It does seem kind of dodgy that IPA is modifying the types of functions directly, though... Here's a non-C++0x testcase: struct X { void func() {} }; template<typename T, void (X::*P)() = &T::func> void b(T) {} int main() { b(X()); /* line 9 */ X().func(); return 0; } So, this could be fixed by 1) Not relying on function types being sensible once IPA begins. 1a) Generating names for debug info earlier 1b) Giving up on trying not to print default args in names for debug info 2) Keeping function types sensible.
I'd like to see 1a) for obvious reasons (we'll need that for proper LTO debuginfo support). But 2) is also sensible.
The ICE happens within count_non_default_template_args which (as far as I understand it) somehow re-creates each template parameter to see whether it is the default one (and increments a counter if it is). I am not exactly sure what the option 1b means but we get an ICE even when the template does not have default parameters: struct X { void func() {} void f2() {} }; template<typename T, void (X::*P)() = &T::func> void b(T) {} int main() { b<X, &X::f2>(X()); /* line 9 */ X().func(); return 0; } I also do not quite understand what the option 2 means. If we remove the this pointer, the method is no longer a method and thus is sensibly turned into a function. Gcc does this IPA-CP since 4.4 and in IPA-SRA in trunk, primarily because of some ICEs that happen if we don't (Honza would know more but I would suspect they were also related to debug info). (1a sounds nice. However, since my knowledge and experience with debug info (not to mention C++) code is rather limited, I would like to discuss what needs to be done in much more detail before attempting it myself. But it certainly looks interesting.)
It basically seems to me that the modifications made by ipa_modify_formal_parameters are incompatible with proper debugging information; the method is still a method as far as the language is concerned even if the actual code generated optimizes away the this pointer. I think it would be better to represent those sorts of modifications via cloning rather than by modifying the primary decls.
I agree. Modifying existing DECLs doesn't sound like a good thing to do.
Unfortunately, creating clones within an intraprocedural pass (and IPA-SRA is an intraprocedural pass from the pass manager point of view) and continuing optimizing them as the original procedure would currently does not work. Allowing that would require some substantial changes to the pass manager. I originally wanted to clone and did try various hacks but all of them were exceptionally ugly and eventually I gave up. It is of course doable but not particularly easy, if that was the intent.
In general requiring all changes to clone function body is bit expensive since it involves copying of whole function (ipa-sra is one of more busy passes). It is also somewhat difficult to implement with current PM organization: early IPA passes are allowed to produce new functions and process them via cgraph_add_new_function but in this case this won't work, since the function is half way optimized (i.e. already in SSA form). This will require either splitting optimizations into early optimization from in-to SSA as separate pass so they are re-entrant (that would be useful to run them at LTO stage too) and/or teaching passmanager to be more flexible and start from given pass. But this is both bit too invasiave for stage 4. Can't we just fix this in dwarf2out to give out debug info here or output templates early? Honza
IMHO we should go into-SSA for all functions before even starting with early optimizations (that also avoids the funny SSA form mismatch during early inlining of cycles). Of course that's for 4.6 as well. Another possibility for 4.5 is to remove the early IPA-SRA pass again or make it an annotation-only pass.
Well, since we want to make more similar changes in foreseeable future, I would prefer to see ipa-sra enabled in 4.5 and problems fixed. It is excercising quite new type of transformations. In general I am not sure plan of doing all datastructure/function call conventions changes via clonning is coolest idea. These transforms tends to be quite busy so we would need to do a lot of copying. Usual top-down inliner should not look into future of topological order anyway. While current implementation of incremental inlining can theoretically bring in nonoptimized bodies too, I am not sure it is good idea.
Subject: Re: [4.5 Regression] ICE with pointer-to-member-function argument in template function On 01/10/2010 06:42 PM, hubicka at gcc dot gnu dot org wrote: > In general I am not sure plan of doing all > datastructure/function call conventions changes via cloning is coolest idea. Well, just pretending that a particular parameter never existed isn't acceptable from a debugging standpoint; I think we need to have a separate modified decl which points back to the original unmodified decl with DECL_ABSTRACT_ORIGIN. Beyond that, it might be possible to avoid much copying by just moving the function body over from the original decl to the modified one. Jason
I wonder why the C++ frontend emits overload resolution errors from emitting debug information like seen in the duplicate PR42797.
*** Bug 42797 has been marked as a duplicate of this bug. ***
42797 doesn't seem like a duplicate; it's another issue with count_non_default_template_args, but the issue there is that we are triggering instantiation when we shouldn't. But I'm not sure yet why -fno-ipa-sra makes a difference for that test.
(In reply to comment #18) > Subject: Re: [4.5 Regression] ICE with pointer-to-member-function > argument in template function > > On 01/10/2010 06:42 PM, hubicka at gcc dot gnu dot org wrote: > > In general I am not sure plan of doing all > > datastructure/function call conventions changes via cloning is coolest idea. > > Well, just pretending that a particular parameter never existed isn't > acceptable from a debugging standpoint; I think we need to have a > separate modified decl which points back to the original unmodified decl > with DECL_ABSTRACT_ORIGIN. > > Beyond that, it might be possible to avoid much copying by just moving > the function body over from the original decl to the modified one. That hints at a possible fix? Instead of versioning the function just version the DECL (thus basically perform the DECL creation part of versioning only). It requires fixing up call stmts of course, but that shouldn't be too hard. Martin - can you try this?
Subject: Bug 42336 Author: dodji Date: Fri Jan 29 14:30:41 2010 New Revision: 156351 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156351 Log: Fix PRs c++/42758, c++/42634, c++/42797 ... and mitigate PR c++/42336 gcc/cp/ChangeLog: PR c++/42758 PR c++/42634 PR c++/42336 PR c++/42797 PR c++/42880 * cp-tree.h (NON_DEFAULT_TEMPLATE_ARGS_COUNT, SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT, GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT): New accessor macros. * pt.c (coerce_template_parms, type_unification_real, expand_template_argument_pack, coerce_template_parameter_pack): Set the non default template args count. (current_template_args): Always set non defaulted template args count when compiled with --enable-checking (tsubst_template_args, type_unification_real): Propagate the non defaulted template args count. * error.c (get_non_default_template_args_count): Renamed count_non_default_template_args into this. Don't calculate the non default template argument count anymore. Use the new accessor macros above to get it. (dump_template_argument_list, dump_type, dump_decl, dump_template_parms): Adjust. * parser.c (cp_parser_template_argument_list): Always set defaulted template args count when compiled with --enable-checking. gcc/testsuite/ChangeLog: PR c++/42758 PR c++/42634 PR c++/42336 PR c++/42797 PR c++/42880 * g++.dg/other/crash-5.C: New test. * g++.dg/other/crash-6.C: New test. * g++.dg/other/crash-7.C: New test. * g++.dg/other/crash-8.C: New test. Added: trunk/gcc/testsuite/g++.dg/other/crash-5.C trunk/gcc/testsuite/g++.dg/other/crash-6.C trunk/gcc/testsuite/g++.dg/other/crash-7.C trunk/gcc/testsuite/g++.dg/other/crash-8.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-tree.h trunk/gcc/cp/error.c trunk/gcc/cp/parser.c trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Subject: Re: [4.5 Regression] ICE with pointer-to-member-function argument in template function with -fipa-sra So this commit r156351 won't fix the root cause this issue, but I believe it prevents the compiler from crashing. The generated debugging info will surely still be wrong after this commit, though.
In fact the debug info is currently OK, at least for this testcase, because we generate debug info for the signature of X::func at the end of the definition of X, well before we start optimizing X::func. But here's a C testcase where we lose debug info about a parameter that was optimized away: there are no formal parameters in the DWARF output for f. int i; static int f(int) __attribute ((noinline)); static int f(int x) { return i; } int main() { return f(42); } so, this becomes a wrong-debug regression, and should probably have its priority reduced.
Subject: Bug 42336 Author: hjl Date: Sun Feb 7 04:41:22 2010 New Revision: 156562 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156562 Log: Backport testcases from mainline to 4.4. 2010-02-06 H.J. Lu <hongjiu.lu@intel.com> Backport from mainline: 2010-02-05 Dodji Seketeli <dodji@redhat.com> PR c++/42915 * g++.dg/other/crash-9.C: New test. 2010-02-03 Jason Merrill <jason@redhat.com> PR c++/40138 * g++.dg/ext/builtin11.C: New. 2010-02-03 Richard Guenther <rguenther@suse.de> PR tree-optimization/42944 * gcc.dg/errno-1.c: New testcase. 2010-02-03 Richard Guenther <rguenther@suse.de> PR middle-end/42927 * gcc.c-torture/compile/pr42927.c: New testcase. 2010-01-29 Dodji Seketeli <dodji@redhat.com> PR c++/42758 PR c++/42634 PR c++/42336 PR c++/42797 PR c++/42880 * g++.dg/other/crash-5.C: New test. * g++.dg/other/crash-7.C: New test. * g++.dg/other/crash-8.C: New test. 2010-01-28 Uros Bizjak <ubizjak@gmail.com> PR target/42891 * gcc.target/i386/pr42891.c: New test. 2010-01-28 Richard Guenther <rguenther@suse.de> PR middle-end/42883 * g++.dg/torture/pr42883.C: New testcase. 2010-01-28 Michael Matz <matz@suse.de> * gcc.target/i386/pr42881.c: New test. 2010-01-28 Dodji Seketeli <dodji@redhat.com> PR c++/42713 PR c++/42820 * g++.dg/template/typedef27.C: New test case. * g++.dg/template/typedef28.C: New test case. 2010-01-27 Jakub Jelinek <jakub@redhat.com> PR middle-end/42874 * gcc.dg/vla-22.c: New test. 2010-01-26 Richard Guenther <rguenther@suse.de> PR tree-optimization/42250 * gcc.dg/pr42250.c: New testcase. 2010-01-25 Tobias Burnus <burnus@net-b.de> PR fortran/42858 * gfortran.dg/generic_21.f90: New test. 2010-01-21 Martin Jambor <mjambor@suse.cz> PR tree-optimization/42585 * gcc.dg/tree-ssa/pr42585.c: New test. 2010-01-20 Alexandre Oliva <aoliva@redhat.com> PR debug/42715 * gcc.dg/pr42715.c: New. 2010-01-20 Richard Guenther <rguenther@suse.de> PR tree-optimization/42717 * gcc.c-torture/compile/pr42717.c: New testcase. 2010-01-19 Paul Thomas <pault@gcc.gnu.org> PR fortran/42783 * gfortran.dg/bounds_check_15.f90 : New test. 2010-01-18 Dodji Seketeli <dodji@redhat.com> PR c++/42766 * g++.dg/conversion/op6.C: New test. 2010-01-18 Richard Guenther <rguenther@suse.de> PR tree-optimization/42781 * gfortran.fortran-torture/compile/pr42781.f90: New testcase. 2010-01-17 Richard Guenther <rguenther@suse.de> PR middle-end/42248 * gcc.c-torture/execute/pr42248.c: New testcase. 2010-01-17 Janus Weil <janus@gcc.gnu.org> PR fortran/42677 * gfortran.dg/interface_assignment_5.f90: New test. 2010-01-15 Richard Guenther <rguenther@suse.de> PR middle-end/42739 * g++.dg/torture/pr42739.C: New testcase. 2010-01-14 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/42684 * gfortran.dg/interface_31.f90: New test. 2010-01-14 Martin Jambor <mjambor@suse.cz> PR tree-optimization/42706 * gcc.dg/ipa/pr42706.c: New testcase. 2010-01-14 Martin Jambor <mjambor@suse.cz> PR tree-optimization/42714 * g++.dg/torture/pr42714.C: New test. 2010-01-14 Alexander Monakov <amonakov@ispras.ru> PR rtl-optimization/42388 * gcc.dg/pr42388.c: New. 2010-01-14 Alexander Monakov <amonakov@ispras.ru> PR rtl-optimization/42294 * gfortran.dg/pr42294.f: New. 2010-01-14 Ira Rosen <irar@il.ibm.com> PR tree-optimization/42709 * gcc.dg/vect/pr42709.c: New test. 2010-01-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/42730 * gcc.c-torture/compile/pr42730.c: New testcase. 2010-01-13 Martin Jambor <mjambor@suse.cz> PR tree-optimization/42704 * g++.dg/torture/pr42704.C: New test. 2010-01-13 Martin Jambor <mjambor@suse.cz> PR tree-optimization/42703 * gcc.c-torture/compile/pr42703.c: New test. 2010-01-13 Richard Guenther <rguenther@suse.de> PR tree-optimization/42705 * gcc.c-torture/compile/pr42705.c: New testcase. 2010-01-13 Richard Guenther <rguenther@suse.de> PR middle-end/42716 * gcc.c-torture/compile/pr42716.c: New testcase. 2010-01-12 Joseph Myers <joseph@codesourcery.com> PR c/42708 * gcc.c-torture/compile/pr42708-1.c: New test. 2010-01-09 Alexandre Oliva <aoliva@redhat.com> PR middle-end/42363 * gcc.dg/torture/pr42363.c: New. 2010-01-09 Alexandre Oliva <aoliva@redhat.com> PR debug/42604 PR debug/42395 * gcc.dg/vect/pr42604.c: New. * gcc.dg/vect/pr42395.c: New. 2010-01-09 Richard Guenther <rguenther@suse.de> PR middle-end/42512 * gcc.c-torture/execute/pr42512.c: New testcase. Added: branches/gcc-4_4-branch/gcc/testsuite/g++.dg/conversion/op6.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/conversion/op6.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/ext/builtin11.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/ext/builtin11.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/other/crash-5.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/other/crash-5.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/other/crash-7.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/other/crash-7.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/other/crash-8.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/other/crash-8.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/other/crash-9.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/other/crash-9.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef27.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/template/typedef27.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/template/typedef28.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/template/typedef28.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/torture/pr42704.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/torture/pr42704.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/torture/pr42714.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/torture/pr42714.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/torture/pr42739.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/torture/pr42739.C branches/gcc-4_4-branch/gcc/testsuite/g++.dg/torture/pr42883.C - copied unchanged from r156561, trunk/gcc/testsuite/g++.dg/torture/pr42883.C branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42703.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42703.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42705.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42705.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42708-1.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42708-1.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42716.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42716.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42717.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42717.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42730.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42730.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/compile/pr42927.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/compile/pr42927.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/execute/pr42248.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/execute/pr42248.c branches/gcc-4_4-branch/gcc/testsuite/gcc.c-torture/execute/pr42512.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.c-torture/execute/pr42512.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/errno-1.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/errno-1.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/ipa/pr42706.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/ipa/pr42706.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr42250.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/pr42250.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr42388.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/pr42388.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr42715.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/pr42715.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/torture/pr42363.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/torture/pr42363.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vect/pr42395.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/vect/pr42395.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vect/pr42604.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/vect/pr42604.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vect/pr42709.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/vect/pr42709.c branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/vla-22.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.dg/vla-22.c branches/gcc-4_4-branch/gcc/testsuite/gcc.target/i386/pr42881.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.target/i386/pr42881.c branches/gcc-4_4-branch/gcc/testsuite/gcc.target/i386/pr42891.c - copied unchanged from r156561, trunk/gcc/testsuite/gcc.target/i386/pr42891.c branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/bounds_check_15.f90 - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.dg/bounds_check_15.f90 branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/generic_21.f90 - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.dg/generic_21.f90 branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/interface_31.f90 - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.dg/interface_31.f90 branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/interface_assignment_5.f90 - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.dg/interface_assignment_5.f90 branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/pr42294.f - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.dg/pr42294.f branches/gcc-4_4-branch/gcc/testsuite/gfortran.fortran-torture/compile/pr42781.f90 - copied unchanged from r156561, trunk/gcc/testsuite/gfortran.fortran-torture/compile/pr42781.f90 Modified: branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
(In reply to comment #22) > (In reply to comment #18) > > Well, just pretending that a particular parameter never existed isn't > > acceptable from a debugging standpoint; I think we need to have a > > separate modified decl which points back to the original unmodified decl > > with DECL_ABSTRACT_ORIGIN. > > > > Beyond that, it might be possible to avoid much copying by just moving > > the function body over from the original decl to the modified one. > > That hints at a possible fix? Instead of versioning the function just > version the DECL (thus basically perform the DECL creation part of > versioning only). It requires fixing up call stmts of course, but that > shouldn't be too hard. > > Martin - can you try this? > I'll see what I can do.
The ICE is fixed. The wrong-debug issue is PR43141 now.