JDK-8274863 : Indy string concat changes order of operations
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 19
  • Submitted: 2021-10-06
  • Updated: 2024-09-11
  • Resolved: 2021-12-05
Related Reports
CSR :  
Relates :  
Description
Summary
-------

This change causes the operands of string concatenation expressions
to be evaluated and converted to strings in the correct order when using
the invokedynamic-based strategies introduced in [JEP 280](https://openjdk.java.net/jeps/280).

Problem
-------

JLS 15.18.1 requires string conversion to be performed on the operands
of a string concatenation expression, and JLS 15.7.1 requires the operands
to be fully evaluated in left-to-right order. The current behavior of the
invokedynamic string concatenation strategies is to evaluate all operands,
and then separately convert them all to strings. The correct behavior is
to evaluate each argument and eagerly convert it to a string, in left-to-right
order.

Solution
--------

The solution is for the invokedynamic-based strategies to convert the
operands to strings as they are evaluated, and before they are passed
to the invokedynamic call site, to preserve the required evaluation order.

For some well-known types whose string representation is known to be
idempotent (including primitive types, their boxes, and java.lang.String)
the eager string conversion may be skipped.

Specification
-------------

No specification changes are required.

The proposed change to restore the behavior of the implementation
to match the specification can be found in https://git.openjdk.java.net/jdk/pull/5844.

Comments
Friendly reminder. [~darcy], [~cushon] -- I think we need to move it forward for backports to 17 and 11. There seem to be enough of the real-world testing done since 2022, which includes JDK 21, so I would think we do not have to wait for corpus runs. [~cushon], would you like to be a point person to proceed with backports?
03-09-2024

Have we ever completed the corpus run for this change? I think we need to backport this fix to earlier release trains soon. JDK 19 would be released in September 2022, and it would be nice to have the fix in October 2022 releases for earlier releases.
04-08-2022

[~cushon], sorry for the delays here. I still need to do some work in support of the corpus effort. At this point in the JDK 18 schedule, I think this change should go in at the very start of JDK *19* with the assumption it will get backported to earlier release trains pending successful corpus runs and other testing. Integrations to jdk/jdk should mean going into 19 by Dec. 10, 2021. Moving to Approved for 19; one or more CSRs for backports can cover those efforts as needed.
05-12-2021

[~darcy] Did the corpus run turn up anything? And is there anything else you'd like to see addressed before I finalize the proposal? Thanks!
12-11-2021

> Assuming the change in behavior is the same, this CSR can be used for all release trains and the fixVersion field updated before the request is Finalized. Thanks - I added fixVersion to {11-pool, 17-pool, 18}, let me know if I misunderstood the process for that. > It would be informative to know how frequently a difference in behavior can be observed in practice; I'll look into a corpus run. I haven't been able to find any examples where the difference was observed in real-world code. I'll be interested to see what the corpus run turns up, thanks!
04-11-2021

Moving to Provisional for JDK 18. As [~shade] notes, this should also be addressed in the actively maintained update releases. Assuming the change in behavior is the same, this CSR can be used for all release trains and the fixVersion field updated before the request is Finalized. It would be informative to know how frequently a difference in behavior can be observed in practice; I'll look into a corpus run.
26-10-2021

Yes, I believe converting non-trivial arguments to Strings eagerly in left-to-right order would be the right thing to do. This restores the behavior implied by JLS. Given that it happens in releases past JDK 9, I suppose we need to backport the fix to 11u and 17u. (I am not sure if we can just put 11, 17, 18 into Fix Versions).
19-10-2021

The example of https://bugs.openjdk.java.net/browse/JDK-8200118 might be relevant here, since it was a similar bug in the indy string concat strategies that was fixed despite the potential for compatibility impact on code that depended on the bug.
06-10-2021