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

Print this page




 248      */
 249     JCClassDecl classDef;
 250 
 251     /** The first variable sequence number in this class definition.
 252      */
 253     int firstadr;
 254 
 255     /** The next available variable sequence number.
 256      */
 257     int nextadr;
 258 
 259     /** The list of possibly thrown declarable exceptions.
 260      */
 261     List<Type> thrown;
 262 
 263     /** The list of exceptions that are either caught or declared to be
 264      *  thrown.
 265      */
 266     List<Type> caught;
 267 




 268     /** Set when processing a loop body the second time for DU analysis. */
 269     boolean loopPassTwo = false;
 270 
 271     /*-------------------- Environments ----------------------*/
 272 
 273     /** A pending exit.  These are the statements return, break, and
 274      *  continue.  In addition, exception-throwing expressions or
 275      *  statements are put here when not known to be caught.  This
 276      *  will typically result in an error unless it is within a
 277      *  try-finally whose finally block cannot complete normally.
 278      */
 279     static class PendingExit {
 280         JCTree tree;
 281         Bits inits;
 282         Bits uninits;
 283         Type thrown;
 284         PendingExit(JCTree tree, Bits inits, Bits uninits) {
 285             this.tree = tree;
 286             this.inits = inits.dup();
 287             this.uninits = uninits.dup();


 944             alive = true;
 945         }
 946         alive |= resolveBreaks(tree, prevPendingExits);
 947         nextadr = nextadrPrev;
 948     }
 949     // where
 950         /** Add any variables defined in stats to inits and uninits. */
 951         private static void addVars(List<JCStatement> stats, Bits inits,
 952                                     Bits uninits) {
 953             for (;stats.nonEmpty(); stats = stats.tail) {
 954                 JCTree stat = stats.head;
 955                 if (stat.getTag() == JCTree.VARDEF) {
 956                     int adr = ((JCVariableDecl) stat).sym.adr;
 957                     inits.excl(adr);
 958                     uninits.incl(adr);
 959                 }
 960             }
 961         }
 962 
 963     public void visitTry(JCTry tree) {










 964         List<Type> caughtPrev = caught;
 965         List<Type> thrownPrev = thrown;
 966         thrown = List.nil();
 967         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 968             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 969                     ((JCTypeDisjoint)l.head.param.vartype).components :
 970                     List.of(l.head.param.vartype);
 971             for (JCExpression ct : subClauses) {
 972                 caught = chk.incl(ct.type, caught);
 973             }
 974         }
 975         Bits uninitsTryPrev = uninitsTry;
 976         ListBuffer<PendingExit> prevPendingExits = pendingExits;
 977         pendingExits = new ListBuffer<PendingExit>();
 978         Bits initsTry = inits.dup();
 979         uninitsTry = uninits.dup();








 980         scanStat(tree.body);
 981         List<Type> thrownInTry = thrown;
 982         thrown = thrownPrev;
 983         caught = caughtPrev;
 984         boolean aliveEnd = alive;
 985         uninitsTry.andSet(uninits);
 986         Bits initsEnd = inits;
 987         Bits uninitsEnd = uninits;
 988         int nextadrCatch = nextadr;
 989 












 990         List<Type> caughtInTry = List.nil();
 991         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 992             alive = true;
 993             JCVariableDecl param = l.head.param;
 994             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 995                     ((JCTypeDisjoint)l.head.param.vartype).components :
 996                     List.of(l.head.param.vartype);
 997             List<Type> ctypes = List.nil();
 998             List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
 999             for (JCExpression ct : subClauses) {
1000                 Type exc = ct.type;
1001                 ctypes = ctypes.append(exc);
1002                 if (types.isSameType(exc, syms.objectType))
1003                     continue;
1004                 if (chk.subset(exc, caughtInTry)) {
1005                     log.error(l.head.pos(),
1006                               "except.already.caught", exc);
1007                 } else if (!chk.isUnchecked(l.head.pos(), exc) &&
1008                            exc.tsym != syms.throwableType.tsym &&
1009                            exc.tsym != syms.exceptionType.tsym &&


1276             Bits initsWhenTrueLeft = initsWhenTrue;
1277             Bits uninitsWhenTrueLeft = uninitsWhenTrue;
1278             inits = initsWhenFalse;
1279             uninits = uninitsWhenFalse;
1280             scanCond(tree.rhs);
1281             initsWhenTrue.andSet(initsWhenTrueLeft);
1282             uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
1283             break;
1284         default:
1285             scanExpr(tree.lhs);
1286             scanExpr(tree.rhs);
1287         }
1288     }
1289 
1290     public void visitAnnotatedType(JCAnnotatedType tree) {
1291         // annotations don't get scanned
1292         tree.underlyingType.accept(this);
1293     }
1294 
1295     public void visitIdent(JCIdent tree) {
1296         if (tree.sym.kind == VAR)
1297             checkInit(tree.pos(), (VarSymbol)tree.sym);












1298     }
1299 
1300     public void visitTypeCast(JCTypeCast tree) {
1301         super.visitTypeCast(tree);
1302         if (!tree.type.isErroneous()
1303             && lint.isEnabled(Lint.LintCategory.CAST)
1304             && types.isSameType(tree.expr.type, tree.clazz.type)
1305             && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
1306             log.warning(tree.pos(), "redundant.cast", tree.expr.type);
1307         }
1308     }
1309 
1310     public void visitTopLevel(JCCompilationUnit tree) {
1311         // Do nothing for TopLevel since each class is visited individually
1312     }
1313 
1314 /**************************************************************************
1315  * utility methods for ignoring type-annotated casts lint checking
1316  *************************************************************************/
1317     private static final boolean ignoreAnnotatedCasts = true;




 248      */
 249     JCClassDecl classDef;
 250 
 251     /** The first variable sequence number in this class definition.
 252      */
 253     int firstadr;
 254 
 255     /** The next available variable sequence number.
 256      */
 257     int nextadr;
 258 
 259     /** The list of possibly thrown declarable exceptions.
 260      */
 261     List<Type> thrown;
 262 
 263     /** The list of exceptions that are either caught or declared to be
 264      *  thrown.
 265      */
 266     List<Type> caught;
 267 
 268     /** The list of unreferenced automatic resources.
 269      */
 270     List<Symbol> unrefdResources;
 271 
 272     /** Set when processing a loop body the second time for DU analysis. */
 273     boolean loopPassTwo = false;
 274 
 275     /*-------------------- Environments ----------------------*/
 276 
 277     /** A pending exit.  These are the statements return, break, and
 278      *  continue.  In addition, exception-throwing expressions or
 279      *  statements are put here when not known to be caught.  This
 280      *  will typically result in an error unless it is within a
 281      *  try-finally whose finally block cannot complete normally.
 282      */
 283     static class PendingExit {
 284         JCTree tree;
 285         Bits inits;
 286         Bits uninits;
 287         Type thrown;
 288         PendingExit(JCTree tree, Bits inits, Bits uninits) {
 289             this.tree = tree;
 290             this.inits = inits.dup();
 291             this.uninits = uninits.dup();


 948             alive = true;
 949         }
 950         alive |= resolveBreaks(tree, prevPendingExits);
 951         nextadr = nextadrPrev;
 952     }
 953     // where
 954         /** Add any variables defined in stats to inits and uninits. */
 955         private static void addVars(List<JCStatement> stats, Bits inits,
 956                                     Bits uninits) {
 957             for (;stats.nonEmpty(); stats = stats.tail) {
 958                 JCTree stat = stats.head;
 959                 if (stat.getTag() == JCTree.VARDEF) {
 960                     int adr = ((JCVariableDecl) stat).sym.adr;
 961                     inits.excl(adr);
 962                     uninits.incl(adr);
 963                 }
 964             }
 965         }
 966 
 967     public void visitTry(JCTry tree) {
 968         unrefdResources = List.nil();
 969         for (JCTree resource : tree.resources) {
 970             if (resource instanceof JCVariableDecl) {
 971                 visitVarDef((JCVariableDecl) resource);
 972             } else if (resource instanceof JCExpression) {
 973                 scanExpr((JCExpression) resource);
 974             } else {
 975                 throw new AssertionError(tree);  // parser error
 976             }
 977         }
 978         List<Type> caughtPrev = caught;
 979         List<Type> thrownPrev = thrown;
 980         thrown = List.nil();
 981         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 982             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 983                     ((JCTypeDisjoint)l.head.param.vartype).components :
 984                     List.of(l.head.param.vartype);
 985             for (JCExpression ct : subClauses) {
 986                 caught = chk.incl(ct.type, caught);
 987             }
 988         }
 989         Bits uninitsTryPrev = uninitsTry;
 990         ListBuffer<PendingExit> prevPendingExits = pendingExits;
 991         pendingExits = new ListBuffer<PendingExit>();
 992         Bits initsTry = inits.dup();
 993         uninitsTry = uninits.dup();
 994         for (JCTree resource : tree.resources) {
 995             MethodSymbol topCloseMethod = (MethodSymbol)syms.autoCloseableType.tsym.members().lookup(names.close).sym;
 996             MethodSymbol closeMethod = types.implementation(topCloseMethod, resource.type.tsym, types, true);
 997 
 998             for (Type thrownType : closeMethod.getThrownTypes()) {
 999                 markThrown(tree.body, thrownType);
1000             }
1001         }
1002         scanStat(tree.body);
1003         List<Type> thrownInTry = thrown;
1004         thrown = thrownPrev;
1005         caught = caughtPrev;
1006         boolean aliveEnd = alive;
1007         uninitsTry.andSet(uninits);
1008         Bits initsEnd = inits;
1009         Bits uninitsEnd = uninits;
1010         int nextadrCatch = nextadr;
1011 
1012         if (unrefdResources.nonEmpty()) {
1013             for (List<JCTree> l = tree.resources; l.nonEmpty(); l = l.tail) {
1014                 if (l.head instanceof JCVariableDecl) {
1015                     JCVariableDecl v = (JCVariableDecl) l.head;
1016                     if (unrefdResources.contains(v.sym)) {
1017                         log.warning(v.pos(),
1018                                     "automatic.resource.not.referenced", v.sym);
1019                     }
1020                 }
1021             }
1022         }
1023 
1024         List<Type> caughtInTry = List.nil();
1025         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1026             alive = true;
1027             JCVariableDecl param = l.head.param;
1028             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
1029                     ((JCTypeDisjoint)l.head.param.vartype).components :
1030                     List.of(l.head.param.vartype);
1031             List<Type> ctypes = List.nil();
1032             List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
1033             for (JCExpression ct : subClauses) {
1034                 Type exc = ct.type;
1035                 ctypes = ctypes.append(exc);
1036                 if (types.isSameType(exc, syms.objectType))
1037                     continue;
1038                 if (chk.subset(exc, caughtInTry)) {
1039                     log.error(l.head.pos(),
1040                               "except.already.caught", exc);
1041                 } else if (!chk.isUnchecked(l.head.pos(), exc) &&
1042                            exc.tsym != syms.throwableType.tsym &&
1043                            exc.tsym != syms.exceptionType.tsym &&


1310             Bits initsWhenTrueLeft = initsWhenTrue;
1311             Bits uninitsWhenTrueLeft = uninitsWhenTrue;
1312             inits = initsWhenFalse;
1313             uninits = uninitsWhenFalse;
1314             scanCond(tree.rhs);
1315             initsWhenTrue.andSet(initsWhenTrueLeft);
1316             uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
1317             break;
1318         default:
1319             scanExpr(tree.lhs);
1320             scanExpr(tree.rhs);
1321         }
1322     }
1323 
1324     public void visitAnnotatedType(JCAnnotatedType tree) {
1325         // annotations don't get scanned
1326         tree.underlyingType.accept(this);
1327     }
1328 
1329     public void visitIdent(JCIdent tree) {
1330         if (tree.sym.kind == VAR) {
1331             checkInit(tree.pos(), (VarSymbol)tree.sym);
1332             referenced(tree.sym);
1333         }
1334     }
1335 
1336     void referenced(Symbol sym) {
1337         if (unrefdResources != null && unrefdResources.contains(sym)) {
1338             ListBuffer<Symbol> lb = new ListBuffer<Symbol>();
1339             for (List<Symbol> l = unrefdResources; l.nonEmpty(); l = l.tail)
1340                 if (l.head != sym)
1341                     lb.add(l.head);
1342             unrefdResources = lb.toList();
1343         }
1344     }
1345 
1346     public void visitTypeCast(JCTypeCast tree) {
1347         super.visitTypeCast(tree);
1348         if (!tree.type.isErroneous()
1349             && lint.isEnabled(Lint.LintCategory.CAST)
1350             && types.isSameType(tree.expr.type, tree.clazz.type)
1351             && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
1352             log.warning(tree.pos(), "redundant.cast", tree.expr.type);
1353         }
1354     }
1355 
1356     public void visitTopLevel(JCCompilationUnit tree) {
1357         // Do nothing for TopLevel since each class is visited individually
1358     }
1359 
1360 /**************************************************************************
1361  * utility methods for ignoring type-annotated casts lint checking
1362  *************************************************************************/
1363     private static final boolean ignoreAnnotatedCasts = true;