Message ID | alpine.LNX.2.00.1106271628240.810@zhemvz.fhfr.qr |
---|---|
State | New |
Headers | show |
> > 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? Well, the transforms are added into cgraph node at a time IPA pass is run and then when non-IPA pass is run the transform is applied and removed from the list. The passmanager was originally intended to allow arbitrary ping-pong in between ipa/small-ipa and local passes doing the right thing (i.e. applying the ipa passes run since last non-IPA pass first time non-IPA pass is executed after a sequence of IPA passes. So the transforms are not run twice with IPA-PTA even if apply_ipa_transforms is. Honza
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; +}