Skip to content

Handle local variable values in MA0173 analyzer#1097

Merged
meziantou merged 1 commit intomainfrom
meziantou/fix-compareexchange-lazyinitializer-test
Apr 18, 2026
Merged

Handle local variable values in MA0173 analyzer#1097
meziantou merged 1 commit intomainfrom
meziantou/fix-compareexchange-lazyinitializer-test

Conversation

@meziantou
Copy link
Copy Markdown
Owner

Why

MA0173 only reported Interlocked.CompareExchange when the value argument was an object creation expression. This missed valid cases where the value came from a local variable (for example, a local Func assigned to a static field), so the analyzer did not suggest LazyInitializer.EnsureInitialized consistently.

What changed

  • Expanded MA0173 detection to also report when the second CompareExchange argument is a local reference.
  • Kept the null-comparand requirement and added a reference-type check on the target argument to avoid non-applicable value-type cases.
  • Added a regression test (LocalVariable_Field_Null) covering:
    • Interlocked.CompareExchange(ref s_getDisplayName, getDisplayName, comparand: null)
    • expected fix: LazyInitializer.EnsureInitialized(ref s_getDisplayName, () => getDisplayName)

Notes for reviewers

The fixed code intentionally uses () => getDisplayName (a factory returning Func<string>). Passing getDisplayName directly would not match the EnsureInitialized overload for this scenario.

Report Interlocked.CompareExchange(ref field, localVariable, null) and add a regression test for Func field/local variable usage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@meziantou meziantou marked this pull request as ready for review April 18, 2026 14:02
@meziantou meziantou merged commit 2f07c56 into main Apr 18, 2026
13 checks passed
@meziantou meziantou deleted the meziantou/fix-compareexchange-lazyinitializer-test branch April 18, 2026 14:02
IhateTrains pushed a commit to ParadoxGameConverters/ImperatorToCK3 that referenced this pull request Apr 19, 2026
Updated
[Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer)
from 3.0.49 to 3.0.50.

<details>
<summary>Release notes</summary>

_Sourced from [Meziantou.Analyzer's
releases](https://github.com/meziantou/Meziantou.Analyzer/releases)._

## 3.0.50

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.50>

## What's Changed
* Handle local variable values in MA0173 analyzer by @​meziantou in
meziantou/Meziantou.Analyzer#1097


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.49...3.0.50

Commits viewable in [compare
view](meziantou/Meziantou.Analyzer@3.0.49...3.0.50).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Meziantou.Analyzer&package-manager=nuget&previous-version=3.0.49&new-version=3.0.50)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Chris-Wolfgang added a commit to Chris-Wolfgang/DbContextBuilder that referenced this pull request Apr 20, 2026
Updated
[coverlet.collector](https://github.com/coverlet-coverage/coverlet) from
8.0.1 to 10.0.0.

<details>
<summary>Release notes</summary>

_Sourced from [coverlet.collector's
releases](https://github.com/coverlet-coverage/coverlet/releases)._

## 10.0.0

## Improvements

- Unique Report Filenames (coverlet.MTP and AzDO)
[#​1866](coverlet-coverage/coverlet#1866)
- Add `--coverlet-file-prefix` option for unique report files
[#​1869](coverlet-coverage/coverlet#1869)
- Introduce .NET 10 support
[#​1823](coverlet-coverage/coverlet#1823)

## Fixed

- Fix [BUG] Wrong branch rate on IAsyncEnumerable for generic type
[#​1836](coverlet-coverage/coverlet#1836)
- Fix [BUG] Missing Coverage after moving to MTP
[#​1843](coverlet-coverage/coverlet#1843)
- Fix [BUG] No coverage reported when targeting .NET Framework with
8.0.1
[#​1842](coverlet-coverage/coverlet#1842)
- Fix [BUG] Behavior changes between MTP and Legacy (msbuild)
[#​1878](coverlet-coverage/coverlet#1878)
- Fix [BUG] Coverlet.MTP - Unable to load coverlet.mtp.appsettings.json
[#​1880](coverlet-coverage/coverlet#1880)
- Fix [BUG] Coverlet.Collector produces empty report when
Mediator.SourceGenerator is referenced
[#​1718](coverlet-coverage/coverlet#1718) by
<https://github.com/yusyd>
- Fix [BUG] Crash during instrumentation (Methods using
LibraryImport/DllImport have no body)
[#​1762](coverlet-coverage/coverlet#1762)

## Maintenance

- Add comprehensive async method tests and documentation for issue
[#​1864](coverlet-coverage/coverlet#1864)
- Replace Tmds.ExecFunction Package in coverlet.core.coverage.tests
[#​1833](coverlet-coverage/coverlet#1833)
- Add net9.0 and net10.0 targets
[#​1822](coverlet-coverage/coverlet#1822)

[Diff between 8.0.1 and
10.0.0](coverlet-coverage/coverlet@v8.0.1...v10.0.0)

Commits viewable in [compare
view](coverlet-coverage/coverlet@v8.0.1...v10.0.0).
</details>

Updated
[Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer)
from 3.0.47 to 3.0.50.

<details>
<summary>Release notes</summary>

_Sourced from [Meziantou.Analyzer's
releases](https://github.com/meziantou/Meziantou.Analyzer/releases)._

## 3.0.50

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.50>

## What's Changed
* Handle local variable values in MA0173 analyzer by @​meziantou in
meziantou/Meziantou.Analyzer#1097


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.49...3.0.50

## 3.0.49

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.49>

## What's Changed
* MA0182: treat `is` type checks as internal type usage by @​Copilot in
meziantou/Meziantou.Analyzer#1096


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.48...3.0.49

## 3.0.48

NuGet package:
<https://www.nuget.org/packages/Meziantou.Analyzer/3.0.48>

## What's Changed
* Fix MA0004 code fix crash with chained await using by @​meziantou in
meziantou/Meziantou.Analyzer#1094


**Full Changelog**:
meziantou/Meziantou.Analyzer@3.0.47...3.0.48

Commits viewable in [compare
view](meziantou/Meziantou.Analyzer@3.0.47...3.0.50).
</details>

Updated [System.Formats.Asn1](https://github.com/dotnet/dotnet) from
10.0.5 to 10.0.6.

<details>
<summary>Release notes</summary>

_Sourced from [System.Formats.Asn1's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated [System.Text.Json](https://github.com/dotnet/dotnet) from 10.0.5
to 10.0.6.

<details>
<summary>Release notes</summary>

_Sourced from [System.Text.Json's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>
This was referenced May 4, 2026
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