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

Name: Expression has no effect

Description: An expression that has no effect and is used in a void context is most likely redundant and may indicate a bug.

ID: go/useless-expression

Kind: problem

Severity: warning

Precision: very-high

Query: ExprHasNoEffect.ql
/**
 * @name Expression has no effect
 * @description An expression that has no effect and is used in a void context is most
 *              likely redundant and may indicate a bug.
 * @kind problem
 * @problem.severity warning
 * @id go/useless-expression
 * @tags maintainability
 *       correctness
 *       external/cwe/cwe-480
 *       external/cwe/cwe-561
 * @precision very-high
 */

import go

/**
 * Holds if `e` appears in a syntactic context where its value is discarded.
 */
predicate inVoidContext(Expr e) {
  e = any(ExprStmt es).getExpr()
  or
  exists(LogicalBinaryExpr logical | e = logical.getRightOperand() and inVoidContext(logical))
}

/**
 * Holds if `ce` is a call to a stub function with an empty body.
 */
predicate callToStubFunction(CallExpr ce) { ce.getTarget().getBody().getNumStmt() = 0 }

from Expr e
where
  not e.mayHaveOwnSideEffects() and
  inVoidContext(e) and
  // don't flag calls to functions with an empty body
  not callToStubFunction(e)
select e, "This expression has no effect."

An expression that has no effects (such as changing variable values or producing output) and occurs in a context where its value is ignored possibly indicates missing code or a latent bug.

Recommendation

Carefully inspect the expression to ensure it is not a symptom of a bug.

Example

The following example shows a named type Timestamp that is an alias for int, representing time stamps expressed as the number of seconds elapsed since some epoch. The addDays method returns a time stamp that is a given number of days after another time stamp, without modifying that time stamp.

However, when addDays is used in function test, its result is discarded, perhaps because the programmer mistakenly assumed that addDays updates the time stamp in place.

package main

import "fmt"

type Timestamp int

func (t Timestamp) addDays(d int) Timestamp {
	return Timestamp(int(t) + d*24*3600)
}

func test(t Timestamp) {
	fmt.Printf("Before: %s\n", t)
	t.addDays(7)
	fmt.Printf("After: %s\n", t)
}

Instead, the result of addDays should be assigned back into t:

package main

import "fmt"

func testGood(t Timestamp) {
	fmt.Printf("Before: %s\n", t)
	t = t.addDays(7)
	fmt.Printf("After: %s\n", t)
}