Re: [Jastadd] [bug report] problems in ClassInstanceExpr.typeCheckEnclosingInstance() in Java1.4Frontend/TypeCheck.jrag

From: Na, Hyunik <hina_at_kaist.ac.kr>
Date: Fri, 1 Jun 2012 13:41:31 +0900

I realized that, only with the modification I suggested, the compiler
rejects the following correct program:

 

-=-=-=

public class C004100 {

  public static void main( String [] args ) {

    new C004100().test();

  }

 

  void test() {

    new Inner2().m();

  }

 

  class Inner {}

 

  class Inner2 extends C004100 {

    void m() { new Inner(); }

  }

}

-=-=-=

 

It seems that the 'instanceOf' in the replacing while-block should also be
replaced with reference comparison (or identityConversionTo).

That is, it should be

 

-=-=-=

public void ClassInstanceExpr.typeCheckEnclosingInstance() {

    .

    .

      else {

          TypeDecl nest = hostType();

          /*

          while(nest != null && !nest.instanceOf(C.enclosingType()))

            nest = nest.enclosingType();

           replaced with the following while-block */

          //while(nest != null && !nest.instanceOf(C.enclosingType())) {
again, replaced with the following line

          while(nest != null && nest != C.enclosingType()) {

            if ( nest.isStatic() || nest.inStaticContext() ) {

              nest = unknownType();

              break;

            }

            nest = nest.enclosingType();

          }

 

          enclosing = nest == null ? unknownType() : nest;

    .

    .

-=-=-=

 

Please check this.

 

- Hyunik

 

 

From: jastadd-bounces_at_cs.lth.se [mailto:jastadd-bounces_at_cs.lth.se] On Behalf
Of Na, Hyunik
Sent: Friday, June 01, 2012 1:07 PM
To: jastadd_at_cs.lth.se
Subject: [Jastadd] [bug report] problems in
ClassInstanceExpr.typeCheckEnclosingInstance() in
Java1.4Frontend/TypeCheck.jrag

 

Hello JastAddJ developers,

 

Compiling the following to codes with JastAddJ JavaCompiler (rev. 9267)
produces no error messages.

 

-=-=-= E004100.java

public class E004100 {

  public static void main( String [] args ) {

    new StaticNested().m();

  }

 

  class Inner {}

 

  static class StaticNested {

    void m() { new Inner(); }

  }

}

-=-=-=

 

-=-=-= E004101.java

public class E004101 {

  public static void main( String [] args ) {

 }

 

  class Inner {}

 

  static {

    class StaticNested {

      void m() { new Inner(); }

    }

    new StaticNested().m();

  }

}

-=-=-=

 

But, running the generated classes produces the following run-time error
messages:

 

-=-=-=

hina_at_ns:~/myWork/test$ java E004100

Exception in thread "main" java.lang.NoSuchFieldError: this$0

        at E004100$StaticNested.m(E004100.java:9)

        at E004100.main(E004100.java:3)

hina_at_ns:~/myWork/test$ java E004101

Exception in thread "main" java.lang.NoSuchFieldError: this$0

        at E004101$1StaticNested.m(E004101.java:9)

        at E004101.<clinit>(E004101.java:11)

Could not find the main class: E004101. Program will exit.

-=-=-=

 

The problem is, as you can easily seen, JastAddJ typechecker does not reject
the cases where

an inner class is instantiated within a static context (but, the class
instance expression itself is not in a static context).

 

The cause of this problem seems to be in
ClassInstanceExpr.typeCheckEnclosingInstance() in
Java1.4Frontend/TypeCheck.jrag.

The following code shows how I modified the code:

 

-=-=-=

public void ClassInstanceExpr.typeCheckEnclosingInstance() {

  .

else if(C.isMemberType()) {

      if(!isQualified()) {

        if(noEnclosingInstance()) {

          error("No enclosing instance to initialize " + C.typeName() + "
with");

          //System.err.println("ClassInstanceExpr: Non qualified MemberType
" + C.typeName() + " is in a static context when instantiated in " + this);

          enclosing = unknownType();

        }

        else {

          TypeDecl nest = hostType();

          /*

          while(nest != null && !nest.instanceOf(C.enclosingType()))
// !!!

            nest = nest.enclosingType();
// !!!

           replaced with the following while-block */

         while(nest != null && !nest.instanceOf(C.enclosingType())) {

            if ( nest.isStatic() || nest.inStaticContext() ) {

              nest = unknownType();

              break;

            }

            nest = nest.enclosingType();

          }

 

          enclosing = nest == null ? unknownType() : nest;

        }

      }

      else {

        enclosing = enclosingInstance();

      }

    }

    //if(enclosing != null && !enclosing.instanceOf(type().enclosingType()))
{ // !!! replaced with the following line

    if(enclosing != null && enclosing != type().enclosingType()) {

      String msg = enclosing == null ? "None" : enclosing.typeName();

      error("*** Can not instantiate " + type().typeName() + " with the
enclosing instance " + msg + " due to incorrect enclosing instance");

    }

    .

-=-=-=

 

The three lines marked with "!!!" were replaced as shown above.

( Note that unknownType().instanceOf(T) is true for every type T, so we need
to replace the instanceOf with reference comparison )

 

After rebuilding the compiler with this modification, the compiler rejects
the above two examples as expected.

 

Cheers.

- Hyunik.

 

 
Received on Fri Jun 01 2012 - 06:41:49 CEST

This archive was generated by hypermail 2.3.0 : Wed Apr 16 2014 - 17:19:06 CEST