RFR (14): JDK-8236670: Conflicting bindings accepted in some cases
Jan Lahoda
jan.lahoda at oracle.com
Mon Jan 13 12:42:18 UTC 2020
Hi,
Tagir reported a problem where javac accepts a program with conflicting
bindings, like (simplified):
static void test(Object o1, Object o2) {
boolean b = o1 instanceof String s && !(o2 instanceof String s));
}
There are two problem here:
-in the right-hand side of the conditional and, "s" is already in scope,
but no error reported. This is because in Check, while checking clashes,
clashes between binding variables are ignored, and expected to be
reported in MatchBindingsComputer - but here, MatchBindingsComputer does
not see the conflict when computing the binding variables for the
expression. The proposed fix is to let the error be reported in Check,
with some checks to avoid duplicate errors from MatchBindingsComputer.
As a side effect, this should provide better error positions in some
(although not all) cases, consider:
static void test(Object o1, Object o2) {
if (o1 instanceof String s && (o2 instanceof String s));
}
before:
/tmp/T.java:3: error: illegal attempt to redefine an existing match binding
if (o1 instanceof String s && (o2 instanceof String s));
^
with the patch:
/tmp/T.java:3: error: illegal attempt to redefine an existing match binding
if (o1 instanceof String s && (o2 instanceof String s));
^
-the second problem is more intricate - some bindings consistency
constraints are curently only checked when match bindings are evaluated
for a whole expression, like e.g.:
if (!(o1 instanceof String s) && !(o2 instanceof String s)) {}
this is illegal per JLS 6.3.1.1 ("It is a compile-time error if a
pattern variable is both introduced by a when false, and by b when
false.") The constraint is checked when the expression is e.g. a
condition for an if statement, but not when the expression is e.g. an
initializer to a variable:
boolean b = !(o1 instanceof String s) && !(o2 instanceof String s);
- this yields no error, as the expression is never checked by the
MatchBindingComputer as a whole. We could either run the
MatchBindingComputer on every non-conditional expression, but seems a
nicer way is to build the current match bindings while attributing the
expressions (i.e. keeping the match bindings in Attr and enhance/check
them as it goes up the AST).
The current proposed patch is here:
http://cr.openjdk.java.net/~jlahoda/8236670/webrev.00/
JBS: https://bugs.openjdk.java.net/browse/JDK-8236670
What do you think?
Thanks,
Jan
More information about the compiler-dev
mailing list