< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java

Print this page

        

@@ -28,10 +28,11 @@
 package com.sun.tools.javac.comp;
 
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.WriteableScope;
 import com.sun.tools.javac.code.Source.Feature;

@@ -253,10 +254,50 @@
         } finally {
             log.popDiagnosticHandler(diagHandler);
         }
     }
 
+    public boolean aliveAfter(Env<AttrContext> env, JCTree that, TreeMaker make) {
+        //we need to disable diagnostics temporarily; the problem is that if
+        //"that" contains e.g. an unreachable statement, an error
+        //message will be reported and will cause compilation to skip the flow analyis
+        //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+        //related errors, which will allow for more errors to be detected
+        Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+        try {
+            SnippetAliveAnalyzer analyzer = new SnippetAliveAnalyzer();
+
+            analyzer.analyzeTree(env, that, make);
+            return analyzer.isAlive();
+        } finally {
+            log.popDiagnosticHandler(diagHandler);
+        }
+    }
+
+    public boolean breaksOutOf(Env<AttrContext> env, JCTree loop, JCTree body, TreeMaker make) {
+        //we need to disable diagnostics temporarily; the problem is that if
+        //"that" contains e.g. an unreachable statement, an error
+        //message will be reported and will cause compilation to skip the flow analyis
+        //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+        //related errors, which will allow for more errors to be detected
+        Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+        try {
+            boolean[] breaksOut = new boolean[1];
+            new AliveAnalyzer() {
+                @Override
+                public void visitBreak(JCBreak tree) {
+                    breaksOut[0] |= (super.alive == Liveness.ALIVE && tree.target == loop);
+                    super.visitBreak(tree);
+                }
+            }.analyzeTree(env, body, make);
+
+            return breaksOut[0];
+        } finally {
+            log.popDiagnosticHandler(diagHandler);
+        }
+    }
+
     /**
      * Definite assignment scan mode
      */
     enum FlowKind {
         /**

@@ -1465,10 +1506,23 @@
             //skip
         }
     }
 
     /**
+     * Determine if alive after the given tree.
+     */
+    class SnippetAliveAnalyzer extends AliveAnalyzer {
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            //skip
+        }
+        public boolean isAlive() {
+            return super.alive != Liveness.DEAD;
+        }
+    }
+
+    /**
      * Specialized pass that performs DA/DU on a lambda
      */
     class LambdaAssignAnalyzer extends AssignAnalyzer {
         WriteableScope enclosedSymbols;
         boolean inLambda;

@@ -1986,21 +2040,25 @@
                     scan(tree.body);
 
                     if (isInitialConstructor) {
                         boolean isSynthesized = (tree.sym.flags() &
                                                  GENERATEDCONSTR) != 0;
-                        for (int i = firstadr; i < nextadr; i++) {
-                            JCVariableDecl vardecl = vardecls[i];
-                            VarSymbol var = vardecl.sym;
-                            if (var.owner == classDef.sym) {
-                                // choose the diagnostic position based on whether
-                                // the ctor is default(synthesized) or not
-                                if (isSynthesized) {
-                                    checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
-                                        var, Errors.VarNotInitializedInDefaultConstructor(var));
-                                } else {
-                                    checkInit(TreeInfo.diagEndPos(tree.body), var);
+                        boolean isRecord = (tree.sym.owner.flags() & Flags.RECORD) != 0;
+                        // skip record as they are generated by the compiler and guaranteed to be correct
+                        if (!isRecord || !isSynthesized) {
+                            for (int i = firstadr; i < nextadr; i++) {
+                                JCVariableDecl vardecl = vardecls[i];
+                                VarSymbol var = vardecl.sym;
+                                if (var.owner == classDef.sym) {
+                                    // choose the diagnostic position based on whether
+                                    // the ctor is default(synthesized) or not
+                                    if (isSynthesized) {
+                                        checkInit(TreeInfo.diagnosticPositionFor(var, vardecl),
+                                            var, Errors.VarNotInitializedInDefaultConstructor(var));
+                                    } else {
+                                        checkInit(TreeInfo.diagEndPos(tree.body), var);
+                                    }
                                 }
                             }
                         }
                     }
                     List<PendingExit> exits = pendingExits.toList();
< prev index next >