1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Mar 15 14:19:00 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Mar 16 11:12:26 2011 +0000 1.3 @@ -190,7 +190,8 @@ 1.4 private final Resolve rs; 1.5 private Env<AttrContext> attrEnv; 1.6 private Lint lint; 1.7 - private final boolean allowRethrowAnalysis; 1.8 + private final boolean allowImprovedRethrowAnalysis; 1.9 + private final boolean allowImprovedCatchAnalysis; 1.10 1.11 public static Flow instance(Context context) { 1.12 Flow instance = context.get(flowKey); 1.13 @@ -209,7 +210,8 @@ 1.14 lint = Lint.instance(context); 1.15 rs = Resolve.instance(context); 1.16 Source source = Source.instance(context); 1.17 - allowRethrowAnalysis = source.allowMulticatch(); 1.18 + allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis(); 1.19 + allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); 1.20 } 1.21 1.22 /** A flag that indicates whether the last statement could 1.23 @@ -1046,7 +1048,9 @@ 1.24 } 1.25 } 1.26 scanStat(tree.body); 1.27 - List<Type> thrownInTry = thrown; 1.28 + List<Type> thrownInTry = allowImprovedCatchAnalysis ? 1.29 + chk.union(thrown, List.of(syms.runtimeExceptionType, syms.errorType)) : 1.30 + thrown; 1.31 thrown = thrownPrev; 1.32 caught = caughtPrev; 1.33 boolean aliveEnd = alive; 1.34 @@ -1081,16 +1085,7 @@ 1.35 ctypes = ctypes.append(exc); 1.36 if (types.isSameType(exc, syms.objectType)) 1.37 continue; 1.38 - if (chk.subset(exc, caughtInTry)) { 1.39 - log.error(l.head.pos(), 1.40 - "except.already.caught", exc); 1.41 - } else if (!chk.isUnchecked(l.head.pos(), exc) && 1.42 - exc.tsym != syms.throwableType.tsym && 1.43 - exc.tsym != syms.exceptionType.tsym && 1.44 - !chk.intersects(exc, thrownInTry)) { 1.45 - log.error(l.head.pos(), 1.46 - "except.never.thrown.in.try", exc); 1.47 - } 1.48 + checkCaughtType(l.head.pos(), exc, thrownInTry, caughtInTry); 1.49 caughtInTry = chk.incl(exc, caughtInTry); 1.50 } 1.51 } 1.52 @@ -1154,6 +1149,29 @@ 1.53 uninitsTry.andSet(uninitsTryPrev).andSet(uninits); 1.54 } 1.55 1.56 + void checkCaughtType(DiagnosticPosition pos, Type exc, List<Type> thrownInTry, List<Type> caughtInTry) { 1.57 + if (chk.subset(exc, caughtInTry)) { 1.58 + log.error(pos, "except.already.caught", exc); 1.59 + } else if (!chk.isUnchecked(pos, exc) && 1.60 + exc.tsym != syms.throwableType.tsym && 1.61 + exc.tsym != syms.exceptionType.tsym && 1.62 + !chk.intersects(exc, thrownInTry)) { 1.63 + log.error(pos, "except.never.thrown.in.try", exc); 1.64 + } else if (allowImprovedCatchAnalysis) { 1.65 + List<Type> catchableThrownTypes = chk.intersect(List.of(exc), thrownInTry); 1.66 + // 'catchableThrownTypes' cannnot possibly be empty - if 'exc' was an 1.67 + // unchecked exception, the result list would not be empty, as the augmented 1.68 + // thrown set includes { RuntimeException, Error }; if 'exc' was a checked 1.69 + // exception, that would have been covered in the branch above 1.70 + if (chk.diff(catchableThrownTypes, caughtInTry).isEmpty()) { 1.71 + String key = catchableThrownTypes.length() == 1 ? 1.72 + "unreachable.catch" : 1.73 + "unreachable.catch.1"; 1.74 + log.warning(pos, key, catchableThrownTypes); 1.75 + } 1.76 + } 1.77 + } 1.78 + 1.79 public void visitConditional(JCConditional tree) { 1.80 scanCond(tree.cond); 1.81 Bits initsBeforeElse = initsWhenFalse; 1.82 @@ -1238,7 +1256,7 @@ 1.83 sym.kind == VAR && 1.84 (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0 && 1.85 preciseRethrowTypes.get(sym) != null && 1.86 - allowRethrowAnalysis) { 1.87 + allowImprovedRethrowAnalysis) { 1.88 for (Type t : preciseRethrowTypes.get(sym)) { 1.89 markThrown(tree, t); 1.90 }