CodeQL queries 1.25
Skip to end of metadata
Go to start of metadata

Name: Duplicate switch case

Description: If two cases in a switch statement have the same label, the second case will never be executed.

ID: go/duplicate-switch-case

Kind: problem

Severity: error

Precision: very-high

Query: DuplicateSwitchCase.ql
/**
 * @name Duplicate switch case
 * @description If two cases in a switch statement have the same label, the second case
 *              will never be executed.
 * @kind problem
 * @problem.severity error
 * @id go/duplicate-switch-case
 * @tags maintainability
 *       correctness
 *       external/cwe/cwe-561
 * @precision very-high
 */

import go

/** Gets the global value number of of `e`, which is the `i`th case label of `switch`. */
GVN switchCaseGVN(SwitchStmt switch, int i, Expr e) {
  e = switch.getCase(i).getExpr(0) and result = e.getGlobalValueNumber()
}

from SwitchStmt switch, int i, Expr e, int j, Expr f
where switchCaseGVN(switch, i, e) = switchCaseGVN(switch, j, f) and i < j
select f, "This case is a duplicate of $@.", e, "an earlier case"

If two cases in a 'switch' statement are identical, the second case will never be executed. This most likely indicates a copy-paste error where the first case was copied and then not properly adjusted.

Recommendation

Examine the two cases to find out what they were meant to check. If both the conditions and the bodies are identical, then the second case is duplicate code that can be deleted. Otherwise, the second case needs to be adjusted.

Example

In the example below, the function controller checks its parameter msg to determine what operation it is meant to perform. However, the condition of the second case is identical to that of the first, so this case will never be executed.

package main

func controller(msg string) {
	switch {
	case msg == "start":
		start()
	case msg == "start":
		stop()
	default:
		panic("Message not understood.")
	}
}

Most likely, the second case should compare msg to "stop":

package main

func controllerGood(msg string) {
	switch {
	case msg == "start":
		start()
	case msg == "stop":
		stop()
	default:
		panic("Message not understood.")
	}
}

References