Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4094180

# Synthetic names can conflict with explicit declaration

XMLWordPrintable

    • generic, x86, sparc
    • generic, solaris_2.5, solaris_2.5.1, windows_95, windows_nt



      Name: dkC59003 Date: 11/20/97



      The document "Inner Classes in Java 1.1" says:
      "For purposes of linking, the compiler must generate a unique externally
      visible name for every inaccessible class. The overall form of
      these names is a class name, followed by additional numbers or names, separated by $ characters.
      Also, variable names synthesized by the compiler beginning with this$ and val$ must follow the usage patterns described here."

      Compiler outputs an error while compiling the following source file
      incorrectly considering val$prm2 as int whereas it is defined as Object.
      Note that the case of val$prm1 is OK. The only difference between these two
      variables is the parameter prm2 occurence preceding val$prm2 usage.

      -----------------------------------------
      package javasoft.sqe.tests.lang.icls122.icls12201;
       
      import java.io.PrintStream;
       
      public class icls12201 {

      interface Intf {
      int getFirst();
      int getSecond();
      }

      static Intf meth(final int prm1, final int prm2) {

      final Object val$prm1 = null;
      final Object val$prm2 = null;

      class InnClass implements Intf {
      Object locVar;
      public int getFirst() {
      locVar = val$prm1;
      return prm1;
      }
      public int getSecond() {
      int locInt;
      locInt = prm2;
      locVar = val$prm2;
      return locInt;
      }
      }
      return new InnClass();
      }
      }
      -----------------------------------------

      JDK 1.1.5F and JDK 1.2S compilers output:

      t1.java:26: Incompatible type for =. Can't convert int to java.lang.Object.
      locVar = val$prm2;
      ^
      1 error
      -----------------------------------------

      ======================================================================

      A similar problem can arise with the flatnames of inner classes
      conflicting with explicitly-declared classes (from 4096303):

      class Some$Clazz { }

      class Some {
          class Clazz { }
      }

      Another case was reported in 4030356:

      Source code can refer to synthetic names like "this$Foo",
      which are an implementation detail supposedly inaccessible to programmers.
      Thus, files like this should not compile, but they do:

              class HiddenFieldBug {
                  class Inner {
                      Object x = this$HiddenFieldBug;
                      // A similar problem exists with other synthesized names,
                      // such as val$foo, access$2(), HiddenFieldBug$1$Local.
                  }
              }

      william.maddox@Eng 2000-01-10


      ======================================================================
      from 4094180:


      Javac (jdk1.4.0beta-b62, jdk1.3.1-b23) allows access to a local
      class by using a synthetic name that compiler constructs to represent
      a local class. Through this synthetic name the class is accessible
      even outside of its scope.

      That contradicts the following assertions of JLS-2,
      14.3 "Local class declarations":

        "The scope of a local class declared in a block is the rest of the
         immediately enclosing block, including its own class declaration."
         
        "A local class does not have a canonical name, nor does it have a fully
         qualified name."
         
      The following test demonstrates the behavior:

      --stmt16503_a.java--------------------------------------------
      public class stmt16503_a {
          public static void test() {
              class Local {};
          }
      }
      --------------------------------------------------------------

      --stmt16503.java----------------------------------------------
      public class stmt16503 {
          public static void main(String argv[]) {
              Object a = new stmt16503_a$1$Local();
          }
      }
      --------------------------------------------------------------

      The class Local can be accessed from a method of class stmt16503 by using
      the name stmt16503_a$1$Local. To reproduce the bug classes should be compiled
      in sequence - stmt16503_a.java, then stmt16503.java.
      Compiler correctly detects the error when classes are compiled together.

      The execution log is following:

      $ jdk1.4.0beta-b62/solsparc/bin/java -version
      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b62)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b62, mixed mode)
      $ jdk1.4.0beta-b62/solsparc/bin/javac -d . stmt16503_a.java stmt16503.java; echo
      $?
      stmt16503.java:3: cannot resolve symbol
      symbol : class stmt16503_a$1$Local
      location: class stmt16503
              Object a = new stmt16503_a$1$Local();
                             ^
      1 error
      1
      $ jdk1.4.0beta-b62/solsparc/bin/javac -d . stmt16503_a.java; echo $?
      0
      $ jdk1.4.0beta-b62/solsparc/bin/javac -d . stmt16503.java; echo $?
      0
      $ jdk1.4.0beta-b62/solsparc/bin/java stmt16503; echo $?
      0
      $


      ========================================================
      from 4480593:

      When compiling the following class

      class t
      {
              public static void main(String[] args)
              {
                      Class c = t.class;
                      System.out.println(c);
              }
              
              int class$t() { return 0; }
      }

      the following exception trace was obtained.

      C:\jdk1.4\bin>javac t.java
      An exception has occurred in the compiler (1.4.0-beta). Please file a bug at the
       Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi) after ch
      ecking the Bug Parade for duplicates. Include your program and the following dia
      gnostic in your report. Thank you.
      java.lang.ClassCastException: com.sun.tools.javac.v8.code.Symbol$MethodSymbol
              at com.sun.tools.javac.v8.comp.TransInner.cacheSym(TransInner.java:1528)

              at com.sun.tools.javac.v8.comp.TransInner.classOfType(TransInner.java:1582)
              at com.sun.tools.javac.v8.comp.TransInner.classOf(TransInner.java:1547)
              at com.sun.tools.javac.v8.comp.TransInner._case(TransInner.java:1954)
              at com.sun.tools.javac.v8.tree.Tree$Select.visit(Tree.java:1200)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:45)
              at com.sun.tools.javac.v8.tree.TreeTranslator._case(TreeTranslator.java:120)
              at com.sun.tools.javac.v8.tree.Tree$VarDef.visit(Tree.java:604)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:45)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:58)
              at com.sun.tools.javac.v8.tree.TreeTranslator._case(TreeTranslator.java:129)
              at com.sun.tools.javac.v8.tree.Tree$Block.visit(Tree.java:644)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:45)
              at com.sun.tools.javac.v8.tree.TreeTranslator._case(TreeTranslator.java:114)
              at com.sun.tools.javac.v8.comp.TransInner._case(TransInner.java:1748)
              at com.sun.tools.javac.v8.tree.Tree$MethodDef.visit(Tree.java:569)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:45)
              at com.sun.tools.javac.v8.comp.TransInner._case(TransInner.java:1678)
              at com.sun.tools.javac.v8.tree.Tree$ClassDef.visit(Tree.java:521)
              at com.sun.tools.javac.v8.tree.TreeTranslator.translate(TreeTranslator.java:45)
              at com.sun.tools.javac.v8.comp.TransInner.translate(TransInner.java:1638)
              at com.sun.tools.javac.v8.comp.TransInner.translateTopLevelClass(TransInner.java:1988)
              at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:484)
              at com.sun.tools.javac.v8.Main.compile(Main.java:505)
              at com.sun.tools.javac.Main.compile(Main.java:27)
              at com.sun.tools.javac.Main.main(Main.java:16)

      -------------------------------------------------------------------------------
      On the other hand, using other internally used names such as 'this$n', compiler
      gives proper error message.

            gafter Neal Gafter (Inactive)
            dkhukhrosunw Dmitry Khukhro (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: