United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6491592 Compiler crashes on assignment operator
JDK-6491592 : Compiler crashes on assignment operator

Details
Type:
Bug
Submit Date:
2006-11-09
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
generic
Sub-Component:
javac
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports

Sub Tasks

Description
class Test {
    public static void main(String... args) {
        Object o = null;  // o can be any reference type except String
        o += null;
    }
}

java.lang.ArrayIndexOutOfBoundsException: 277
        at com.sun.tools.javac.jvm.Code.mnem(Code.java:1953)
        at com.sun.tools.javac.jvm.Code.emitop0(Code.java:841)
        at com.sun.tools.javac.jvm.Gen.completeBinop(Gen.java:1992)
        at com.sun.tools.javac.jvm.Gen.visitAssignop(Gen.java:1766)
        at com.sun.tools.javac.tree.JCTree$JCAssignOp.accept(JCTree.java:1367)
        at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:813)
        at com.sun.tools.javac.jvm.Gen.visitExec(Gen.java:1570)
        at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1074)
        at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:660)
        at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:695)
        at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:681)
        at com.sun.tools.javac.jvm.Gen.genStats(Gen.java:732)
        at com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:985)
        at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:739)
        at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:660)
        at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:695)
        at com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:918)
        at com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:854)
        at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:639)
        at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:660)
        at com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2163)
        at com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:617)
        at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1289)
        at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1259)
        at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
        at com.sun.tools.javac.main.Main.compile(Main.java:353)
        at com.sun.tools.javac.main.Main.compile(Main.java:279)
        at com.sun.tools.javac.main.Main.compile(Main.java:270)
        at com.sun.tools.javac.Main.compile(Main.java:69)
        at com.sun.tools.javac.Main.main(Main.java:54)

                                    

Comments
EVALUATION

JLS3 15.26.2 Compound Assignment Operators
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.26.2

"A compound assignment expression of the form E1 op= E2 is equivalent
to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1
is evaluated only once."

JLS3 15.18 Additive Operators
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18

"If the type of either operand of a + operator is String, then the
operation is string concatenation.

Otherwise, the type of each of the operands of the + operator must be
a type that is convertible (??5.1.8) to a primitive numeric type, or a
compile-time error occurs."

??5.1.8 is unboxing conversion.

***

Since ??15.26.2 states that o += null is equivalent to o = o + null we
examine the rules in ??15.18 which clearly states that this is a compile-
time error.
                                     
2006-11-09
EVALUATION

The error will look like this:

Test.java:4: operator + cannot be applied to java.lang.Object,<nulltype>
        o += null;
          ^
1 error
                                     
2006-11-09
SUGGESTED FIX

Index: j2se/src/share/classes/com/sun/tools/javac/comp/Attr.java
--- /tmp/geta23225	2006-11-08 20:16:57.000000000 -0800
+++ /tmp/getb23225	2006-11-08 20:16:57.000000000 -0800
@@ -63,7 +63,6 @@
     final TreeMaker make;
     final ConstFold cfolder;
     final Enter enter;
-    final TreeInfo treeinfo;
     final Target target;
     final Types types;
     final Annotate annotate;
@@ -87,7 +86,6 @@
         make = TreeMaker.instance(context);
         enter = Enter.instance(context);
         cfolder = ConstFold.instance(context);
-        treeinfo = TreeInfo.instance(context);
         target = Target.instance(context);
         types = Types.instance(context);
         annotate = Annotate.instance(context);
@@ -1558,6 +1556,11 @@
             owntype, operand);
 
         if (operator.kind == MTH) {
+            chk.checkOperator(tree.pos(),
+                              (OperatorSymbol)operator,
+                              tree.tag - JCTree.ASGOffset,
+                              owntype,
+                              operand);
             if (types.isSameType(operator.type.getReturnType(), syms.stringType)) {
                 // String assignment; make sure the lhs is a string
                 chk.checkType(tree.lhs.pos(),
@@ -1622,14 +1625,11 @@
         Type owntype = syms.errType;
         if (operator.kind == MTH) {
             owntype = operator.type.getReturnType();
-            int opc = ((OperatorSymbol)operator).opcode;
-
-            if (opc == ByteCodes.error) {
-                log.error(tree.lhs.pos(),
-                          "operator.cant.be.applied",
-                          treeinfo.operatorName(tree.tag),
-                          left + "," + right);
-            }
+            int opc = chk.checkOperator(tree.lhs.pos(),
+                                        (OperatorSymbol)operator,
+                                        tree.tag,
+                                        left,
+                                        right);
 
             // If both arguments are constants, fold them.
             if (left.constValue() != null && right.constValue() != null) {
                                     
2006-11-09
SUGGESTED FIX

Index: j2se/src/share/classes/com/sun/tools/javac/comp/Check.java
--- /tmp/geta23218	2006-11-08 20:16:25.000000000 -0800
+++ /tmp/getb23218	2006-11-08 20:16:26.000000000 -0800
@@ -50,6 +50,7 @@
     private final Source source;
     private final Types types;
     private final boolean skipAnnotations;
+    private final TreeInfo treeinfo;
 
     // The set of lint options currently in effect. It is initialized
     // from the context, and then is set/reset as needed by Attr as it 
@@ -75,6 +76,7 @@
 	target = Target.instance(context);
         source = Source.instance(context);
 	lint = Lint.instance(context);
+        treeinfo = TreeInfo.instance(context);
 
 	Source source = Source.instance(context);
 	allowGenerics = source.allowGenerics();
@@ -1912,6 +1914,30 @@
  **************************************************************************/
 
     /**
+     * Return the opcode of the operator but emit an error if it is an
+     * error.
+     * @param pos        position for error reporting.
+     * @param operator   an operator
+     * @param tag        a tree tag
+     * @param left       type of left hand side
+     * @param right      type of right hand side
+     */
+    int checkOperator(DiagnosticPosition pos,
+                       OperatorSymbol operator,
+                       int tag,
+                       Type left,
+                       Type right) {
+        if (operator.opcode == ByteCodes.error) {
+            log.error(pos,
+                      "operator.cant.be.applied",
+                      treeinfo.operatorName(tag),
+                      left + "," + right);
+        }
+        return operator.opcode;
+    }
+
+
+    /**
      *  Check for division by integer constant zero
      *	@param pos	     Position for error reporting.
      *	@param operator      The operator for the expression
                                     
2006-11-09
SUGGESTED FIX

Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=6491592
See also attachment 6491592.tar.gz.
                                     
2006-11-09



Hardware and Software, Engineered to Work Together