[ 
https://issues.apache.org/jira/browse/GROOVY-4721?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15889394#comment-15889394
 ] 

Daniel Sun commented on GROOVY-4721:
------------------------------------


{code}
    String m() {
        try {
            String str = "hello";
            return str;
        } finally {
            System.out.println("world");
        }
    }
{code}

Java will compile the above method into the following bytecode. As we can see, 
local variable {{str}}'s range {{ [L3, L2) }} covers {{L1}}, so the finally 
block of nomal execution flow can access {{str}} on the bytecode level. I guess 
Java control the access before generating bytecodes.
{code}
  // access flags 0x0
  m()Ljava/lang/String;
    TRYCATCHBLOCK L0 L1 L2 null
   L0
    LINENUMBER 13 L0
    LDC "hello"
    ASTORE 1
   L3
    LINENUMBER 14 L3
    ALOAD 1
    ASTORE 2
   L1
    LINENUMBER 16 L1
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "world"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L4
    LINENUMBER 14 L4
    ALOAD 2
    ARETURN
   L2
    LINENUMBER 16 L2
   FRAME SAME1 java/lang/Throwable
    ASTORE 3
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "world"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    ALOAD 3
    ATHROW
   L5
    LOCALVARIABLE str Ljava/lang/String; L3 L2 1
    LOCALVARIABLE this Lcom/groovyhelp/bytecodelab/TryCatchFinally; L0 L5 0
    MAXSTACK = 2
    MAXLOCALS = 4
{code}

> variable declared in try block is in scope in finally block
> -----------------------------------------------------------
>
>                 Key: GROOVY-4721
>                 URL: https://issues.apache.org/jira/browse/GROOVY-4721
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 2.4.0-rc-1
>            Reporter: Hamlet D'Arcy
>
> This code should fail because 'x' is out of scope in the finally block. 
> {code}
> class MyClass {
>     def myMethod() {
>         try {
>             def x = 'foo'
>             println x
>         }
>         finally {
>             println x
>         }
>     }
> }
> new MyClass().myMethod()
> {code}
> Instead it prints 'foo' twice. 
> if myMethod is static then it shows the behavior I expect. 
> Could be something wrong with VariableScope somewhere? 
> This example is from the Groovy codebase. We have code that relies on this 
> behavior (although it is easy to find and fix, just run the UnusedVariable 
> codenarc inspection, which is how I found it)



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to