dotnet / dotnet/sdk

DoNotPassDisposablesIntoUnawaitedTasksAnalyzer crashes with NRE

Open
#53,926 3 comments 2 reactions 2 assignees Claimed by @jeffhandley View on GitHub
Area-Microsoft.CodeAnalysis.NetAnalyzers Bug
Dominant language
C#
Stars
3.2k
Forks
1.3k
PR merge metrics
PR metrics pending

Description

Minimal repro (SDK 11.0.100-preview.3, `Microsoft.CodeAnalysis.CSharp.NetAnalyzers` v11.1.26.17106):

```xml


Library
net9.0
enable
true
latest-all

```

```csharp
using System.IO;
using System.Threading;
using System.Threading.Tasks;

public class C
{
private StreamReader _field = null!;

public async Task M(CancellationToken ct)
{
CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
Task t = Local(_field, cts.Token); // AD0001 crash
await Task.Yield();
await t;
cts.Dispose();

async Task Local(StreamReader r, CancellationToken token)
{
await r.ReadLineAsync(token);
}
}
}
```

Three conditions are all required to trigger it:
1. `CancellationTokenSource` created **without** `using` declaration
2. Instance field passed **directly** as argument to a local async function (not via a local variable)
3. Resulting `Task` stored but **not immediately awaited** (there's other code between the call and the `await`)

Workaround: introduce a local for the field — `StreamReader local = _field; Task t = Local(local, cts.Token);`

_Originally posted by @Copilot in https://github.com/dotnet/runtime/pull/126987#discussion_r3095258323_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.