Skip to content

Fix false positives in SS008, SS050, SS057#408

Merged
Vannevelj merged 3 commits into
masterfrom
worktree-quirky-floating-codd
Jun 29, 2026
Merged

Fix false positives in SS008, SS050, SS057#408
Vannevelj merged 3 commits into
masterfrom
worktree-quirky-floating-codd

Conversation

@Vannevelj

Copy link
Copy Markdown
Owner

Summary

  • SS008 GetHashCodeRefersToMutableMember (#406): readonly fields typed as System.Tuple<...> are no longer flagged. Tuple is a sealed immutable class so a readonly reference to it cannot change state.
  • SS050 ParameterAssignedInConstructor (#389): The analyzer no longer fires when the suspect parameter is subsequently stored into a field or property in the same constructor. This covers the normalization/defaulting pattern (if (x == null) x = fallback; this.field = x;) which was triggering a 100% false-positive rate across 560 evaluated repos.
  • SS057 CollectionManipulatedDuringTraversal (#383): Modifications inside for/foreach loops are no longer flagged when the modification statement is immediately followed by return or break in the same block. These are safe because the loop does not continue after the modification.

All three fixes follow TDD — failing tests were added first, then minimal implementation changes to make them pass. The full suite of 1345 tests continues to pass.

Test plan

  • GetHashCodeRefersToMutableMember_ReadonlyTupleField_NoDiagnostic — no warning on readonly Tuple<DateTime, Guid>
  • GetHashCodeRefersToMutableMember_NonReadonlyTupleField_Diagnostic — still warns on non-readonly Tuple
  • CollectionManipulatedDuringTraversal_ForLoop_RemoveAtFollowedByReturn_NoDiagnostic
  • CollectionManipulatedDuringTraversal_ForLoop_RemoveAtFollowedByBreak_NoDiagnostic
  • CollectionManipulatedDuringTraversal_ForEachLoop_RemoveAtFollowedByReturn_NoDiagnostic
  • CollectionManipulatedDuringTraversal_ForLoop_RemoveAtWithoutReturn_Diagnostic — still warns when no early exit
  • ParameterAssignedInConstructor_NormalizationBeforeFieldAssignment_NoDiagnostic
  • ParameterAssignedInConstructor_NormalizationWithNullCheck_NoDiagnostic
  • ParameterAssignedInConstructor_AssignedFromFieldWithoutStoringToField_Diagnostic — still warns when param is never stored

🤖 Generated with Claude Code

Vannevelj and others added 3 commits June 29, 2026 00:25
- GetHashCodeRefersToMutableMember: exempt readonly System.Tuple<...> fields since Tuple is an immutable sealed class
- ParameterAssignedInConstructor: suppress when the parameter is later stored in a field/property (normalization pattern)
- CollectionManipulatedDuringTraversal: skip modifications in for/foreach loops immediately followed by return or break

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…comparison

Simpler heuristic than checking for downstream field assignment: if the parameter
is used in any binary comparison in the constructor, the reassignment is intentional
normalization/defaulting. Unwrap implicit conversions when inspecting operands
(needed for nullable-enabled projects where reference-type operands are wrapped).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Vannevelj Vannevelj merged commit 02fe4aa into master Jun 29, 2026
5 checks passed
@Vannevelj Vannevelj deleted the worktree-quirky-floating-codd branch June 29, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant