langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
author mcimadamore
Thu, 03 Mar 2011 17:32:35 +0000
changeset 8627 e60ca990602f
parent 8626 38b24af530bc
child 8849 4189ac38ddc9
permissions -rw-r--r--
7023703: Valid code doesn't compile Summary: leftovers cause problems when analyzing loops in Flow.java Reviewed-by: jjg
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     1
/*
8031
d5fe2c1cecfc 6992999: fully remove JSR 308 from langtools
jjg
parents: 7681
diff changeset
     2
 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
06bc494ca11e Initial load
duke
parents:
diff changeset
     4
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
06bc494ca11e Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 5492
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 5492
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    10
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
06bc494ca11e Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
06bc494ca11e Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
06bc494ca11e Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
06bc494ca11e Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
06bc494ca11e Initial load
duke
parents:
diff changeset
    16
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
06bc494ca11e Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
06bc494ca11e Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
06bc494ca11e Initial load
duke
parents:
diff changeset
    20
 *
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 5492
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 5492
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 5492
diff changeset
    23
 * questions.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    24
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    25
06bc494ca11e Initial load
duke
parents:
diff changeset
    26
//todo: one might eliminate uninits.andSets when monotonic
06bc494ca11e Initial load
duke
parents:
diff changeset
    27
06bc494ca11e Initial load
duke
parents:
diff changeset
    28
package com.sun.tools.javac.comp;
06bc494ca11e Initial load
duke
parents:
diff changeset
    29
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
    30
import java.util.HashMap;
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
    31
import java.util.Map;
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
    32
import java.util.LinkedHashMap;
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
    33
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    34
import com.sun.tools.javac.code.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    35
import com.sun.tools.javac.tree.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    36
import com.sun.tools.javac.util.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    37
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
06bc494ca11e Initial load
duke
parents:
diff changeset
    38
06bc494ca11e Initial load
duke
parents:
diff changeset
    39
import com.sun.tools.javac.code.Symbol.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    40
import com.sun.tools.javac.tree.JCTree.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    41
06bc494ca11e Initial load
duke
parents:
diff changeset
    42
import static com.sun.tools.javac.code.Flags.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    43
import static com.sun.tools.javac.code.Kinds.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    44
import static com.sun.tools.javac.code.TypeTags.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    45
06bc494ca11e Initial load
duke
parents:
diff changeset
    46
/** This pass implements dataflow analysis for Java programs.
06bc494ca11e Initial load
duke
parents:
diff changeset
    47
 *  Liveness analysis checks that every statement is reachable.
06bc494ca11e Initial load
duke
parents:
diff changeset
    48
 *  Exception analysis ensures that every checked exception that is
06bc494ca11e Initial load
duke
parents:
diff changeset
    49
 *  thrown is declared or caught.  Definite assignment analysis
06bc494ca11e Initial load
duke
parents:
diff changeset
    50
 *  ensures that each variable is assigned when used.  Definite
06bc494ca11e Initial load
duke
parents:
diff changeset
    51
 *  unassignment analysis ensures that no final variable is assigned
06bc494ca11e Initial load
duke
parents:
diff changeset
    52
 *  more than once.
06bc494ca11e Initial load
duke
parents:
diff changeset
    53
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    54
 *  <p>The second edition of the JLS has a number of problems in the
06bc494ca11e Initial load
duke
parents:
diff changeset
    55
 *  specification of these flow analysis problems. This implementation
06bc494ca11e Initial load
duke
parents:
diff changeset
    56
 *  attempts to address those issues.
06bc494ca11e Initial load
duke
parents:
diff changeset
    57
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    58
 *  <p>First, there is no accommodation for a finally clause that cannot
06bc494ca11e Initial load
duke
parents:
diff changeset
    59
 *  complete normally. For liveness analysis, an intervening finally
06bc494ca11e Initial load
duke
parents:
diff changeset
    60
 *  clause can cause a break, continue, or return not to reach its
06bc494ca11e Initial load
duke
parents:
diff changeset
    61
 *  target.  For exception analysis, an intervening finally clause can
06bc494ca11e Initial load
duke
parents:
diff changeset
    62
 *  cause any exception to be "caught".  For DA/DU analysis, the finally
06bc494ca11e Initial load
duke
parents:
diff changeset
    63
 *  clause can prevent a transfer of control from propagating DA/DU
06bc494ca11e Initial load
duke
parents:
diff changeset
    64
 *  state to the target.  In addition, code in the finally clause can
06bc494ca11e Initial load
duke
parents:
diff changeset
    65
 *  affect the DA/DU status of variables.
06bc494ca11e Initial load
duke
parents:
diff changeset
    66
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    67
 *  <p>For try statements, we introduce the idea of a variable being
06bc494ca11e Initial load
duke
parents:
diff changeset
    68
 *  definitely unassigned "everywhere" in a block.  A variable V is
06bc494ca11e Initial load
duke
parents:
diff changeset
    69
 *  "unassigned everywhere" in a block iff it is unassigned at the
06bc494ca11e Initial load
duke
parents:
diff changeset
    70
 *  beginning of the block and there is no reachable assignment to V
06bc494ca11e Initial load
duke
parents:
diff changeset
    71
 *  in the block.  An assignment V=e is reachable iff V is not DA
06bc494ca11e Initial load
duke
parents:
diff changeset
    72
 *  after e.  Then we can say that V is DU at the beginning of the
06bc494ca11e Initial load
duke
parents:
diff changeset
    73
 *  catch block iff V is DU everywhere in the try block.  Similarly, V
06bc494ca11e Initial load
duke
parents:
diff changeset
    74
 *  is DU at the beginning of the finally block iff V is DU everywhere
06bc494ca11e Initial load
duke
parents:
diff changeset
    75
 *  in the try block and in every catch block.  Specifically, the
06bc494ca11e Initial load
duke
parents:
diff changeset
    76
 *  following bullet is added to 16.2.2
06bc494ca11e Initial load
duke
parents:
diff changeset
    77
 *  <pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    78
 *      V is <em>unassigned everywhere</em> in a block if it is
06bc494ca11e Initial load
duke
parents:
diff changeset
    79
 *      unassigned before the block and there is no reachable
06bc494ca11e Initial load
duke
parents:
diff changeset
    80
 *      assignment to V within the block.
06bc494ca11e Initial load
duke
parents:
diff changeset
    81
 *  </pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    82
 *  <p>In 16.2.15, the third bullet (and all of its sub-bullets) for all
06bc494ca11e Initial load
duke
parents:
diff changeset
    83
 *  try blocks is changed to
06bc494ca11e Initial load
duke
parents:
diff changeset
    84
 *  <pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    85
 *      V is definitely unassigned before a catch block iff V is
06bc494ca11e Initial load
duke
parents:
diff changeset
    86
 *      definitely unassigned everywhere in the try block.
06bc494ca11e Initial load
duke
parents:
diff changeset
    87
 *  </pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    88
 *  <p>The last bullet (and all of its sub-bullets) for try blocks that
06bc494ca11e Initial load
duke
parents:
diff changeset
    89
 *  have a finally block is changed to
06bc494ca11e Initial load
duke
parents:
diff changeset
    90
 *  <pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    91
 *      V is definitely unassigned before the finally block iff
06bc494ca11e Initial load
duke
parents:
diff changeset
    92
 *      V is definitely unassigned everywhere in the try block
06bc494ca11e Initial load
duke
parents:
diff changeset
    93
 *      and everywhere in each catch block of the try statement.
06bc494ca11e Initial load
duke
parents:
diff changeset
    94
 *  </pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    95
 *  <p>In addition,
06bc494ca11e Initial load
duke
parents:
diff changeset
    96
 *  <pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
    97
 *      V is definitely assigned at the end of a constructor iff
06bc494ca11e Initial load
duke
parents:
diff changeset
    98
 *      V is definitely assigned after the block that is the body
06bc494ca11e Initial load
duke
parents:
diff changeset
    99
 *      of the constructor and V is definitely assigned at every
06bc494ca11e Initial load
duke
parents:
diff changeset
   100
 *      return that can return from the constructor.
06bc494ca11e Initial load
duke
parents:
diff changeset
   101
 *  </pre>
06bc494ca11e Initial load
duke
parents:
diff changeset
   102
 *  <p>In addition, each continue statement with the loop as its target
06bc494ca11e Initial load
duke
parents:
diff changeset
   103
 *  is treated as a jump to the end of the loop body, and "intervening"
06bc494ca11e Initial load
duke
parents:
diff changeset
   104
 *  finally clauses are treated as follows: V is DA "due to the
06bc494ca11e Initial load
duke
parents:
diff changeset
   105
 *  continue" iff V is DA before the continue statement or V is DA at
06bc494ca11e Initial load
duke
parents:
diff changeset
   106
 *  the end of any intervening finally block.  V is DU "due to the
06bc494ca11e Initial load
duke
parents:
diff changeset
   107
 *  continue" iff any intervening finally cannot complete normally or V
06bc494ca11e Initial load
duke
parents:
diff changeset
   108
 *  is DU at the end of every intervening finally block.  This "due to
06bc494ca11e Initial load
duke
parents:
diff changeset
   109
 *  the continue" concept is then used in the spec for the loops.
06bc494ca11e Initial load
duke
parents:
diff changeset
   110
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   111
 *  <p>Similarly, break statements must consider intervening finally
06bc494ca11e Initial load
duke
parents:
diff changeset
   112
 *  blocks.  For liveness analysis, a break statement for which any
06bc494ca11e Initial load
duke
parents:
diff changeset
   113
 *  intervening finally cannot complete normally is not considered to
06bc494ca11e Initial load
duke
parents:
diff changeset
   114
 *  cause the target statement to be able to complete normally. Then
06bc494ca11e Initial load
duke
parents:
diff changeset
   115
 *  we say V is DA "due to the break" iff V is DA before the break or
06bc494ca11e Initial load
duke
parents:
diff changeset
   116
 *  V is DA at the end of any intervening finally block.  V is DU "due
06bc494ca11e Initial load
duke
parents:
diff changeset
   117
 *  to the break" iff any intervening finally cannot complete normally
06bc494ca11e Initial load
duke
parents:
diff changeset
   118
 *  or V is DU at the break and at the end of every intervening
06bc494ca11e Initial load
duke
parents:
diff changeset
   119
 *  finally block.  (I suspect this latter condition can be
06bc494ca11e Initial load
duke
parents:
diff changeset
   120
 *  simplified.)  This "due to the break" is then used in the spec for
06bc494ca11e Initial load
duke
parents:
diff changeset
   121
 *  all statements that can be "broken".
06bc494ca11e Initial load
duke
parents:
diff changeset
   122
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   123
 *  <p>The return statement is treated similarly.  V is DA "due to a
06bc494ca11e Initial load
duke
parents:
diff changeset
   124
 *  return statement" iff V is DA before the return statement or V is
06bc494ca11e Initial load
duke
parents:
diff changeset
   125
 *  DA at the end of any intervening finally block.  Note that we
06bc494ca11e Initial load
duke
parents:
diff changeset
   126
 *  don't have to worry about the return expression because this
06bc494ca11e Initial load
duke
parents:
diff changeset
   127
 *  concept is only used for construcrors.
06bc494ca11e Initial load
duke
parents:
diff changeset
   128
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   129
 *  <p>There is no spec in JLS2 for when a variable is definitely
06bc494ca11e Initial load
duke
parents:
diff changeset
   130
 *  assigned at the end of a constructor, which is needed for final
06bc494ca11e Initial load
duke
parents:
diff changeset
   131
 *  fields (8.3.1.2).  We implement the rule that V is DA at the end
06bc494ca11e Initial load
duke
parents:
diff changeset
   132
 *  of the constructor iff it is DA and the end of the body of the
06bc494ca11e Initial load
duke
parents:
diff changeset
   133
 *  constructor and V is DA "due to" every return of the constructor.
06bc494ca11e Initial load
duke
parents:
diff changeset
   134
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   135
 *  <p>Intervening finally blocks similarly affect exception analysis.  An
06bc494ca11e Initial load
duke
parents:
diff changeset
   136
 *  intervening finally that cannot complete normally allows us to ignore
06bc494ca11e Initial load
duke
parents:
diff changeset
   137
 *  an otherwise uncaught exception.
06bc494ca11e Initial load
duke
parents:
diff changeset
   138
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   139
 *  <p>To implement the semantics of intervening finally clauses, all
06bc494ca11e Initial load
duke
parents:
diff changeset
   140
 *  nonlocal transfers (break, continue, return, throw, method call that
06bc494ca11e Initial load
duke
parents:
diff changeset
   141
 *  can throw a checked exception, and a constructor invocation that can
06bc494ca11e Initial load
duke
parents:
diff changeset
   142
 *  thrown a checked exception) are recorded in a queue, and removed
06bc494ca11e Initial load
duke
parents:
diff changeset
   143
 *  from the queue when we complete processing the target of the
06bc494ca11e Initial load
duke
parents:
diff changeset
   144
 *  nonlocal transfer.  This allows us to modify the queue in accordance
06bc494ca11e Initial load
duke
parents:
diff changeset
   145
 *  with the above rules when we encounter a finally clause.  The only
06bc494ca11e Initial load
duke
parents:
diff changeset
   146
 *  exception to this [no pun intended] is that checked exceptions that
06bc494ca11e Initial load
duke
parents:
diff changeset
   147
 *  are known to be caught or declared to be caught in the enclosing
06bc494ca11e Initial load
duke
parents:
diff changeset
   148
 *  method are not recorded in the queue, but instead are recorded in a
06bc494ca11e Initial load
duke
parents:
diff changeset
   149
 *  global variable "Set<Type> thrown" that records the type of all
06bc494ca11e Initial load
duke
parents:
diff changeset
   150
 *  exceptions that can be thrown.
06bc494ca11e Initial load
duke
parents:
diff changeset
   151
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   152
 *  <p>Other minor issues the treatment of members of other classes
06bc494ca11e Initial load
duke
parents:
diff changeset
   153
 *  (always considered DA except that within an anonymous class
06bc494ca11e Initial load
duke
parents:
diff changeset
   154
 *  constructor, where DA status from the enclosing scope is
06bc494ca11e Initial load
duke
parents:
diff changeset
   155
 *  preserved), treatment of the case expression (V is DA before the
06bc494ca11e Initial load
duke
parents:
diff changeset
   156
 *  case expression iff V is DA after the switch expression),
06bc494ca11e Initial load
duke
parents:
diff changeset
   157
 *  treatment of variables declared in a switch block (the implied
06bc494ca11e Initial load
duke
parents:
diff changeset
   158
 *  DA/DU status after the switch expression is DU and not DA for
06bc494ca11e Initial load
duke
parents:
diff changeset
   159
 *  variables defined in a switch block), the treatment of boolean ?:
06bc494ca11e Initial load
duke
parents:
diff changeset
   160
 *  expressions (The JLS rules only handle b and c non-boolean; the
06bc494ca11e Initial load
duke
parents:
diff changeset
   161
 *  new rule is that if b and c are boolean valued, then V is
06bc494ca11e Initial load
duke
parents:
diff changeset
   162
 *  (un)assigned after a?b:c when true/false iff V is (un)assigned
06bc494ca11e Initial load
duke
parents:
diff changeset
   163
 *  after b when true/false and V is (un)assigned after c when
06bc494ca11e Initial load
duke
parents:
diff changeset
   164
 *  true/false).
06bc494ca11e Initial load
duke
parents:
diff changeset
   165
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
   166
 *  <p>There is the remaining question of what syntactic forms constitute a
06bc494ca11e Initial load
duke
parents:
diff changeset
   167
 *  reference to a variable.  It is conventional to allow this.x on the
06bc494ca11e Initial load
duke
parents:
diff changeset
   168
 *  left-hand-side to initialize a final instance field named x, yet
06bc494ca11e Initial load
duke
parents:
diff changeset
   169
 *  this.x isn't considered a "use" when appearing on a right-hand-side
06bc494ca11e Initial load
duke
parents:
diff changeset
   170
 *  in most implementations.  Should parentheses affect what is
06bc494ca11e Initial load
duke
parents:
diff changeset
   171
 *  considered a variable reference?  The simplest rule would be to
06bc494ca11e Initial load
duke
parents:
diff changeset
   172
 *  allow unqualified forms only, parentheses optional, and phase out
06bc494ca11e Initial load
duke
parents:
diff changeset
   173
 *  support for assigning to a final field via this.x.
06bc494ca11e Initial load
duke
parents:
diff changeset
   174
 *
5847
1908176fd6e3 6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents: 5520
diff changeset
   175
 *  <p><b>This is NOT part of any supported API.
1908176fd6e3 6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents: 5520
diff changeset
   176
 *  If you write code that depends on this, you do so at your own risk.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   177
 *  This code and its internal interfaces are subject to change or
06bc494ca11e Initial load
duke
parents:
diff changeset
   178
 *  deletion without notice.</b>
06bc494ca11e Initial load
duke
parents:
diff changeset
   179
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
   180
public class Flow extends TreeScanner {
06bc494ca11e Initial load
duke
parents:
diff changeset
   181
    protected static final Context.Key<Flow> flowKey =
06bc494ca11e Initial load
duke
parents:
diff changeset
   182
        new Context.Key<Flow>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   183
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   184
    private final Names names;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   185
    private final Log log;
06bc494ca11e Initial load
duke
parents:
diff changeset
   186
    private final Symtab syms;
06bc494ca11e Initial load
duke
parents:
diff changeset
   187
    private final Types types;
06bc494ca11e Initial load
duke
parents:
diff changeset
   188
    private final Check chk;
06bc494ca11e Initial load
duke
parents:
diff changeset
   189
    private       TreeMaker make;
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
   190
    private final Resolve rs;
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
   191
    private Env<AttrContext> attrEnv;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   192
    private       Lint lint;
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   193
    private final boolean allowRethrowAnalysis;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   194
06bc494ca11e Initial load
duke
parents:
diff changeset
   195
    public static Flow instance(Context context) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   196
        Flow instance = context.get(flowKey);
06bc494ca11e Initial load
duke
parents:
diff changeset
   197
        if (instance == null)
06bc494ca11e Initial load
duke
parents:
diff changeset
   198
            instance = new Flow(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
   199
        return instance;
06bc494ca11e Initial load
duke
parents:
diff changeset
   200
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   201
06bc494ca11e Initial load
duke
parents:
diff changeset
   202
    protected Flow(Context context) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   203
        context.put(flowKey, this);
1260
a772ba9ba43d 6574134: Allow for alternative implementation of Name Table with garbage collection of name bytes
jjg
parents: 10
diff changeset
   204
        names = Names.instance(context);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   205
        log = Log.instance(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
   206
        syms = Symtab.instance(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
   207
        types = Types.instance(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
   208
        chk = Check.instance(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
   209
        lint = Lint.instance(context);
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
   210
        rs = Resolve.instance(context);
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   211
        Source source = Source.instance(context);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   212
        allowRethrowAnalysis = source.allowMulticatch();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   213
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   214
06bc494ca11e Initial load
duke
parents:
diff changeset
   215
    /** A flag that indicates whether the last statement could
06bc494ca11e Initial load
duke
parents:
diff changeset
   216
     *  complete normally.
06bc494ca11e Initial load
duke
parents:
diff changeset
   217
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   218
    private boolean alive;
06bc494ca11e Initial load
duke
parents:
diff changeset
   219
06bc494ca11e Initial load
duke
parents:
diff changeset
   220
    /** The set of definitely assigned variables.
06bc494ca11e Initial load
duke
parents:
diff changeset
   221
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   222
    Bits inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   223
06bc494ca11e Initial load
duke
parents:
diff changeset
   224
    /** The set of definitely unassigned variables.
06bc494ca11e Initial load
duke
parents:
diff changeset
   225
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   226
    Bits uninits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   227
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
   228
    HashMap<Symbol, List<Type>> preciseRethrowTypes;
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   229
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   230
    /** The set of variables that are definitely unassigned everywhere
06bc494ca11e Initial load
duke
parents:
diff changeset
   231
     *  in current try block. This variable is maintained lazily; it is
06bc494ca11e Initial load
duke
parents:
diff changeset
   232
     *  updated only when something gets removed from uninits,
06bc494ca11e Initial load
duke
parents:
diff changeset
   233
     *  typically by being assigned in reachable code.  To obtain the
06bc494ca11e Initial load
duke
parents:
diff changeset
   234
     *  correct set of variables which are definitely unassigned
06bc494ca11e Initial load
duke
parents:
diff changeset
   235
     *  anywhere in current try block, intersect uninitsTry and
06bc494ca11e Initial load
duke
parents:
diff changeset
   236
     *  uninits.
06bc494ca11e Initial load
duke
parents:
diff changeset
   237
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   238
    Bits uninitsTry;
06bc494ca11e Initial load
duke
parents:
diff changeset
   239
06bc494ca11e Initial load
duke
parents:
diff changeset
   240
    /** When analyzing a condition, inits and uninits are null.
06bc494ca11e Initial load
duke
parents:
diff changeset
   241
     *  Instead we have:
06bc494ca11e Initial load
duke
parents:
diff changeset
   242
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   243
    Bits initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   244
    Bits initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   245
    Bits uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   246
    Bits uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   247
06bc494ca11e Initial load
duke
parents:
diff changeset
   248
    /** A mapping from addresses to variable symbols.
06bc494ca11e Initial load
duke
parents:
diff changeset
   249
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   250
    VarSymbol[] vars;
06bc494ca11e Initial load
duke
parents:
diff changeset
   251
06bc494ca11e Initial load
duke
parents:
diff changeset
   252
    /** The current class being defined.
06bc494ca11e Initial load
duke
parents:
diff changeset
   253
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   254
    JCClassDecl classDef;
06bc494ca11e Initial load
duke
parents:
diff changeset
   255
06bc494ca11e Initial load
duke
parents:
diff changeset
   256
    /** The first variable sequence number in this class definition.
06bc494ca11e Initial load
duke
parents:
diff changeset
   257
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   258
    int firstadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   259
06bc494ca11e Initial load
duke
parents:
diff changeset
   260
    /** The next available variable sequence number.
06bc494ca11e Initial load
duke
parents:
diff changeset
   261
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   262
    int nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   263
06bc494ca11e Initial load
duke
parents:
diff changeset
   264
    /** The list of possibly thrown declarable exceptions.
06bc494ca11e Initial load
duke
parents:
diff changeset
   265
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   266
    List<Type> thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   267
06bc494ca11e Initial load
duke
parents:
diff changeset
   268
    /** The list of exceptions that are either caught or declared to be
06bc494ca11e Initial load
duke
parents:
diff changeset
   269
     *  thrown.
06bc494ca11e Initial load
duke
parents:
diff changeset
   270
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   271
    List<Type> caught;
06bc494ca11e Initial load
duke
parents:
diff changeset
   272
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
   273
    /** The list of unreferenced automatic resources.
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
   274
     */
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
   275
    Scope unrefdResources;
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
   276
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   277
    /** Set when processing a loop body the second time for DU analysis. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   278
    boolean loopPassTwo = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   279
06bc494ca11e Initial load
duke
parents:
diff changeset
   280
    /*-------------------- Environments ----------------------*/
06bc494ca11e Initial load
duke
parents:
diff changeset
   281
06bc494ca11e Initial load
duke
parents:
diff changeset
   282
    /** A pending exit.  These are the statements return, break, and
06bc494ca11e Initial load
duke
parents:
diff changeset
   283
     *  continue.  In addition, exception-throwing expressions or
06bc494ca11e Initial load
duke
parents:
diff changeset
   284
     *  statements are put here when not known to be caught.  This
06bc494ca11e Initial load
duke
parents:
diff changeset
   285
     *  will typically result in an error unless it is within a
06bc494ca11e Initial load
duke
parents:
diff changeset
   286
     *  try-finally whose finally block cannot complete normally.
06bc494ca11e Initial load
duke
parents:
diff changeset
   287
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   288
    static class PendingExit {
06bc494ca11e Initial load
duke
parents:
diff changeset
   289
        JCTree tree;
06bc494ca11e Initial load
duke
parents:
diff changeset
   290
        Bits inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   291
        Bits uninits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   292
        Type thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   293
        PendingExit(JCTree tree, Bits inits, Bits uninits) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   294
            this.tree = tree;
06bc494ca11e Initial load
duke
parents:
diff changeset
   295
            this.inits = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   296
            this.uninits = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   297
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   298
        PendingExit(JCTree tree, Type thrown) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   299
            this.tree = tree;
06bc494ca11e Initial load
duke
parents:
diff changeset
   300
            this.thrown = thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   301
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   302
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   303
06bc494ca11e Initial load
duke
parents:
diff changeset
   304
    /** The currently pending exits that go from current inner blocks
06bc494ca11e Initial load
duke
parents:
diff changeset
   305
     *  to an enclosing block, in source order.
06bc494ca11e Initial load
duke
parents:
diff changeset
   306
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   307
    ListBuffer<PendingExit> pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   308
06bc494ca11e Initial load
duke
parents:
diff changeset
   309
    /*-------------------- Exceptions ----------------------*/
06bc494ca11e Initial load
duke
parents:
diff changeset
   310
06bc494ca11e Initial load
duke
parents:
diff changeset
   311
    /** Complain that pending exceptions are not caught.
06bc494ca11e Initial load
duke
parents:
diff changeset
   312
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   313
    void errorUncaught() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   314
        for (PendingExit exit = pendingExits.next();
06bc494ca11e Initial load
duke
parents:
diff changeset
   315
             exit != null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   316
             exit = pendingExits.next()) {
8428
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   317
            if (classDef != null &&
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   318
                classDef.pos == exit.tree.pos) {
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   319
                log.error(exit.tree.pos(),
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   320
                        "unreported.exception.default.constructor",
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   321
                        exit.thrown);
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   322
            } else if (exit.tree.getTag() == JCTree.VARDEF &&
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   323
                    ((JCVariableDecl)exit.tree).sym.isResourceVariable()) {
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   324
                log.error(exit.tree.pos(),
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   325
                        "unreported.exception.implicit.close",
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   326
                        exit.thrown,
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   327
                        ((JCVariableDecl)exit.tree).sym.name);
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   328
            } else {
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   329
                log.error(exit.tree.pos(),
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   330
                        "unreported.exception.need.to.catch.or.throw",
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   331
                        exit.thrown);
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
   332
            }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   333
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   334
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   335
06bc494ca11e Initial load
duke
parents:
diff changeset
   336
    /** Record that exception is potentially thrown and check that it
06bc494ca11e Initial load
duke
parents:
diff changeset
   337
     *  is caught.
06bc494ca11e Initial load
duke
parents:
diff changeset
   338
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   339
    void markThrown(JCTree tree, Type exc) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   340
        if (!chk.isUnchecked(tree.pos(), exc)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   341
            if (!chk.isHandled(exc, caught))
06bc494ca11e Initial load
duke
parents:
diff changeset
   342
                pendingExits.append(new PendingExit(tree, exc));
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
   343
                thrown = chk.incl(exc, thrown);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   344
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   345
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   346
06bc494ca11e Initial load
duke
parents:
diff changeset
   347
    /*-------------- Processing variables ----------------------*/
06bc494ca11e Initial load
duke
parents:
diff changeset
   348
06bc494ca11e Initial load
duke
parents:
diff changeset
   349
    /** Do we need to track init/uninit state of this symbol?
06bc494ca11e Initial load
duke
parents:
diff changeset
   350
     *  I.e. is symbol either a local or a blank final variable?
06bc494ca11e Initial load
duke
parents:
diff changeset
   351
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   352
    boolean trackable(VarSymbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   353
        return
06bc494ca11e Initial load
duke
parents:
diff changeset
   354
            (sym.owner.kind == MTH ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   355
             ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   356
              classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   357
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   358
06bc494ca11e Initial load
duke
parents:
diff changeset
   359
    /** Initialize new trackable variable by setting its address field
06bc494ca11e Initial load
duke
parents:
diff changeset
   360
     *  to the next available sequence number and entering it under that
06bc494ca11e Initial load
duke
parents:
diff changeset
   361
     *  index into the vars array.
06bc494ca11e Initial load
duke
parents:
diff changeset
   362
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   363
    void newVar(VarSymbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   364
        if (nextadr == vars.length) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   365
            VarSymbol[] newvars = new VarSymbol[nextadr * 2];
06bc494ca11e Initial load
duke
parents:
diff changeset
   366
            System.arraycopy(vars, 0, newvars, 0, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   367
            vars = newvars;
06bc494ca11e Initial load
duke
parents:
diff changeset
   368
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   369
        sym.adr = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   370
        vars[nextadr] = sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   371
        inits.excl(nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   372
        uninits.incl(nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   373
        nextadr++;
06bc494ca11e Initial load
duke
parents:
diff changeset
   374
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   375
06bc494ca11e Initial load
duke
parents:
diff changeset
   376
    /** Record an initialization of a trackable variable.
06bc494ca11e Initial load
duke
parents:
diff changeset
   377
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   378
    void letInit(DiagnosticPosition pos, VarSymbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   379
        if (sym.adr >= firstadr && trackable(sym)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   380
            if ((sym.flags() & FINAL) != 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   381
                if ((sym.flags() & PARAMETER) != 0) {
7074
0183c3f9614e 6949587: rename "DisjointType" to "DisjunctType"
jjg
parents: 6594
diff changeset
   382
                    if ((sym.flags() & DISJUNCTION) != 0) { //multi-catch parameter
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   383
                        log.error(pos, "multicatch.parameter.may.not.be.assigned",
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   384
                                  sym);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   385
                    }
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   386
                    else {
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   387
                        log.error(pos, "final.parameter.may.not.be.assigned",
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   388
                              sym);
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
   389
                    }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   390
                } else if (!uninits.isMember(sym.adr)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   391
                    log.error(pos,
06bc494ca11e Initial load
duke
parents:
diff changeset
   392
                              loopPassTwo
06bc494ca11e Initial load
duke
parents:
diff changeset
   393
                              ? "var.might.be.assigned.in.loop"
06bc494ca11e Initial load
duke
parents:
diff changeset
   394
                              : "var.might.already.be.assigned",
06bc494ca11e Initial load
duke
parents:
diff changeset
   395
                              sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   396
                } else if (!inits.isMember(sym.adr)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   397
                    // reachable assignment
06bc494ca11e Initial load
duke
parents:
diff changeset
   398
                    uninits.excl(sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   399
                    uninitsTry.excl(sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   400
                } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   401
                    //log.rawWarning(pos, "unreachable assignment");//DEBUG
06bc494ca11e Initial load
duke
parents:
diff changeset
   402
                    uninits.excl(sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   403
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   404
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   405
            inits.incl(sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   406
        } else if ((sym.flags() & FINAL) != 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   407
            log.error(pos, "var.might.already.be.assigned", sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   408
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   409
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   410
06bc494ca11e Initial load
duke
parents:
diff changeset
   411
    /** If tree is either a simple name or of the form this.name or
06bc494ca11e Initial load
duke
parents:
diff changeset
   412
     *  C.this.name, and tree represents a trackable variable,
06bc494ca11e Initial load
duke
parents:
diff changeset
   413
     *  record an initialization of the variable.
06bc494ca11e Initial load
duke
parents:
diff changeset
   414
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   415
    void letInit(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   416
        tree = TreeInfo.skipParens(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   417
        if (tree.getTag() == JCTree.IDENT || tree.getTag() == JCTree.SELECT) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   418
            Symbol sym = TreeInfo.symbol(tree);
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   419
            if (sym.kind == VAR) {
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   420
                letInit(tree.pos(), (VarSymbol)sym);
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   421
            }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   422
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   423
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   424
06bc494ca11e Initial load
duke
parents:
diff changeset
   425
    /** Check that trackable variable is initialized.
06bc494ca11e Initial load
duke
parents:
diff changeset
   426
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   427
    void checkInit(DiagnosticPosition pos, VarSymbol sym) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   428
        if ((sym.adr >= firstadr || sym.owner.kind != TYP) &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   429
            trackable(sym) &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   430
            !inits.isMember(sym.adr)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   431
            log.error(pos, "var.might.not.have.been.initialized",
06bc494ca11e Initial load
duke
parents:
diff changeset
   432
                      sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   433
            inits.incl(sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   434
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   435
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   436
06bc494ca11e Initial load
duke
parents:
diff changeset
   437
    /*-------------------- Handling jumps ----------------------*/
06bc494ca11e Initial load
duke
parents:
diff changeset
   438
06bc494ca11e Initial load
duke
parents:
diff changeset
   439
    /** Record an outward transfer of control. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   440
    void recordExit(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   441
        pendingExits.append(new PendingExit(tree, inits, uninits));
06bc494ca11e Initial load
duke
parents:
diff changeset
   442
        markDead();
06bc494ca11e Initial load
duke
parents:
diff changeset
   443
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   444
06bc494ca11e Initial load
duke
parents:
diff changeset
   445
    /** Resolve all breaks of this statement. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   446
    boolean resolveBreaks(JCTree tree,
06bc494ca11e Initial load
duke
parents:
diff changeset
   447
                          ListBuffer<PendingExit> oldPendingExits) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   448
        boolean result = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   449
        List<PendingExit> exits = pendingExits.toList();
06bc494ca11e Initial load
duke
parents:
diff changeset
   450
        pendingExits = oldPendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   451
        for (; exits.nonEmpty(); exits = exits.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   452
            PendingExit exit = exits.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   453
            if (exit.tree.getTag() == JCTree.BREAK &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   454
                ((JCBreak) exit.tree).target == tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   455
                inits.andSet(exit.inits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   456
                uninits.andSet(exit.uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   457
                result = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   458
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   459
                pendingExits.append(exit);
06bc494ca11e Initial load
duke
parents:
diff changeset
   460
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   461
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   462
        return result;
06bc494ca11e Initial load
duke
parents:
diff changeset
   463
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   464
06bc494ca11e Initial load
duke
parents:
diff changeset
   465
    /** Resolve all continues of this statement. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   466
    boolean resolveContinues(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   467
        boolean result = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   468
        List<PendingExit> exits = pendingExits.toList();
06bc494ca11e Initial load
duke
parents:
diff changeset
   469
        pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   470
        for (; exits.nonEmpty(); exits = exits.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   471
            PendingExit exit = exits.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   472
            if (exit.tree.getTag() == JCTree.CONTINUE &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   473
                ((JCContinue) exit.tree).target == tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   474
                inits.andSet(exit.inits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   475
                uninits.andSet(exit.uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   476
                result = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   477
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   478
                pendingExits.append(exit);
06bc494ca11e Initial load
duke
parents:
diff changeset
   479
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   480
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   481
        return result;
06bc494ca11e Initial load
duke
parents:
diff changeset
   482
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   483
06bc494ca11e Initial load
duke
parents:
diff changeset
   484
    /** Record that statement is unreachable.
06bc494ca11e Initial load
duke
parents:
diff changeset
   485
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   486
    void markDead() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   487
        inits.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   488
        uninits.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   489
        alive = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   490
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   491
06bc494ca11e Initial load
duke
parents:
diff changeset
   492
    /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
06bc494ca11e Initial load
duke
parents:
diff changeset
   493
     */
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   494
    void split(boolean setToNull) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   495
        initsWhenFalse = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   496
        uninitsWhenFalse = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   497
        initsWhenTrue = inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   498
        uninitsWhenTrue = uninits;
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   499
        if (setToNull)
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   500
            inits = uninits = null;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   501
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   502
06bc494ca11e Initial load
duke
parents:
diff changeset
   503
    /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
06bc494ca11e Initial load
duke
parents:
diff changeset
   504
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   505
    void merge() {
06bc494ca11e Initial load
duke
parents:
diff changeset
   506
        inits = initsWhenFalse.andSet(initsWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
   507
        uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
   508
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   509
06bc494ca11e Initial load
duke
parents:
diff changeset
   510
/* ************************************************************************
06bc494ca11e Initial load
duke
parents:
diff changeset
   511
 * Visitor methods for statements and definitions
06bc494ca11e Initial load
duke
parents:
diff changeset
   512
 *************************************************************************/
06bc494ca11e Initial load
duke
parents:
diff changeset
   513
06bc494ca11e Initial load
duke
parents:
diff changeset
   514
    /** Analyze a definition.
06bc494ca11e Initial load
duke
parents:
diff changeset
   515
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   516
    void scanDef(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   517
        scanStat(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   518
        if (tree != null && tree.getTag() == JCTree.BLOCK && !alive) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   519
            log.error(tree.pos(),
06bc494ca11e Initial load
duke
parents:
diff changeset
   520
                      "initializer.must.be.able.to.complete.normally");
06bc494ca11e Initial load
duke
parents:
diff changeset
   521
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   522
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   523
06bc494ca11e Initial load
duke
parents:
diff changeset
   524
    /** Analyze a statement. Check that statement is reachable.
06bc494ca11e Initial load
duke
parents:
diff changeset
   525
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   526
    void scanStat(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   527
        if (!alive && tree != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   528
            log.error(tree.pos(), "unreachable.stmt");
06bc494ca11e Initial load
duke
parents:
diff changeset
   529
            if (tree.getTag() != JCTree.SKIP) alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   530
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   531
        scan(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   532
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   533
06bc494ca11e Initial load
duke
parents:
diff changeset
   534
    /** Analyze list of statements.
06bc494ca11e Initial load
duke
parents:
diff changeset
   535
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   536
    void scanStats(List<? extends JCStatement> trees) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   537
        if (trees != null)
06bc494ca11e Initial load
duke
parents:
diff changeset
   538
            for (List<? extends JCStatement> l = trees; l.nonEmpty(); l = l.tail)
06bc494ca11e Initial load
duke
parents:
diff changeset
   539
                scanStat(l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
   540
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   541
06bc494ca11e Initial load
duke
parents:
diff changeset
   542
    /** Analyze an expression. Make sure to set (un)inits rather than
06bc494ca11e Initial load
duke
parents:
diff changeset
   543
     *  (un)initsWhenTrue(WhenFalse) on exit.
06bc494ca11e Initial load
duke
parents:
diff changeset
   544
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   545
    void scanExpr(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   546
        if (tree != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   547
            scan(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   548
            if (inits == null) merge();
06bc494ca11e Initial load
duke
parents:
diff changeset
   549
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   550
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   551
06bc494ca11e Initial load
duke
parents:
diff changeset
   552
    /** Analyze a list of expressions.
06bc494ca11e Initial load
duke
parents:
diff changeset
   553
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   554
    void scanExprs(List<? extends JCExpression> trees) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   555
        if (trees != null)
06bc494ca11e Initial load
duke
parents:
diff changeset
   556
            for (List<? extends JCExpression> l = trees; l.nonEmpty(); l = l.tail)
06bc494ca11e Initial load
duke
parents:
diff changeset
   557
                scanExpr(l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
   558
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   559
06bc494ca11e Initial load
duke
parents:
diff changeset
   560
    /** Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
06bc494ca11e Initial load
duke
parents:
diff changeset
   561
     *  rather than (un)inits on exit.
06bc494ca11e Initial load
duke
parents:
diff changeset
   562
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   563
    void scanCond(JCTree tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   564
        if (tree.type.isFalse()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   565
            if (inits == null) merge();
06bc494ca11e Initial load
duke
parents:
diff changeset
   566
            initsWhenTrue = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   567
            initsWhenTrue.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   568
            uninitsWhenTrue = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   569
            uninitsWhenTrue.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   570
            initsWhenFalse = inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   571
            uninitsWhenFalse = uninits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   572
        } else if (tree.type.isTrue()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   573
            if (inits == null) merge();
06bc494ca11e Initial load
duke
parents:
diff changeset
   574
            initsWhenFalse = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   575
            initsWhenFalse.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   576
            uninitsWhenFalse = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   577
            uninitsWhenFalse.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   578
            initsWhenTrue = inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   579
            uninitsWhenTrue = uninits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   580
        } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   581
            scan(tree);
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   582
            if (inits != null)
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   583
                split(tree.type != syms.unknownType);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   584
        }
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   585
        if (tree.type != syms.unknownType)
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
   586
            inits = uninits = null;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   587
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   588
06bc494ca11e Initial load
duke
parents:
diff changeset
   589
    /* ------------ Visitor methods for various sorts of trees -------------*/
06bc494ca11e Initial load
duke
parents:
diff changeset
   590
06bc494ca11e Initial load
duke
parents:
diff changeset
   591
    public void visitClassDef(JCClassDecl tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   592
        if (tree.sym == null) return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   593
06bc494ca11e Initial load
duke
parents:
diff changeset
   594
        JCClassDecl classDefPrev = classDef;
06bc494ca11e Initial load
duke
parents:
diff changeset
   595
        List<Type> thrownPrev = thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   596
        List<Type> caughtPrev = caught;
06bc494ca11e Initial load
duke
parents:
diff changeset
   597
        boolean alivePrev = alive;
06bc494ca11e Initial load
duke
parents:
diff changeset
   598
        int firstadrPrev = firstadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   599
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   600
        ListBuffer<PendingExit> pendingExitsPrev = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   601
        Lint lintPrev = lint;
06bc494ca11e Initial load
duke
parents:
diff changeset
   602
06bc494ca11e Initial load
duke
parents:
diff changeset
   603
        pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   604
        if (tree.name != names.empty) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   605
            caught = List.nil();
06bc494ca11e Initial load
duke
parents:
diff changeset
   606
            firstadr = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   607
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   608
        classDef = tree;
06bc494ca11e Initial load
duke
parents:
diff changeset
   609
        thrown = List.nil();
06bc494ca11e Initial load
duke
parents:
diff changeset
   610
        lint = lint.augment(tree.sym.attributes_field);
06bc494ca11e Initial load
duke
parents:
diff changeset
   611
06bc494ca11e Initial load
duke
parents:
diff changeset
   612
        try {
06bc494ca11e Initial load
duke
parents:
diff changeset
   613
            // define all the static fields
06bc494ca11e Initial load
duke
parents:
diff changeset
   614
            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   615
                if (l.head.getTag() == JCTree.VARDEF) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   616
                    JCVariableDecl def = (JCVariableDecl)l.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   617
                    if ((def.mods.flags & STATIC) != 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   618
                        VarSymbol sym = def.sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   619
                        if (trackable(sym))
06bc494ca11e Initial load
duke
parents:
diff changeset
   620
                            newVar(sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   621
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   622
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   623
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   624
06bc494ca11e Initial load
duke
parents:
diff changeset
   625
            // process all the static initializers
06bc494ca11e Initial load
duke
parents:
diff changeset
   626
            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   627
                if (l.head.getTag() != JCTree.METHODDEF &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   628
                    (TreeInfo.flags(l.head) & STATIC) != 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   629
                    scanDef(l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
   630
                    errorUncaught();
06bc494ca11e Initial load
duke
parents:
diff changeset
   631
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   632
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   633
06bc494ca11e Initial load
duke
parents:
diff changeset
   634
            // add intersection of all thrown clauses of initial constructors
06bc494ca11e Initial load
duke
parents:
diff changeset
   635
            // to set of caught exceptions, unless class is anonymous.
06bc494ca11e Initial load
duke
parents:
diff changeset
   636
            if (tree.name != names.empty) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   637
                boolean firstConstructor = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   638
                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   639
                    if (TreeInfo.isInitialConstructor(l.head)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   640
                        List<Type> mthrown =
06bc494ca11e Initial load
duke
parents:
diff changeset
   641
                            ((JCMethodDecl) l.head).sym.type.getThrownTypes();
06bc494ca11e Initial load
duke
parents:
diff changeset
   642
                        if (firstConstructor) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   643
                            caught = mthrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   644
                            firstConstructor = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   645
                        } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   646
                            caught = chk.intersect(mthrown, caught);
06bc494ca11e Initial load
duke
parents:
diff changeset
   647
                        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   648
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   649
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   650
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   651
06bc494ca11e Initial load
duke
parents:
diff changeset
   652
            // define all the instance fields
06bc494ca11e Initial load
duke
parents:
diff changeset
   653
            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   654
                if (l.head.getTag() == JCTree.VARDEF) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   655
                    JCVariableDecl def = (JCVariableDecl)l.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   656
                    if ((def.mods.flags & STATIC) == 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   657
                        VarSymbol sym = def.sym;
06bc494ca11e Initial load
duke
parents:
diff changeset
   658
                        if (trackable(sym))
06bc494ca11e Initial load
duke
parents:
diff changeset
   659
                            newVar(sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   660
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   661
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   662
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   663
06bc494ca11e Initial load
duke
parents:
diff changeset
   664
            // process all the instance initializers
06bc494ca11e Initial load
duke
parents:
diff changeset
   665
            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   666
                if (l.head.getTag() != JCTree.METHODDEF &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   667
                    (TreeInfo.flags(l.head) & STATIC) == 0) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   668
                    scanDef(l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
   669
                    errorUncaught();
06bc494ca11e Initial load
duke
parents:
diff changeset
   670
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   671
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   672
06bc494ca11e Initial load
duke
parents:
diff changeset
   673
            // in an anonymous class, add the set of thrown exceptions to
06bc494ca11e Initial load
duke
parents:
diff changeset
   674
            // the throws clause of the synthetic constructor and propagate
06bc494ca11e Initial load
duke
parents:
diff changeset
   675
            // outwards.
8430
be3e5581ea25 6990136: Cleanup use of Type.clone()
dlsmith
parents: 8428
diff changeset
   676
            // Changing the throws clause on the fly is okay here because
be3e5581ea25 6990136: Cleanup use of Type.clone()
dlsmith
parents: 8428
diff changeset
   677
            // the anonymous constructor can't be invoked anywhere else,
be3e5581ea25 6990136: Cleanup use of Type.clone()
dlsmith
parents: 8428
diff changeset
   678
            // and its type hasn't been cached.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   679
            if (tree.name == names.empty) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   680
                for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   681
                    if (TreeInfo.isInitialConstructor(l.head)) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   682
                        JCMethodDecl mdef = (JCMethodDecl)l.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   683
                        mdef.thrown = make.Types(thrown);
8430
be3e5581ea25 6990136: Cleanup use of Type.clone()
dlsmith
parents: 8428
diff changeset
   684
                        mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   685
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   686
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   687
                thrownPrev = chk.union(thrown, thrownPrev);
06bc494ca11e Initial load
duke
parents:
diff changeset
   688
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   689
06bc494ca11e Initial load
duke
parents:
diff changeset
   690
            // process all the methods
06bc494ca11e Initial load
duke
parents:
diff changeset
   691
            for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   692
                if (l.head.getTag() == JCTree.METHODDEF) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   693
                    scan(l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
   694
                    errorUncaught();
06bc494ca11e Initial load
duke
parents:
diff changeset
   695
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   696
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   697
06bc494ca11e Initial load
duke
parents:
diff changeset
   698
            thrown = thrownPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   699
        } finally {
06bc494ca11e Initial load
duke
parents:
diff changeset
   700
            pendingExits = pendingExitsPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   701
            alive = alivePrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   702
            nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   703
            firstadr = firstadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   704
            caught = caughtPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   705
            classDef = classDefPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   706
            lint = lintPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   707
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   708
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   709
06bc494ca11e Initial load
duke
parents:
diff changeset
   710
    public void visitMethodDef(JCMethodDecl tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   711
        if (tree.body == null) return;
06bc494ca11e Initial load
duke
parents:
diff changeset
   712
06bc494ca11e Initial load
duke
parents:
diff changeset
   713
        List<Type> caughtPrev = caught;
06bc494ca11e Initial load
duke
parents:
diff changeset
   714
        List<Type> mthrown = tree.sym.type.getThrownTypes();
06bc494ca11e Initial load
duke
parents:
diff changeset
   715
        Bits initsPrev = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   716
        Bits uninitsPrev = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   717
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   718
        int firstadrPrev = firstadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   719
        Lint lintPrev = lint;
06bc494ca11e Initial load
duke
parents:
diff changeset
   720
06bc494ca11e Initial load
duke
parents:
diff changeset
   721
        lint = lint.augment(tree.sym.attributes_field);
06bc494ca11e Initial load
duke
parents:
diff changeset
   722
8032
e1aa25ccdabb 6396503: javac should not require assertions enabled
jjg
parents: 8031
diff changeset
   723
        Assert.check(pendingExits.isEmpty());
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   724
06bc494ca11e Initial load
duke
parents:
diff changeset
   725
        try {
06bc494ca11e Initial load
duke
parents:
diff changeset
   726
            boolean isInitialConstructor =
06bc494ca11e Initial load
duke
parents:
diff changeset
   727
                TreeInfo.isInitialConstructor(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   728
06bc494ca11e Initial load
duke
parents:
diff changeset
   729
            if (!isInitialConstructor)
06bc494ca11e Initial load
duke
parents:
diff changeset
   730
                firstadr = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   731
            for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   732
                JCVariableDecl def = l.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   733
                scan(def);
06bc494ca11e Initial load
duke
parents:
diff changeset
   734
                inits.incl(def.sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   735
                uninits.excl(def.sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   736
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   737
            if (isInitialConstructor)
06bc494ca11e Initial load
duke
parents:
diff changeset
   738
                caught = chk.union(caught, mthrown);
06bc494ca11e Initial load
duke
parents:
diff changeset
   739
            else if ((tree.sym.flags() & (BLOCK | STATIC)) != BLOCK)
06bc494ca11e Initial load
duke
parents:
diff changeset
   740
                caught = mthrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
   741
            // else we are in an instance initializer block;
06bc494ca11e Initial load
duke
parents:
diff changeset
   742
            // leave caught unchanged.
06bc494ca11e Initial load
duke
parents:
diff changeset
   743
06bc494ca11e Initial load
duke
parents:
diff changeset
   744
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   745
            scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   746
06bc494ca11e Initial load
duke
parents:
diff changeset
   747
            if (alive && tree.sym.type.getReturnType().tag != VOID)
06bc494ca11e Initial load
duke
parents:
diff changeset
   748
                log.error(TreeInfo.diagEndPos(tree.body), "missing.ret.stmt");
06bc494ca11e Initial load
duke
parents:
diff changeset
   749
06bc494ca11e Initial load
duke
parents:
diff changeset
   750
            if (isInitialConstructor) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   751
                for (int i = firstadr; i < nextadr; i++)
06bc494ca11e Initial load
duke
parents:
diff changeset
   752
                    if (vars[i].owner == classDef.sym)
06bc494ca11e Initial load
duke
parents:
diff changeset
   753
                        checkInit(TreeInfo.diagEndPos(tree.body), vars[i]);
06bc494ca11e Initial load
duke
parents:
diff changeset
   754
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   755
            List<PendingExit> exits = pendingExits.toList();
06bc494ca11e Initial load
duke
parents:
diff changeset
   756
            pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   757
            while (exits.nonEmpty()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   758
                PendingExit exit = exits.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   759
                exits = exits.tail;
06bc494ca11e Initial load
duke
parents:
diff changeset
   760
                if (exit.thrown == null) {
8032
e1aa25ccdabb 6396503: javac should not require assertions enabled
jjg
parents: 8031
diff changeset
   761
                    Assert.check(exit.tree.getTag() == JCTree.RETURN);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   762
                    if (isInitialConstructor) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   763
                        inits = exit.inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   764
                        for (int i = firstadr; i < nextadr; i++)
06bc494ca11e Initial load
duke
parents:
diff changeset
   765
                            checkInit(exit.tree.pos(), vars[i]);
06bc494ca11e Initial load
duke
parents:
diff changeset
   766
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   767
                } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   768
                    // uncaught throws will be reported later
06bc494ca11e Initial load
duke
parents:
diff changeset
   769
                    pendingExits.append(exit);
06bc494ca11e Initial load
duke
parents:
diff changeset
   770
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   771
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   772
        } finally {
06bc494ca11e Initial load
duke
parents:
diff changeset
   773
            inits = initsPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   774
            uninits = uninitsPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   775
            nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   776
            firstadr = firstadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   777
            caught = caughtPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   778
            lint = lintPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   779
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   780
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   781
06bc494ca11e Initial load
duke
parents:
diff changeset
   782
    public void visitVarDef(JCVariableDecl tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   783
        boolean track = trackable(tree.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   784
        if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   785
        if (tree.init != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   786
            Lint lintPrev = lint;
06bc494ca11e Initial load
duke
parents:
diff changeset
   787
            lint = lint.augment(tree.sym.attributes_field);
06bc494ca11e Initial load
duke
parents:
diff changeset
   788
            try{
06bc494ca11e Initial load
duke
parents:
diff changeset
   789
                scanExpr(tree.init);
06bc494ca11e Initial load
duke
parents:
diff changeset
   790
                if (track) letInit(tree.pos(), tree.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   791
            } finally {
06bc494ca11e Initial load
duke
parents:
diff changeset
   792
                lint = lintPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   793
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   794
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   795
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   796
06bc494ca11e Initial load
duke
parents:
diff changeset
   797
    public void visitBlock(JCBlock tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   798
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   799
        scanStats(tree.stats);
06bc494ca11e Initial load
duke
parents:
diff changeset
   800
        nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   801
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   802
06bc494ca11e Initial load
duke
parents:
diff changeset
   803
    public void visitDoLoop(JCDoWhileLoop tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   804
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   805
        boolean prevLoopPassTwo = loopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   806
        pendingExits = new ListBuffer<PendingExit>();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   807
        int prevErrors = log.nerrors;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   808
        do {
06bc494ca11e Initial load
duke
parents:
diff changeset
   809
            Bits uninitsEntry = uninits.dup();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   810
            uninitsEntry.excludeFrom(nextadr);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   811
            scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   812
            alive |= resolveContinues(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   813
            scanCond(tree.cond);
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   814
            if (log.nerrors !=  prevErrors ||
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   815
                loopPassTwo ||
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   816
                uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   817
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   818
            inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   819
            uninits = uninitsEntry.andSet(uninitsWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
   820
            loopPassTwo = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   821
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   822
        } while (true);
06bc494ca11e Initial load
duke
parents:
diff changeset
   823
        loopPassTwo = prevLoopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   824
        inits = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   825
        uninits = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   826
        alive = alive && !tree.cond.type.isTrue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   827
        alive |= resolveBreaks(tree, prevPendingExits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   828
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   829
06bc494ca11e Initial load
duke
parents:
diff changeset
   830
    public void visitWhileLoop(JCWhileLoop tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   831
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   832
        boolean prevLoopPassTwo = loopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   833
        Bits initsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   834
        Bits uninitsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   835
        pendingExits = new ListBuffer<PendingExit>();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   836
        int prevErrors = log.nerrors;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   837
        do {
06bc494ca11e Initial load
duke
parents:
diff changeset
   838
            Bits uninitsEntry = uninits.dup();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   839
            uninitsEntry.excludeFrom(nextadr);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   840
            scanCond(tree.cond);
06bc494ca11e Initial load
duke
parents:
diff changeset
   841
            initsCond = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   842
            uninitsCond = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   843
            inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   844
            uninits = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   845
            alive = !tree.cond.type.isFalse();
06bc494ca11e Initial load
duke
parents:
diff changeset
   846
            scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   847
            alive |= resolveContinues(tree);
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   848
            if (log.nerrors != prevErrors ||
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   849
                loopPassTwo ||
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   850
                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   851
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   852
            uninits = uninitsEntry.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   853
            loopPassTwo = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   854
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   855
        } while (true);
06bc494ca11e Initial load
duke
parents:
diff changeset
   856
        loopPassTwo = prevLoopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   857
        inits = initsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   858
        uninits = uninitsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   859
        alive = resolveBreaks(tree, prevPendingExits) ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   860
            !tree.cond.type.isTrue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   861
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   862
06bc494ca11e Initial load
duke
parents:
diff changeset
   863
    public void visitForLoop(JCForLoop tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   864
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   865
        boolean prevLoopPassTwo = loopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   866
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   867
        scanStats(tree.init);
06bc494ca11e Initial load
duke
parents:
diff changeset
   868
        Bits initsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   869
        Bits uninitsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   870
        pendingExits = new ListBuffer<PendingExit>();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   871
        int prevErrors = log.nerrors;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   872
        do {
06bc494ca11e Initial load
duke
parents:
diff changeset
   873
            Bits uninitsEntry = uninits.dup();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   874
            uninitsEntry.excludeFrom(nextadr);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   875
            if (tree.cond != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   876
                scanCond(tree.cond);
06bc494ca11e Initial load
duke
parents:
diff changeset
   877
                initsCond = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   878
                uninitsCond = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
   879
                inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   880
                uninits = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
   881
                alive = !tree.cond.type.isFalse();
06bc494ca11e Initial load
duke
parents:
diff changeset
   882
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   883
                initsCond = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   884
                initsCond.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   885
                uninitsCond = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   886
                uninitsCond.inclRange(firstadr, nextadr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   887
                alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   888
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   889
            scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   890
            alive |= resolveContinues(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
   891
            scan(tree.step);
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   892
            if (log.nerrors != prevErrors ||
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   893
                loopPassTwo ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   894
                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
06bc494ca11e Initial load
duke
parents:
diff changeset
   895
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   896
            uninits = uninitsEntry.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   897
            loopPassTwo = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   898
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   899
        } while (true);
06bc494ca11e Initial load
duke
parents:
diff changeset
   900
        loopPassTwo = prevLoopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   901
        inits = initsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   902
        uninits = uninitsCond;
06bc494ca11e Initial load
duke
parents:
diff changeset
   903
        alive = resolveBreaks(tree, prevPendingExits) ||
06bc494ca11e Initial load
duke
parents:
diff changeset
   904
            tree.cond != null && !tree.cond.type.isTrue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   905
        nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   906
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   907
06bc494ca11e Initial load
duke
parents:
diff changeset
   908
    public void visitForeachLoop(JCEnhancedForLoop tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   909
        visitVarDef(tree.var);
06bc494ca11e Initial load
duke
parents:
diff changeset
   910
06bc494ca11e Initial load
duke
parents:
diff changeset
   911
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   912
        boolean prevLoopPassTwo = loopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   913
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   914
        scan(tree.expr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   915
        Bits initsStart = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   916
        Bits uninitsStart = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   917
06bc494ca11e Initial load
duke
parents:
diff changeset
   918
        letInit(tree.pos(), tree.var.sym);
06bc494ca11e Initial load
duke
parents:
diff changeset
   919
        pendingExits = new ListBuffer<PendingExit>();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   920
        int prevErrors = log.nerrors;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   921
        do {
06bc494ca11e Initial load
duke
parents:
diff changeset
   922
            Bits uninitsEntry = uninits.dup();
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   923
            uninitsEntry.excludeFrom(nextadr);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   924
            scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   925
            alive |= resolveContinues(tree);
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   926
            if (log.nerrors != prevErrors ||
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   927
                loopPassTwo ||
8627
e60ca990602f 7023703: Valid code doesn't compile
mcimadamore
parents: 8626
diff changeset
   928
                uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   929
                break;
06bc494ca11e Initial load
duke
parents:
diff changeset
   930
            uninits = uninitsEntry.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   931
            loopPassTwo = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   932
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   933
        } while (true);
06bc494ca11e Initial load
duke
parents:
diff changeset
   934
        loopPassTwo = prevLoopPassTwo;
06bc494ca11e Initial load
duke
parents:
diff changeset
   935
        inits = initsStart;
06bc494ca11e Initial load
duke
parents:
diff changeset
   936
        uninits = uninitsStart.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   937
        resolveBreaks(tree, prevPendingExits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   938
        alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   939
        nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   940
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   941
06bc494ca11e Initial load
duke
parents:
diff changeset
   942
    public void visitLabelled(JCLabeledStatement tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   943
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   944
        pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   945
        scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
   946
        alive |= resolveBreaks(tree, prevPendingExits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   947
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   948
06bc494ca11e Initial load
duke
parents:
diff changeset
   949
    public void visitSwitch(JCSwitch tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   950
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   951
        pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
   952
        int nextadrPrev = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   953
        scanExpr(tree.selector);
06bc494ca11e Initial load
duke
parents:
diff changeset
   954
        Bits initsSwitch = inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
   955
        Bits uninitsSwitch = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   956
        boolean hasDefault = false;
06bc494ca11e Initial load
duke
parents:
diff changeset
   957
        for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   958
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   959
            inits = initsSwitch.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
   960
            uninits = uninits.andSet(uninitsSwitch);
06bc494ca11e Initial load
duke
parents:
diff changeset
   961
            JCCase c = l.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   962
            if (c.pat == null)
06bc494ca11e Initial load
duke
parents:
diff changeset
   963
                hasDefault = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   964
            else
06bc494ca11e Initial load
duke
parents:
diff changeset
   965
                scanExpr(c.pat);
06bc494ca11e Initial load
duke
parents:
diff changeset
   966
            scanStats(c.stats);
06bc494ca11e Initial load
duke
parents:
diff changeset
   967
            addVars(c.stats, initsSwitch, uninitsSwitch);
06bc494ca11e Initial load
duke
parents:
diff changeset
   968
            // Warn about fall-through if lint switch fallthrough enabled.
06bc494ca11e Initial load
duke
parents:
diff changeset
   969
            if (!loopPassTwo &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   970
                alive &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   971
                lint.isEnabled(Lint.LintCategory.FALLTHROUGH) &&
06bc494ca11e Initial load
duke
parents:
diff changeset
   972
                c.stats.nonEmpty() && l.tail.nonEmpty())
6151
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
   973
                log.warning(Lint.LintCategory.FALLTHROUGH,
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
   974
                            l.tail.head.pos(),
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   975
                            "possible.fall-through.into.case");
06bc494ca11e Initial load
duke
parents:
diff changeset
   976
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   977
        if (!hasDefault) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   978
            inits.andSet(initsSwitch);
06bc494ca11e Initial load
duke
parents:
diff changeset
   979
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
   980
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   981
        alive |= resolveBreaks(tree, prevPendingExits);
06bc494ca11e Initial load
duke
parents:
diff changeset
   982
        nextadr = nextadrPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
   983
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   984
    // where
06bc494ca11e Initial load
duke
parents:
diff changeset
   985
        /** Add any variables defined in stats to inits and uninits. */
06bc494ca11e Initial load
duke
parents:
diff changeset
   986
        private static void addVars(List<JCStatement> stats, Bits inits,
06bc494ca11e Initial load
duke
parents:
diff changeset
   987
                                    Bits uninits) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   988
            for (;stats.nonEmpty(); stats = stats.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   989
                JCTree stat = stats.head;
06bc494ca11e Initial load
duke
parents:
diff changeset
   990
                if (stat.getTag() == JCTree.VARDEF) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   991
                    int adr = ((JCVariableDecl) stat).sym.adr;
06bc494ca11e Initial load
duke
parents:
diff changeset
   992
                    inits.excl(adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   993
                    uninits.incl(adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
   994
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   995
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   996
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   997
06bc494ca11e Initial load
duke
parents:
diff changeset
   998
    public void visitTry(JCTry tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   999
        List<Type> caughtPrev = caught;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1000
        List<Type> thrownPrev = thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1001
        thrown = List.nil();
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1002
        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1003
            List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
7074
0183c3f9614e 6949587: rename "DisjointType" to "DisjunctType"
jjg
parents: 6594
diff changeset
  1004
                    ((JCTypeDisjunction)l.head.param.vartype).alternatives :
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1005
                    List.of(l.head.param.vartype);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1006
            for (JCExpression ct : subClauses) {
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1007
                caught = chk.incl(ct.type, caught);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1008
            }
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1009
        }
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1010
        ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1011
        Bits uninitsTryPrev = uninitsTry;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1012
        ListBuffer<PendingExit> prevPendingExits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1013
        pendingExits = new ListBuffer<PendingExit>();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1014
        Bits initsTry = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1015
        uninitsTry = uninits.dup();
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1016
        for (JCTree resource : tree.resources) {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1017
            if (resource instanceof JCVariableDecl) {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1018
                JCVariableDecl vdecl = (JCVariableDecl) resource;
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1019
                visitVarDef(vdecl);
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1020
                unrefdResources.enter(vdecl.sym);
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1021
                resourceVarDecls.append(vdecl);
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1022
            } else if (resource instanceof JCExpression) {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1023
                scanExpr((JCExpression) resource);
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1024
            } else {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1025
                throw new AssertionError(tree);  // parser error
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1026
            }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1027
        }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1028
        for (JCTree resource : tree.resources) {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1029
            List<Type> closeableSupertypes = resource.type.isCompound() ?
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1030
                types.interfaces(resource.type).prepend(types.supertype(resource.type)) :
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1031
                List.of(resource.type);
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1032
            for (Type sup : closeableSupertypes) {
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1033
                if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) {
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1034
                    Symbol closeMethod = rs.resolveQualifiedMethod(tree,
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1035
                            attrEnv,
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1036
                            sup,
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1037
                            names.close,
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1038
                            List.<Type>nil(),
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1039
                            List.<Type>nil());
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1040
                    if (closeMethod.kind == MTH) {
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1041
                        for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
8428
1e9935b883cd 7017104: improve error reporting for uncaught/undeclared exceptions from try-with-resources
mcimadamore
parents: 8036
diff changeset
  1042
                            markThrown(resource, t);
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1043
                        }
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1044
                    }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1045
                }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1046
            }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1047
        }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1048
        scanStat(tree.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1049
        List<Type> thrownInTry = thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1050
        thrown = thrownPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1051
        caught = caughtPrev;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1052
        boolean aliveEnd = alive;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1053
        uninitsTry.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1054
        Bits initsEnd = inits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1055
        Bits uninitsEnd = uninits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1056
        int nextadrCatch = nextadr;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1057
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1058
        if (!resourceVarDecls.isEmpty() &&
7211
163fe60f63de 6970016: Clean up ARM/try-with-resources implementation
mcimadamore
parents: 7210
diff changeset
  1059
                lint.isEnabled(Lint.LintCategory.TRY)) {
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1060
            for (JCVariableDecl resVar : resourceVarDecls) {
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1061
                if (unrefdResources.includes(resVar.sym)) {
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1062
                    log.warning(Lint.LintCategory.TRY, resVar.pos(),
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1063
                                "try.resource.not.referenced", resVar.sym);
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1064
                    unrefdResources.remove(resVar.sym);
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1065
                }
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1066
            }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1067
        }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1068
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1069
        List<Type> caughtInTry = List.nil();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1070
        for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1071
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1072
            JCVariableDecl param = l.head.param;
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1073
            List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
7074
0183c3f9614e 6949587: rename "DisjointType" to "DisjunctType"
jjg
parents: 6594
diff changeset
  1074
                    ((JCTypeDisjunction)l.head.param.vartype).alternatives :
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1075
                    List.of(l.head.param.vartype);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1076
            List<Type> ctypes = List.nil();
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1077
            List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1078
            for (JCExpression ct : subClauses) {
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1079
                Type exc = ct.type;
6594
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1080
                if (exc != syms.unknownType) {
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1081
                    ctypes = ctypes.append(exc);
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1082
                    if (types.isSameType(exc, syms.objectType))
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1083
                        continue;
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1084
                    if (chk.subset(exc, caughtInTry)) {
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1085
                        log.error(l.head.pos(),
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1086
                                  "except.already.caught", exc);
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1087
                    } else if (!chk.isUnchecked(l.head.pos(), exc) &&
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1088
                               exc.tsym != syms.throwableType.tsym &&
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1089
                               exc.tsym != syms.exceptionType.tsym &&
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1090
                               !chk.intersects(exc, thrownInTry)) {
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1091
                        log.error(l.head.pos(),
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1092
                                  "except.never.thrown.in.try", exc);
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1093
                    }
d43f068fba19 6970584: Flow.java should be more error-friendly
mcimadamore
parents: 6156
diff changeset
  1094
                    caughtInTry = chk.incl(exc, caughtInTry);
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1095
                }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1096
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1097
            inits = initsTry.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1098
            uninits = uninitsTry.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1099
            scan(param);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1100
            inits.incl(param.sym.adr);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1101
            uninits.excl(param.sym.adr);
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1102
            preciseRethrowTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes));
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1103
            scanStat(l.head.body);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1104
            initsEnd.andSet(inits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1105
            uninitsEnd.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1106
            nextadr = nextadrCatch;
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1107
            preciseRethrowTypes.remove(param.sym);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1108
            aliveEnd |= alive;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1109
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1110
        if (tree.finalizer != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1111
            List<Type> savedThrown = thrown;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1112
            thrown = List.nil();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1113
            inits = initsTry.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1114
            uninits = uninitsTry.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1115
            ListBuffer<PendingExit> exits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1116
            pendingExits = prevPendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1117
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1118
            scanStat(tree.finalizer);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1119
            if (!alive) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1120
                // discard exits and exceptions from try and finally
06bc494ca11e Initial load
duke
parents:
diff changeset
  1121
                thrown = chk.union(thrown, thrownPrev);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1122
                if (!loopPassTwo &&
06bc494ca11e Initial load
duke
parents:
diff changeset
  1123
                    lint.isEnabled(Lint.LintCategory.FINALLY)) {
6151
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
  1124
                    log.warning(Lint.LintCategory.FINALLY,
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
  1125
                            TreeInfo.diagEndPos(tree.finalizer),
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
  1126
                            "finally.cannot.complete");
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1127
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1128
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1129
                thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
06bc494ca11e Initial load
duke
parents:
diff changeset
  1130
                thrown = chk.union(thrown, savedThrown);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1131
                uninits.andSet(uninitsEnd);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1132
                // FIX: this doesn't preserve source order of exits in catch
06bc494ca11e Initial load
duke
parents:
diff changeset
  1133
                // versus finally!
06bc494ca11e Initial load
duke
parents:
diff changeset
  1134
                while (exits.nonEmpty()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1135
                    PendingExit exit = exits.next();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1136
                    if (exit.inits != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1137
                        exit.inits.orSet(inits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1138
                        exit.uninits.andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1139
                    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1140
                    pendingExits.append(exit);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1141
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1142
                inits.orSet(initsEnd);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1143
                alive = aliveEnd;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1144
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1145
        } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1146
            thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
06bc494ca11e Initial load
duke
parents:
diff changeset
  1147
            inits = initsEnd;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1148
            uninits = uninitsEnd;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1149
            alive = aliveEnd;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1150
            ListBuffer<PendingExit> exits = pendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1151
            pendingExits = prevPendingExits;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1152
            while (exits.nonEmpty()) pendingExits.append(exits.next());
06bc494ca11e Initial load
duke
parents:
diff changeset
  1153
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1154
        uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1155
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1156
06bc494ca11e Initial load
duke
parents:
diff changeset
  1157
    public void visitConditional(JCConditional tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1158
        scanCond(tree.cond);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1159
        Bits initsBeforeElse = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1160
        Bits uninitsBeforeElse = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1161
        inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1162
        uninits = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1163
        if (tree.truepart.type.tag == BOOLEAN &&
06bc494ca11e Initial load
duke
parents:
diff changeset
  1164
            tree.falsepart.type.tag == BOOLEAN) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1165
            // if b and c are boolean valued, then
06bc494ca11e Initial load
duke
parents:
diff changeset
  1166
            // v is (un)assigned after a?b:c when true iff
06bc494ca11e Initial load
duke
parents:
diff changeset
  1167
            //    v is (un)assigned after b when true and
06bc494ca11e Initial load
duke
parents:
diff changeset
  1168
            //    v is (un)assigned after c when true
06bc494ca11e Initial load
duke
parents:
diff changeset
  1169
            scanCond(tree.truepart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1170
            Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1171
            Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1172
            Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1173
            Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1174
            inits = initsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1175
            uninits = uninitsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1176
            scanCond(tree.falsepart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1177
            initsWhenTrue.andSet(initsAfterThenWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1178
            initsWhenFalse.andSet(initsAfterThenWhenFalse);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1179
            uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1180
            uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1181
        } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1182
            scanExpr(tree.truepart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1183
            Bits initsAfterThen = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1184
            Bits uninitsAfterThen = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1185
            inits = initsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1186
            uninits = uninitsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1187
            scanExpr(tree.falsepart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1188
            inits.andSet(initsAfterThen);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1189
            uninits.andSet(uninitsAfterThen);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1190
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1191
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1192
06bc494ca11e Initial load
duke
parents:
diff changeset
  1193
    public void visitIf(JCIf tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1194
        scanCond(tree.cond);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1195
        Bits initsBeforeElse = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1196
        Bits uninitsBeforeElse = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1197
        inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1198
        uninits = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1199
        scanStat(tree.thenpart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1200
        if (tree.elsepart != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1201
            boolean aliveAfterThen = alive;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1202
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1203
            Bits initsAfterThen = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1204
            Bits uninitsAfterThen = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1205
            inits = initsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1206
            uninits = uninitsBeforeElse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1207
            scanStat(tree.elsepart);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1208
            inits.andSet(initsAfterThen);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1209
            uninits.andSet(uninitsAfterThen);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1210
            alive = alive | aliveAfterThen;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1211
        } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1212
            inits.andSet(initsBeforeElse);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1213
            uninits.andSet(uninitsBeforeElse);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1214
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1215
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1216
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1217
06bc494ca11e Initial load
duke
parents:
diff changeset
  1218
06bc494ca11e Initial load
duke
parents:
diff changeset
  1219
06bc494ca11e Initial load
duke
parents:
diff changeset
  1220
    public void visitBreak(JCBreak tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1221
        recordExit(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1222
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1223
06bc494ca11e Initial load
duke
parents:
diff changeset
  1224
    public void visitContinue(JCContinue tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1225
        recordExit(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1226
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1227
06bc494ca11e Initial load
duke
parents:
diff changeset
  1228
    public void visitReturn(JCReturn tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1229
        scanExpr(tree.expr);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1230
        // if not initial constructor, should markDead instead of recordExit
06bc494ca11e Initial load
duke
parents:
diff changeset
  1231
        recordExit(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1232
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1233
06bc494ca11e Initial load
duke
parents:
diff changeset
  1234
    public void visitThrow(JCThrow tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1235
        scanExpr(tree.expr);
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1236
        Symbol sym = TreeInfo.symbol(tree.expr);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1237
        if (sym != null &&
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1238
            sym.kind == VAR &&
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1239
            (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 &&
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1240
            preciseRethrowTypes.get(sym) != null &&
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1241
            allowRethrowAnalysis) {
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1242
            for (Type t : preciseRethrowTypes.get(sym)) {
5492
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1243
                markThrown(tree, t);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1244
            }
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1245
        }
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1246
        else {
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1247
            markThrown(tree, tree.expr.type);
515e4b33b335 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch')
mcimadamore
parents: 3149
diff changeset
  1248
        }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1249
        markDead();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1250
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1251
06bc494ca11e Initial load
duke
parents:
diff changeset
  1252
    public void visitApply(JCMethodInvocation tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1253
        scanExpr(tree.meth);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1254
        scanExprs(tree.args);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1255
        for (List<Type> l = tree.meth.type.getThrownTypes(); l.nonEmpty(); l = l.tail)
06bc494ca11e Initial load
duke
parents:
diff changeset
  1256
            markThrown(tree, l.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1257
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1258
06bc494ca11e Initial load
duke
parents:
diff changeset
  1259
    public void visitNewClass(JCNewClass tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1260
        scanExpr(tree.encl);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1261
        scanExprs(tree.args);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1262
       // scan(tree.def);
1791
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1263
        for (List<Type> l = tree.constructorType.getThrownTypes();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1264
             l.nonEmpty();
1791
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1265
             l = l.tail) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1266
            markThrown(tree, l.head);
1791
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1267
        }
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1268
        List<Type> caughtPrev = caught;
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1269
        try {
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1270
            // If the new class expression defines an anonymous class,
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1271
            // analysis of the anonymous constructor may encounter thrown
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1272
            // types which are unsubstituted type variables.
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1273
            // However, since the constructor's actual thrown types have
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1274
            // already been marked as thrown, it is safe to simply include
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1275
            // each of the constructor's formal thrown types in the set of
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1276
            // 'caught/declared to be thrown' types, for the duration of
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1277
            // the class def analysis.
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1278
            if (tree.def != null)
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1279
                for (List<Type> l = tree.constructor.type.getThrownTypes();
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1280
                     l.nonEmpty();
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1281
                     l = l.tail) {
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1282
                    caught = chk.incl(l.head, caught);
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1283
                }
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1284
            scan(tree.def);
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1285
        }
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1286
        finally {
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1287
            caught = caughtPrev;
d378f023c36d 6723444: javac fails to substitute type variables into a constructor's throws clause
mcimadamore
parents: 1264
diff changeset
  1288
        }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1289
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1290
06bc494ca11e Initial load
duke
parents:
diff changeset
  1291
    public void visitNewArray(JCNewArray tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1292
        scanExprs(tree.dims);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1293
        scanExprs(tree.elems);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1294
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1295
06bc494ca11e Initial load
duke
parents:
diff changeset
  1296
    public void visitAssert(JCAssert tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1297
        Bits initsExit = inits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1298
        Bits uninitsExit = uninits.dup();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1299
        scanCond(tree.cond);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1300
        uninitsExit.andSet(uninitsWhenTrue);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1301
        if (tree.detail != null) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1302
            inits = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1303
            uninits = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1304
            scanExpr(tree.detail);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1305
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1306
        inits = initsExit;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1307
        uninits = uninitsExit;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1308
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1309
06bc494ca11e Initial load
duke
parents:
diff changeset
  1310
    public void visitAssign(JCAssign tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1311
        JCTree lhs = TreeInfo.skipParens(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1312
        if (!(lhs instanceof JCIdent)) scanExpr(lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1313
        scanExpr(tree.rhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1314
        letInit(lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1315
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1316
06bc494ca11e Initial load
duke
parents:
diff changeset
  1317
    public void visitAssignop(JCAssignOp tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1318
        scanExpr(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1319
        scanExpr(tree.rhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1320
        letInit(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1321
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1322
06bc494ca11e Initial load
duke
parents:
diff changeset
  1323
    public void visitUnary(JCUnary tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1324
        switch (tree.getTag()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1325
        case JCTree.NOT:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1326
            scanCond(tree.arg);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1327
            Bits t = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1328
            initsWhenFalse = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1329
            initsWhenTrue = t;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1330
            t = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1331
            uninitsWhenFalse = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1332
            uninitsWhenTrue = t;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1333
            break;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1334
        case JCTree.PREINC: case JCTree.POSTINC:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1335
        case JCTree.PREDEC: case JCTree.POSTDEC:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1336
            scanExpr(tree.arg);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1337
            letInit(tree.arg);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1338
            break;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1339
        default:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1340
            scanExpr(tree.arg);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1341
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1342
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1343
06bc494ca11e Initial load
duke
parents:
diff changeset
  1344
    public void visitBinary(JCBinary tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1345
        switch (tree.getTag()) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1346
        case JCTree.AND:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1347
            scanCond(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1348
            Bits initsWhenFalseLeft = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1349
            Bits uninitsWhenFalseLeft = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1350
            inits = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1351
            uninits = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1352
            scanCond(tree.rhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1353
            initsWhenFalse.andSet(initsWhenFalseLeft);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1354
            uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1355
            break;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1356
        case JCTree.OR:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1357
            scanCond(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1358
            Bits initsWhenTrueLeft = initsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1359
            Bits uninitsWhenTrueLeft = uninitsWhenTrue;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1360
            inits = initsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1361
            uninits = uninitsWhenFalse;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1362
            scanCond(tree.rhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1363
            initsWhenTrue.andSet(initsWhenTrueLeft);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1364
            uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1365
            break;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1366
        default:
06bc494ca11e Initial load
duke
parents:
diff changeset
  1367
            scanExpr(tree.lhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1368
            scanExpr(tree.rhs);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1369
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1370
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1371
06bc494ca11e Initial load
duke
parents:
diff changeset
  1372
    public void visitIdent(JCIdent tree) {
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1373
        if (tree.sym.kind == VAR) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1374
            checkInit(tree.pos(), (VarSymbol)tree.sym);
6148
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1375
            referenced(tree.sym);
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1376
        }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1377
    }
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1378
3a8158299c51 6911256: Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler
darcy
parents: 5847
diff changeset
  1379
    void referenced(Symbol sym) {
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1380
        unrefdResources.remove(sym);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1381
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1382
06bc494ca11e Initial load
duke
parents:
diff changeset
  1383
    public void visitTypeCast(JCTypeCast tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1384
        super.visitTypeCast(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1385
        if (!tree.type.isErroneous()
06bc494ca11e Initial load
duke
parents:
diff changeset
  1386
            && lint.isEnabled(Lint.LintCategory.CAST)
3149
0cd06d598d6f 6843077: JSR 308: Annotations on types
jjg
parents: 2212
diff changeset
  1387
            && types.isSameType(tree.expr.type, tree.clazz.type)
7210
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1388
            && !is292targetTypeCast(tree)) {
6151
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
  1389
            log.warning(Lint.LintCategory.CAST,
dd513881e71d 6957438: improve code for generating warning messages containing option names
jjg
parents: 6148
diff changeset
  1390
                    tree.pos(), "redundant.cast", tree.expr.type);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1391
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1392
    }
7210
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1393
    //where
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1394
        private boolean is292targetTypeCast(JCTypeCast tree) {
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1395
            boolean is292targetTypeCast = false;
8036
17b976649c61 6992698: JSR 292: remove support for transient syntax in polymorphic signature calls
mcimadamore
parents: 8032
diff changeset
  1396
            JCExpression expr = TreeInfo.skipParens(tree.expr);
17b976649c61 6992698: JSR 292: remove support for transient syntax in polymorphic signature calls
mcimadamore
parents: 8032
diff changeset
  1397
            if (expr.getTag() == JCTree.APPLY) {
17b976649c61 6992698: JSR 292: remove support for transient syntax in polymorphic signature calls
mcimadamore
parents: 8032
diff changeset
  1398
                JCMethodInvocation apply = (JCMethodInvocation)expr;
7210
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1399
                Symbol sym = TreeInfo.symbol(apply.meth);
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1400
                is292targetTypeCast = sym != null &&
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1401
                    sym.kind == MTH &&
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1402
                    (sym.flags() & POLYMORPHIC_SIGNATURE) != 0;
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1403
            }
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1404
            return is292targetTypeCast;
8dd5f907461e 6999067: cast for invokeExact call gets redundant cast to <type> warnings
mcimadamore
parents: 7203
diff changeset
  1405
        }
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1406
06bc494ca11e Initial load
duke
parents:
diff changeset
  1407
    public void visitTopLevel(JCCompilationUnit tree) {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1408
        // Do nothing for TopLevel since each class is visited individually
06bc494ca11e Initial load
duke
parents:
diff changeset
  1409
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1410
06bc494ca11e Initial load
duke
parents:
diff changeset
  1411
/**************************************************************************
06bc494ca11e Initial load
duke
parents:
diff changeset
  1412
 * main method
06bc494ca11e Initial load
duke
parents:
diff changeset
  1413
 *************************************************************************/
06bc494ca11e Initial load
duke
parents:
diff changeset
  1414
06bc494ca11e Initial load
duke
parents:
diff changeset
  1415
    /** Perform definite assignment/unassignment analysis on a tree.
06bc494ca11e Initial load
duke
parents:
diff changeset
  1416
     */
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1417
    public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1418
        try {
6156
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1419
            attrEnv = env;
e15c221efaac 6970833: Try-with-resource implementation throws an NPE during Flow analysis
mcimadamore
parents: 6151
diff changeset
  1420
            JCTree tree = env.tree;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1421
            this.make = make;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1422
            inits = new Bits();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1423
            uninits = new Bits();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1424
            uninitsTry = new Bits();
06bc494ca11e Initial load
duke
parents:
diff changeset
  1425
            initsWhenTrue = initsWhenFalse =
06bc494ca11e Initial load
duke
parents:
diff changeset
  1426
                uninitsWhenTrue = uninitsWhenFalse = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1427
            if (vars == null)
06bc494ca11e Initial load
duke
parents:
diff changeset
  1428
                vars = new VarSymbol[32];
06bc494ca11e Initial load
duke
parents:
diff changeset
  1429
            else
06bc494ca11e Initial load
duke
parents:
diff changeset
  1430
                for (int i=0; i<vars.length; i++)
06bc494ca11e Initial load
duke
parents:
diff changeset
  1431
                    vars[i] = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1432
            firstadr = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1433
            nextadr = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1434
            pendingExits = new ListBuffer<PendingExit>();
7203
1153590927f7 6993963: Project Coin: Use precise exception analysis for effectively final catch parameters
mcimadamore
parents: 7074
diff changeset
  1435
            preciseRethrowTypes = new HashMap<Symbol, List<Type>>();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1436
            alive = true;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1437
            this.thrown = this.caught = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1438
            this.classDef = null;
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1439
            unrefdResources = new Scope(env.enclClass.sym);
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1440
            scan(tree);
06bc494ca11e Initial load
duke
parents:
diff changeset
  1441
        } finally {
06bc494ca11e Initial load
duke
parents:
diff changeset
  1442
            // note that recursive invocations of this method fail hard
06bc494ca11e Initial load
duke
parents:
diff changeset
  1443
            inits = uninits = uninitsTry = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1444
            initsWhenTrue = initsWhenFalse =
06bc494ca11e Initial load
duke
parents:
diff changeset
  1445
                uninitsWhenTrue = uninitsWhenFalse = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1446
            if (vars != null) for (int i=0; i<vars.length; i++)
06bc494ca11e Initial load
duke
parents:
diff changeset
  1447
                vars[i] = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1448
            firstadr = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1449
            nextadr = 0;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1450
            pendingExits = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1451
            this.make = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1452
            this.thrown = this.caught = null;
06bc494ca11e Initial load
duke
parents:
diff changeset
  1453
            this.classDef = null;
8626
38b24af530bc 7023233: False positive for -Xlint:try with nested try with resources blocks
mcimadamore
parents: 8430
diff changeset
  1454
            unrefdResources = null;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
  1455
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1456
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
  1457
}