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

javac should not analyze final parameters for definite assignment status

XMLWordPrintable

    • mantis
    • generic
    • solaris_7, solaris_8
    • Verified

      From: Eric Blake <###@###.###>
      Date: Fri, 30 Nov 2001 17:29:53 -0700
      Reply-To: ###@###.###
      Subject: [Java Spec Report] Re: Final Release of JSR-41

      I had a conversation off this list, where the following point was made;
      and I'm not sure I agree with it.

      Neal Gafter wrote:
      >
      > > // assignment to final parameter, should fail
      > > assert true : args = null;
      >
      > No, it should pass for the same reason that
      >
      > if (false) args = null;
      >
      > passes.

      According to JLS 4.5.4, "It is a compile time error if a final variable
      is assigned to unless it is definitely unassigned (§16) immediately
      prior to the assignment. ...
      A blank final is a final variable whose declaration lacks an
      initializer."
      According to JLS 16, "Throughout the rest of this chapter, we will,
      unless explicitly stated otherwise, write V to represent a local
      variable or a blank final field (for rules of definite assignment) or a
      blank final variable (for rules of definite unassignment)."
      Also, according to JLS 15.26, "A variable that is declared final cannot
      be assigned to (unless it is a blank final variable (§4.5.4)), because
      when an access of a final variable is used as an expression, the result
      is a value, not a variable, and so it cannot be used as the first
      operand of an assignment operator."

      The way I read it, a final parameter (method, constructor, or
      exception-handler) has an initializer, albeit an implicit one, as the
      grammar does not permit an explicit one (besides, 4.5.3 states that
      these parameters are always initialized, and gives the initial value).
      Therefore, I claim that a parameter cannot be a blank final, and that
      any attempt to assign to a final parameter should fail for the same
      reason that an attempt to assign a non-blank final field fails: the
      variable is not a blank final. In short, I see no reason to perform
      definite unassignment analysis on parameters.

      By my interpretation, this program should fail to compile with 3 errors
      (and that is the implementation jikes presently uses):
      class Blah {
        public static void main(final String[] args) {
          if (false) args = null;
          try {
            throw new Exception();
          } catch (final Exception e) {
            if (false) e = null;
          }
        }
        Blah(final int i) {
          if (false) i = 1;
        }
      }

      But apparently Neal feels otherwise; and javac compiles this program
      without complaint. I am not sure which approach is best; can anyone
      else find unambiguous quotes in the JLS to support one position or the
      other? If not, then this issue deserves at least a Clarification in the
      Spec Report, since compiler implementations currently differ in their
      treatment of the above program.

      Meanwhile, the sentence I quoted above from 16, which claims that
      definite assignment analysis is not necessary for formal method,
      constructor, or exception-handler parameters, makes these phrases in
      16.3 invalid: "A formal parameter V of a method or constructor is
      definitely assigned... An exception parameter V of a catch clause is
      definitely assigned...". Whether the second part of those sentences
      "(and moreover is not definitely unassigned)" is valid depends on the
      outcome of the above discussion, whether a parameter can be considered a
      blank final. If my interpretation is correct, then 16.3 is completely
      unnecessary, as a parameter has neither DA nor DU analysis performed on
      it.

      Also, these two statements conflict - is a final parameter treated as a
      variable, or a value?
      JLS 15.26 "when an access of a final variable is used as an expression,
      the result is a value, not a variable,"
      JLS 6.5.6.1 "If the Identifier appears within the scope (§6.3) of a
      visible local variable declaration (§14.4) or visible parameter
      declaration (§8.4.1, §8.8.1, §14.19) with that name, then the expression
      name denotes a variable, that is, that local variable or parameter."

      Note that if a final parameter is taken as a value and not a variable
      (following chapter 15, but not 6), then my above argument for
      disallowing assignments to final parameters in an if(false) block
      becomes even stronger. But keep in mind Spec Report 6.5.6, which claims
      that treating final variables as variables is an anachronism left over
      from the first edition, which should not be present in the first place.

      --
      This signature intentionally left boring.

      Eric Blake ###@###.###
        BYU student, free software programmer

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

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: