Skip to content

AssignmentExpression matcher is not parenthesis-invariant on nested assignments #5827

@Chordrain

Description

@Chordrain

Error Prone version

Error Prone 2.49.0 (javac plugin) — javac 21.0.8, source/target 21.

Check name

AssignmentExpression

Description

AssignmentExpression flags assignments used inside a larger expression (e.g. int i = j = 0; or if ((a = b) != 1) {}). Its tree walker does not consistently look through ParenthesizedTree nodes when deciding whether an assignment is "embedded": wrapping or unwrapping the inner assignment in redundant parentheses changes whether the rule fires. Since parentheses do not change the value or type of an expression (JLS §15.8), the verdict should be paren-invariant.

This is a low-severity consistency defect — the net count drift on a single file is small (+1 below) — but it shows the matcher is shape-sensitive where it should not be.

Reproducer

// BEFORE — 3 AssignmentExpression findings
class C {
  int a,b,j,l;
  byte[] bresult;
  void m() {
    a = b = 0;
    if ((a = b = 0) != 1) {}
    int i = j = 0;  // flagged
    int k = (l += 1);
    double x = 0, y, z;
    double aa = y = z = 1.0;  // flagged
    byte[] result;
    result = (bresult = new byte[5]); // flagged
  }
}
// AFTER — same logical assignments, parens added/removed; 4 findings
class C {
  int a,b,j,l;
  byte[] bresult;
  void m() {
    a = (b = 0);  // flagged
    if ((a = (b = 0)) != 1) {}  // flagged
    int i = (j = 0);  // flagged
    int k = l += 1;
    double x = 0, y, z;
    double aa = (y = z = 1.0);  // flagged
    byte[] result;
    result = bresult = new byte[5];
  }
}

Expected behavior

AssignmentExpression should report the same number of findings on BEFORE and AFTER. Every nested-assignment site that is "embedded in a larger expression" in BEFORE remains so in AFTER (and vice versa); the rewrites are JLS-inert.

Actual behavior

  • BEFORE: 3 findings.
  • AFTER: 4 findings.

The +1 drift across paren add/remove sites confirms the AST walker is not uniformly parenthesis-invariant when descending into assignment sub-expressions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions