JDK-8215265 : C2: range check elimination may allow illegal out of bound access
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,9,10,11,12
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-12-12
  • Updated: 2020-10-28
  • Resolved: 2019-01-03
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12 JDK 13 JDK 7 JDK 8 Other
11.0.5Fixed 12 b27Fixed 13Fixed 7u281Fixed 8u270Fixed openjdk7uFixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Following test case: 

import java.util.Arrays; 

public class RangeCheckEliminationScaleNotOne { 
    public static void main(String[] args) { 
        { 
            int[] array = new int[199]; 
            boolean[] flags = new boolean[100]; 
            Arrays.fill(flags, true); 
            flags[0] = false; 
            flags[1] = false; 
            for (int i = 0; i < 20_000; i++) { 
                test1(100, array, 0, flags); 
            } 
            boolean ex = false; 
            try { 
                test1(100, array, -5, flags); 
            } catch (ArrayIndexOutOfBoundsException aie) { 
                ex = true; 
            } 
            if (!ex) { 
                throw new RuntimeException("no AIOOB exception"); 
            } 
        } 
    } 

    private static int test1(int stop, int[] array, int offset, boolean[] flags) { 
        if (array == null) {} 
        int res = 0; 
        for (int i = 0; i < stop; i++) { 
            if (flags[i]) { 
                res += array[2 * i + offset]; 
            } 
        } 
        return res; 
    } 
} 

ran with: 

java -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:-UseOnStackReplacement -XX:CompileOnly=RangeCheckEliminationScaleNotOne::test1 -XX:LoopMaxUnroll=1 -XX:-UseLoopPredicate RangeCheckEliminationScaleNotOne 

either:

- fails with same error as JDK-8211698

or with fix suggested:
https://bugs.openjdk.java.net/browse/JDK-8211698?focusedCommentId=14229219&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14229219

- segfaults because of an out of bound access

Given how old this code is, and while I haven't verified, it's likely to affect all  versions since at least 8.
Comments
Fix-request (8u) This fixes bad C2 miscompilation. Patch applies mostly cleanly, except usual path changes and minor changed C2 paradigms (new XYZNode -> new (C) XYZNode() ). New test fails without patch, passes with. Passes tier1 and tier2 tests w/o regressions. Review for jdk8u backport: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-August/010085.html
21-08-2019

Fix Request (11u) This fixes bad C2 miscompilation. Patch applies cleanly to 11u. New test fails without the patch, and passes with it. Patched JDK passes tier1, tier2 tests.
27-06-2019

New regression test passes in mach5
12-02-2019

ILW = Out of bounds array access in C2 compiled code causes segfault, rare but easy to reproduce, -XX:-RangeCheckElimination = HMM = P2
12-12-2018