The one application of "goto" that I swear by is for cleaning up allocations on failure when coding in C.
Maintaining a huge library of legacy C code, one of the most common bugs we see is leaks due to people using multiple "return" statements and failing to clean up allocations. You can fairly reliably pick such a function at random and find a memory leak: people always get it wrong.
"goto cleanup;" however, is hard to mess up.
I've seen any number of clever tricks to avoid the "goto". Using "break" statements in a do {} while (0) loop, for example. All of them merely obfuscate the code, and make it more likely for bugs to appear.