Skip to content

cmd/compile: bounds check elimination for len(x) - 1 #23354

@aclements

Description

@aclements

What version of Go are you using (go version)?

go version devel +1a9f27d503 Thu Jan 4 02:17:33 2018 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

package main

var x []int

func main() {
	if n := len(x); n > 0 {
		x[n-1] = 0
	}
}

What did you expect to see?

There should be no bounds check for x[n-1].

What did you see instead?

There is a bounds check.

This comes up in practice for two reasons:

  1. The range loop construction @dr2chase experimented with to eliminate the out-of-bounds pointer produces exactly this sort of pattern, which in turn causes additional bounds checks to be produced.

  2. This pattern appears in runtime.newdefer, which must be recursively go:nosplit. I'm adding a static check of this for cmd/compile, runtime: add and use go:nosplitrec compilation directive #21314. Unfortunately, while I can see that the generated call to panic here can't happen dynamically, the linker can't, so the static check fails. I can contort the code to the following, but it would be nicer if I didn't have to:

	if n := len(x) - 1; n >= 0 && n < len(x) {
		x[n-1] = 0
	}

/cc @dr2chase

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions