You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2022/04/14 03:18:05 UTC

[groovy] 09/09: GROOVY-10580: Conditionally initialized `final` variables considered maybe uninitialized

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 246f11fbee3c952b6feff3de1ff4b52594213d16
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Apr 13 13:17:34 2022 +1000

    GROOVY-10580: Conditionally initialized `final` variables considered maybe uninitialized
---
 .../groovy/classgen/FinalVariableAnalyzer.java     |  8 ++++++-
 .../classgen/FinalVariableAnalyzerTest.groovy      | 28 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java b/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
index a2d799c1b0..907182ebea 100644
--- a/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
+++ b/src/main/java/org/codehaus/groovy/classgen/FinalVariableAnalyzer.java
@@ -290,13 +290,19 @@ public class FinalVariableAnalyzer extends ClassCodeVisitorSupport {
         allVars.addAll(curState.keySet());
         allVars.addAll(ifState.keySet());
         allVars.addAll(elseState.keySet());
+        boolean ifReturning = returningBlock(ifElse.getIfBlock());
+        boolean elseReturning = returningBlock(ifElse.getElseBlock());
         for (Variable var : allVars) {
             VariableState beforeValue = curState.get(var);
             if (beforeValue != null) {
                 VariableState ifValue = ifState.get(var);
                 VariableState elseValue = elseState.get(var);
-                if (ifValue == elseValue) {
+                if (ifValue == elseValue || (elseReturning && !ifReturning)) {
                     curState.put(var, ifValue);
+                } else if (ifReturning && !elseReturning) {
+                    curState.put(var, elseValue);
+                } else if (ifReturning) {
+                    curState.put(var, beforeValue);
                 } else {
                     curState.put(var, beforeValue == VariableState.is_uninitialized ? VariableState.is_ambiguous : VariableState.is_var);
                 }
diff --git a/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy b/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
index 5e136db1c8..0142721fcd 100644
--- a/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/FinalVariableAnalyzerTest.groovy
@@ -534,6 +534,34 @@ class FinalVariableAnalyzerTest extends GroovyTestCase {
         '''
     }
 
+    // GROOVY-10580
+    void testFinalVarIfElseStatementReturningBranch() {
+        assertScript '''
+            final int i
+            final boolean a = true
+            if (a) {
+                i = 1
+            } else {
+                throw new IllegalStateException('a is false')
+            }
+            def result = i
+            assert result == 1
+
+            def evalJ() {
+                final int j
+                final boolean b = true
+                if (!b) {
+                    return null
+                } else {
+                    j = 2
+                }
+                def result = j
+                return result
+            }
+            assert evalJ() == 2
+        '''
+    }
+
     @CompileStatic
     private static class AssertionFinalVariableAnalyzer extends FinalVariableAnalyzer {