As the testcase shows, we ICEd when generating the debug info for C++ and not splitting types into multiple registers. The issue is in vt_add_function_parameter that we assumed that the DECL_RTL expression was a pseudo register. But in that case it is better to just give up than to ICE. Regtested/bootstrapped on x86_64, ok for trunk?
2012-10-08 Marek Polacek <pola...@redhat.com> PR debug/54831 * var-tracking.c (vt_add_function_parameter): Use condition in place of gcc_assert. * testsuite/g++.dg/debug/pr54831.C: New test. --- gcc/testsuite/g++.dg/debug/pr54831.C.mp 2012-10-08 12:14:55.790807737 +0200 +++ gcc/testsuite/g++.dg/debug/pr54831.C 2012-10-08 12:51:53.856042257 +0200 @@ -0,0 +1,20 @@ +// PR debug/54831 +// { dg-do compile } +// { dg-options "-O -fno-split-wide-types -g" } + +struct S +{ + int m1(); + int m2(); +}; + +typedef void (S::*mptr) (); + +mptr gmp; +void bar (mptr f); + +void foo (mptr f) +{ + f = gmp; + bar (f); +} --- gcc/var-tracking.c.mp 2012-10-08 10:56:32.354556352 +0200 +++ gcc/var-tracking.c 2012-10-08 12:50:09.627307344 +0200 @@ -9404,12 +9404,13 @@ vt_add_function_parameter (tree parm) if (parm != decl) { - /* Assume that DECL_RTL was a pseudo that got spilled to - memory. The spill slot sharing code will force the + /* If that DECL_RTL wasn't a pseudo that got spilled to + memory, bail out. The spill slot sharing code will force the memory to reference spill_slot_decl (%sfp), so we don't match above. That's ok, the pseudo must have referenced the entire parameter, so just reset OFFSET. */ - gcc_assert (decl == get_spill_slot_decl (false)); + if (decl != get_spill_slot_decl (false)) + return; offset = 0; } Marek