Optimizing an expression of the form:
(a() || true)
to true is wrong if a() can raise an exception. Related JLS sections: 15.23
(definition of ||), 14.8 (definition of if stmt), 15.5 (definition of
abrupt completion of evaluation -- see also example on top of page 307).
The following program should not produce any output, but does:
public class Test {
public static void main(String args[]) throws Exception {
if (foo() || true) {
System.out.println("You shouldn't see this line");
}
}
public static boolean foo() throws Exception {
throw new Exception();
}
}
"javap -c Test" clearly shows that javac just short-circuited the call to
foo() in main() and called println directly. See ---> lines.
$ javap -c Test
Compiled from Test.java
public synchronized class Test extends java.lang.Object
/* ACC_SUPER bit set */
{
public static void main(java.lang.String[]);
public static boolean foo();
public Test();
}
Method void main(java.lang.String[])
---> 0 getstatic #9 <Field java.io.PrintStream out>
---> 3 ldc #1 <String "You shouldn't see this line">
---> 5 invokevirtual #10 <Method void println(java.lang.String)>
8 return
Method boolean foo()
0 new #4 <Class java.lang.Exception>
3 dup
4 invokespecial #7 <Method java.lang.Exception()>
7 athrow
Method Test()
0 aload_0
1 invokespecial #8 <Method java.lang.Object()>
4 return
(a() || true)
to true is wrong if a() can raise an exception. Related JLS sections: 15.23
(definition of ||), 14.8 (definition of if stmt), 15.5 (definition of
abrupt completion of evaluation -- see also example on top of page 307).
The following program should not produce any output, but does:
public class Test {
public static void main(String args[]) throws Exception {
if (foo() || true) {
System.out.println("You shouldn't see this line");
}
}
public static boolean foo() throws Exception {
throw new Exception();
}
}
"javap -c Test" clearly shows that javac just short-circuited the call to
foo() in main() and called println directly. See ---> lines.
$ javap -c Test
Compiled from Test.java
public synchronized class Test extends java.lang.Object
/* ACC_SUPER bit set */
{
public static void main(java.lang.String[]);
public static boolean foo();
public Test();
}
Method void main(java.lang.String[])
---> 0 getstatic #9 <Field java.io.PrintStream out>
---> 3 ldc #1 <String "You shouldn't see this line">
---> 5 invokevirtual #10 <Method void println(java.lang.String)>
8 return
Method boolean foo()
0 new #4 <Class java.lang.Exception>
3 dup
4 invokespecial #7 <Method java.lang.Exception()>
7 athrow
Method Test()
0 aload_0
1 invokespecial #8 <Method java.lang.Object()>
4 return
- duplicates
-
JDK-4068183 WRONG implementation of condition evaluation w/ explicit true
- Closed
-
JDK-4017779 compiler may optimize away functions with side effects in if statements
- Closed
-
JDK-4329450 Incorrect Optimization of && and || being performed
- Closed