After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 579101 - Return inside of try block routes around finally block
Return inside of try block routes around finally block
Status: RESOLVED FIXED
Product: vala
Classification: Core
Component: Errors
0.6.x
Other All
: Normal major
: ---
Assigned To: Jürg Billeter
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2009-04-15 23:42 UTC by Jim Nelson
Modified: 2009-09-30 08:53 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
a simple testcase (280 bytes, text/x-vala)
2009-07-17 17:18 UTC, zarevucky.jiri
  Details
Copy the finally block in front of every jump (10.12 KB, patch)
2009-07-25 20:46 UTC, zarevucky.jiri
none Details | Review
Copy the finally block in front of every jump (10.79 KB, patch)
2009-07-25 22:26 UTC, zarevucky.jiri
needs-work Details | Review
Copy the finally block in front of every jump (10.53 KB, patch)
2009-07-28 19:04 UTC, zarevucky.jiri
committed Details | Review

Description Jim Nelson 2009-04-15 23:42:19 UTC
Please describe the problem:
When a return statement is inside a try block, the code in the finally block is not executed.

Steps to reproduce:
void main(string[] args) {
    try {
        stdout.printf("foo");
        
        return;
    } finally {
        stdout.printf("bar");
    }
}

Actual results:
"foo"

Expected results:
"foobar"

Does this happen every time?
Yes.

Other information:
I don't know if this is related to this being a try block with no catch block.
Comment 1 Jim Nelson 2009-04-15 23:49:15 UTC
I should add: I'm using valac 0.6.1.
Comment 2 Yin Jintao 2009-06-07 17:54:37 UTC
It occurs with valac 0.7.1.
Comment 3 Thijs Vermeir 2009-07-07 20:17:17 UTC
This does not happen anymore with latest git version.
Comment 4 zarevucky.jiri 2009-07-17 16:56:04 UTC
It still happens.
Comment 5 zarevucky.jiri 2009-07-17 17:18:12 UTC
Created attachment 138621 [details]
a simple testcase

This is a simple test case. Just look at the generated C code, it's a total mess.

Since it's also a great opportunity to learn something about the compiler, I'm trying to fix it myself right now.
Comment 6 zarevucky.jiri 2009-07-25 20:46:06 UTC
Created attachment 139211 [details] [review]
Copy the finally block in front of every jump

This patch simply duplicates the whole finally block (the whole chain, actually) in front of jumps. Quite redundant, but considering that most finally blocks are one, maybe two lines, it's perhaps not so bad.

Originally, I was working on completely redoing the way scope cleanup is done, by concentrating all the cleanup code at the end of scope, instead of doing it in front of jumps.

Now I'm not sure whether it's worthwhile at the moment. It removes redundancy, but it also adds a lot of goto statements and a helper variable to track the reason of scope exit. Any opinions on that?
Comment 7 zarevucky.jiri 2009-07-25 21:31:26 UTC
The patch I posted is wrong. Ignore it until I attach fixed version.
Comment 8 zarevucky.jiri 2009-07-25 22:26:54 UTC
Created attachment 139213 [details] [review]
Copy the finally block in front of every jump

Fixed the problems. Now it should hopefully work correctly.
Comment 9 Jürg Billeter 2009-07-28 10:39:57 UTC
Thanks for the patch. It looks fine in general, but I have a few comments:

The change in GErroModule.visit_try_statement looks wrong. I haven't tested it but I suspect that this will cause issues if code in the catch clause or the finally block throws an error (as long as `current_try' is set, the compiler assumes that errors should be caught by the corresponding catch clauses).

The patch adds tracking of variables modified in finally blocks to avoid negative side-effects by the shortcut of the return statement (avoiding ref/unref or dup/free pairs).  I'm not sure we want to add this in this form. The reason is that this adds some complexity just for a tiny optimization. As you've probably noticed, the code generator is already complex enough as it is, I'm trying to simplify it.

An alternative to variable tracking is to just disable the shortcut of the return statement when the return statement is within a try that has a finally block. This keeps it a bit simpler without big disadvantages, in my opinion.
Comment 10 zarevucky.jiri 2009-07-28 19:04:11 UTC
Created attachment 139412 [details] [review]
Copy the finally block in front of every jump

You were right about the catch clause. I forgot about that. It seems throws in catch clauses were circumventing finally block, too. It's fixed now.

I've also replaced the modification checking with simple accessibility check, as you wished. You're probably right there is not too much to worry about.

Hopefully, everything should be in order now. :)
Comment 11 Jürg Billeter 2009-07-28 20:37:58 UTC
commit 068d310a4943b04747f0fc9ad7b645709405ff53
Author: Jiří Zárevúcky <zarevucky.jiri@gmail.com>
Date:   Tue Jul 28 22:32:51 2009 +0200

    Fix jump statements in try with finally
    
    Fixes bug 579101.
Comment 12 Jürg Billeter 2009-09-30 08:53:12 UTC
commit 9f21d0b182edad861f93a91674787b8b3b4fc2c5
Author: Jürg Billeter <j@bitron.ch>
Date:   Wed Sep 30 10:52:27 2009 +0200

    Add test for bug 579101