Scala Programming Language
  1. Scala Programming Language
  2. SI-4283

Erasure and inheritance collude: compiler attempts cast to an inaccessible class

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: Scala 2.10.0-M3
    • Component/s: Misc Compiler
    • Labels:
      None

      Description

      Because of erasure, the compiler needs to insert casts to get the expected type. The "expected type" logic seems to depend on the use of the type, rather than the statically-known type.

      In this example, since the class `AbstractFoo` is the one that defines the field `t`, the compiler thinks it needs to cast the result of `ScalaBipp.make.get` to `AbstractFoo` in order to access `t`. This is incorrect behavior, since `AbstractFoo` might in fact be inaccessible in the scope in which the cast is applied.

      === What steps will reproduce the problem (please be specific and use wikiformatting)? ===
      `test/AbstractFoo.java`

      package test;
      
      /* package private */ class AbstractFoo {
        public int t;
      }
      

      `ScalaBipp.scala`

      package test
      
      class ScalaBipp extends AbstractFoo {
        def make: Option[ScalaBipp] = Option(this)
      }
      

      `test.scala`

      package other
      
      object IllegalAccess {
          val x = (new test.ScalaBipp).make.get.t // java.lang.IllegalAccessError: tried to access class test.AbstractFoo from class other.IllegalAccess$$
      }
      

      === What is the expected behavior? ===
      No runtime failure.

      === What do you see instead? ===
      Runtime exception accessing class `test.AbstractFoo` and the following bytecode:

      javap -c other.IllegalAccess$$
      
         0:	new	SI-16; //class test/ScalaBipp
         3:	dup
         4:	invokespecial	SI-18; //Method test/ScalaBipp."<init>":()V
         7:	invokevirtual	SI-22; //Method test/ScalaBipp.make:()Lscala/Option;
         10:	invokevirtual	SI-28; //Method scala/Option.get:()Ljava/lang/Object;
         13:	checkcast	SI-30; //class test/AbstractFoo
         16:	getfield	SI-34; //Field test/AbstractFoo.t:I
         19:	istore_2
         20:	return
      

      === Additional information ===
      The checkcast on line 13 is wrong. It should cast to `ScalaBipp` rather than `AbstractFoo`.

      === Scala version ===
      trunk r24156

        Activity

        Hide
        Martin Odersky added a comment -

        I fixed now my part of this in r24749 by inserting another cast pre-emptively when an IllegalAccess error is possible in an erasure-inserted cast. There's still a problem in that emitted getField and putField instructions get the owner of the accessed field as prefix, instead of the static type of the qualifier. invoke operations are OK. All of these are demonstrated in test t2383, which is in test/pending/run.

        Show
        Martin Odersky added a comment - I fixed now my part of this in r24749 by inserting another cast pre-emptively when an IllegalAccess error is possible in an erasure-inserted cast. There's still a problem in that emitted getField and putField instructions get the owner of the accessed field as prefix, instead of the static type of the qualifier. invoke operations are OK. All of these are demonstrated in test t2383, which is in test/pending/run.
        Hide
        Iulian Dragos added a comment -

        (In r24751) Closes SI-4283. no review.

        Show
        Iulian Dragos added a comment - (In r24751) Closes SI-4283 . no review.
        Hide
        Iulian Dragos added a comment -

        (In r24758) Revert "Closes SI-4283. no review." because of failing tests.

        Show
        Iulian Dragos added a comment - (In r24758) Revert "Closes SI-4283 . no review." because of failing tests.
        Hide
        Iulian Dragos added a comment -

        (In r24762) This time, fixed SI-4283. no review.

        Show
        Iulian Dragos added a comment - (In r24762) This time, fixed SI-4283 . no review.
        Hide
        Paul Phillips added a comment -

        Note that r24749 caused SI-5162.

        Show
        Paul Phillips added a comment - Note that r24749 caused SI-5162 .

          People

          • Assignee:
            Iulian Dragos
            Reporter:
            Josh Suereth
            TracCC:
            Daniel Sobral, Ismael Juma, Johannes Rudolph, Paul Phillips, Seth Tisue
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development