Skip to content

Go: go/comparison-of-identical-expressions false positive when a variable is reassigned in a range loop (go-all 8.0.0) #22770

Description

@gomaja

Description of the false positive

Since codeql/go-queries 1.6.12 (with codeql/go-all 8.0.0), go/comparison-of-identical-expressions reports a comparison between a variable and the value it was initialised from, even though the variable may be reassigned inside a range loop between the two. With codeql/go-queries 1.6.11 (codeql/go-all 7.3.2), the same database gives no result.

The trigger is the range loop. The same assignment in a plain if or in a three-clause for loop is not reported. It looks related to the CFG rewrite in go-all 8.0.0, whose changelog mentions range statements. If assignments in a range body don't reach the code after the loop, other data-flow queries might be affected as well. I have only checked this query.

Code samples or links to source code

package repro

// Reported (line "if n == c"): n may be raised inside the range loop.
func Settle(c int, xs []int) int {
	for {
		n := c
		for _, x := range xs {
			if x > n {
				n = x
			}
		}
		if n == c { // <- "This expression compares an expression to itself."
			break
		}
		c = n
	}
	return c
}

// Also reported: unconditional assignment in a range loop.
func VariantD(c int, xs []int) int {
	n := c
	for _, x := range xs {
		n = x
	}
	if n == c { // <- reported
		return 0
	}
	return n
}

// Not reported: the same assignment in a three-clause loop.
func VariantB(c int, xs []int) int {
	n := c
	for i := 0; i < len(xs); i++ {
		if xs[i] > n {
			n = xs[i]
		}
	}
	if n == c {
		return 0
	}
	return n
}

To reproduce (CodeQL CLI 2.27.1, macOS arm64, Go 1.25.13). --no-tracing is used only because this machine has no Rosetta for the tracer.

codeql database create db --language=go --source-root src --build-mode=autobuild --no-tracing
codeql database analyze db codeql/go-queries@1.6.11:RedundantCode/CompareIdenticalValues.ql --format=sarif-latest --output=a.sarif --rerun
codeql database analyze db codeql/go-queries@1.6.12:RedundantCode/CompareIdenticalValues.ql --format=sarif-latest --output=b.sarif --rerun
  • a.sarif, go-queries 1.6.11 / go-all 7.3.2: 0 results.
  • b.sarif, go-queries 1.6.12 / go-all 8.0.0: 3 results: Settle, VariantD, and a third range-loop variant without the outer loop.

Without --rerun, the second command silently reuses the first command's cached results: its SARIF reports go-queries 1.6.11 and 0 results. This may be worth a look separately.

The same comparison is reported in real code here: https://github.com/gomaja/go-asn1/blob/2e83d89af0dc815fc1e0a589691032aa069153bc/runtime/ber/named_bit_size.go#L43. In that code, next starts as candidate and can be raised inside the range loop over the permitted intervals.

Activity

  1. hvitved commented on Oct 7, 2026

    @hvitved
    Contributor

    @owen-mc : Do you think this can be the result of switching Go over to using the shared CFG library?

  2. owen-mc commented on Oct 8, 2026

    @owen-mc
    Contributor

    @gomaja Many thanks for reporting this issue and for providing so much detail, especially the versions you used. I have investigated it and found the cause.

    The problem occurs when a database created using CodeQL CLI 2.27.1 or earlier is analyzed with codeql/go-all 8.0.0 or later. To avoid these erroneous alerts, please update to CodeQL CLI 2.27.2 and recreate the database.

    As part of migrating the Go libraries to use the shared CFG library, I changed how range loops are represented in the database. The new library pack expects the new representation, while databases created by the older extractor contain the old representation.

    The database-schema upgrade for this change was incorrectly marked as partially compatible. It should have been marked as incompatible, which would have prevented the newer library pack from analyzing an older database and producing these incorrect results. Sorry for the inconvenience.

  3. gomaja commented on Oct 8, 2026

    @gomaja
    Author

    Thanks for the quick investigation. I confirm the cause: with CodeQL CLI 2.27.2, a freshly created database, and codeql/go-queries 1.6.12 (codeql/go-all 8.0.0), the reproducer above gives no results. The old database analysed with the new pack was the problem. I will leave closing to you, in case you want this issue to track the corrected compatibility marking of the schema upgrade.

  4. owen-mc commented on Oct 8, 2026

    @owen-mc
    Contributor

    We have now merged #22783, which corrects the database upgrade script to make it full compatibility. This means that, as of the next release, this issue will be fixed, and it will only occur when using CodeQL CLI 2.27.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions