Running IPA transforms will mess up current_pass (and reset it to NULL), ICEing later for IPA PTA. I also don't see any code that would avoid doing IPA transforms twice in case we put another small IPA pass in the late IPA pass queue. Honza, I guess we need to add some PROP_ipa_transforms_applied and simply make the late IPA passes depend on that?
Noticed when adding a testcase for the now working PR49394 Anyway, bootstrapped and tested on x86_64-unknown-linux-gnu, applied. 2011-06-27 Richard Guenther <rguent...@suse.de> PR tree-optimization/49394 * passes.c (execute_one_pass): Restore current_pass after applying IPA transforms. * g++.dg/torture/pr49394.C: New testcase. Index: gcc/passes.c =================================================================== --- gcc/passes.c (revision 175526) +++ gcc/passes.c (working copy) @@ -2030,6 +2030,8 @@ execute_one_pass (struct opt_pass *pass) do_per_function (apply_ipa_transforms, (void *)&applied); if (applied) cgraph_remove_unreachable_nodes (true, dump_file); + /* Restore current_pass. */ + current_pass = pass; } if (!quiet_flag && !cfun) Index: gcc/testsuite/g++.dg/torture/pr49394.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr49394.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr49394.C (revision 0) @@ -0,0 +1,50 @@ +// { dg-do run } +// { dg-options "-fipa-pta -fnon-call-exceptions" } + +struct Mutex +{ + bool locked; + ~Mutex () + { + if (locked) + throw 0; + } + void lock () + { + locked = true; + } + void unlock () + { + if (!locked) + throw 0; + locked = false; + } +}; + +struct lock_guard +{ + Mutex *m; + lock_guard (Mutex *m) : m(m) + { + } + ~lock_guard () + { + m->unlock (); + } +}; + +int +main () +{ + Mutex m; + m.lock (); + try + { + lock_guard l (&m); + } + catch ( ...) + { + __builtin_abort (); + } + return 0; +}