-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Closed
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
Go version
go version go1.26-devel_5241d11 Mon Nov 10 12:48:05 2025 -0800 linux/amd64
Output of go env in your module/workspace:
Workspace is `go.godbolt.org` on `x86-64 gc (tip)` as above.What did you do?
(Code/output used also found here)
Compile containsDotDot from the standard library:
func containsDotDot(s string) bool {
if len(s) < 2 {
return false
}
for i := 0; i < len(s)-1; i++ {
if s[i] == '.' && s[i+1] == '.' {
return true
}
}
return false
}What did you see happen?
A bounds check + panic section was generated:
TEXT command-line-arguments.containsDotDot(SB), NOSPLIT|ABIInternal, $8-16
[...]
CMPQ BX, $2
JLT command-line-arguments_containsDotDot_pc19
XORL CX, CX
JMP command-line-arguments_containsDotDot_pc26
command-line-arguments_containsDotDot_pc19:
XORL AX, AX
POPQ BP
RET
command-line-arguments_containsDotDot_pc23:
INCQ CX
command-line-arguments_containsDotDot_pc26:
LEAQ -1(BX), DX
NOP
CMPQ CX, DX
JGE command-line-arguments_containsDotDot_pc76
MOVBLZX (AX)(CX*1), DX
CMPB DL, $46
JNE command-line-arguments_containsDotDot_pc23
LEAQ 1(CX), DX
CMPQ BX, DX
JLS command-line-arguments_containsDotDot_pc80 ; <--------------------------
MOVBLZX 1(CX)(AX*1), DX
NOP
CMPB DL, $46
JNE command-line-arguments_containsDotDot_pc23
MOVL $1, AX
POPQ BP
RET
command-line-arguments_containsDotDot_pc76:
XORL AX, AX
POPQ BP
RET
command-line-arguments_containsDotDot_pc80:
PCDATA $1, $1
PCDATA $4, $3663
CALL runtime.panicBounds(SB)
XCHGL AX, AXWhat did you expect to see?
No bounds check + panic section should be generated as the condition checks for i < len(s)-1, meaning i+1 < len(s).
There are two cases below illustrating the effects of what should be equivalent assembly output:
Case 1: Change of variable (j := i + 1)
This results in no extra bounds checking:
func containsDotDot(s string) bool {
if len(s) < 2 {
return false
}
for j := 1; j < len(s); j++ {
if s[j-1] == '.' && s[j] == '.' {
return true
}
}
return false
}Case 2: Move of constant to other side of condition
This results in both index operations having bounds checks:
func containsDotDot(s string) bool {
if len(s) < 2 {
return false
}
for i := 0; i+1 < len(s); i++ {
if s[i] == '.' && s[i+1] == '.' {
return true
}
}
return false
}Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.