Skip to content

Commit

Permalink
Fix null reference exception in DoNotCreateTaskCompletionSourceWithWr…
Browse files Browse the repository at this point in the history
…ongArguments (#3812)

IConversionOperation.Operand.Type can return null.
  • Loading branch information
stephentoub committed Jul 2, 2020
1 parent e0578cd commit d89638c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ public override void Initialize(AnalysisContext context)
compilationContext.RegisterOperationAction(operationContext =>
{
// Warn if this is `new TCS(object ...)` with an expression of type `TaskContinuationOptions` as the argument.
// Warn if this is `new TCS(object)` with an expression of type `TaskContinuationOptions` as the argument.
var objectCreation = (IObjectCreationOperation)operationContext.Operation;
if ((objectCreation.Type.OriginalDefinition.Equals(tcsGenericType) || (tcsType != null && objectCreation.Type.OriginalDefinition.Equals(tcsType))) &&
!objectCreation.Constructor.Parameters.IsEmpty && objectCreation.Constructor.Parameters[0].Type.SpecialType == SpecialType.System_Object &&
!objectCreation.Arguments.IsEmpty && objectCreation.Arguments[0].Value is IConversionOperation conversionOperation &&
objectCreation.Constructor.Parameters.Length == 1 &&
objectCreation.Constructor.Parameters[0].Type.SpecialType == SpecialType.System_Object &&
objectCreation.Arguments.Length == 1 &&
objectCreation.Arguments[0].Value is IConversionOperation conversionOperation &&
conversionOperation.Operand.Type != null &&
conversionOperation.Operand.Type.Equals(taskContinutationOptionsType))
{
operationContext.ReportDiagnostic(conversionOperation.CreateDiagnostic(Rule));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,23 @@ class C
{
void M()
{
// Use TCS correctly without options
new TaskCompletionSource<int>(null);
new TaskCompletionSource<int>(""hello"");
new TaskCompletionSource<int>(new object());
new TaskCompletionSource<int>(42);
// Uses TaskCreationOptions correctly
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
var validEnum = TaskCreationOptions.RunContinuationsAsynchronously;
new TaskCompletionSource<int>(validEnum);
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
new TaskCompletionSource<int>(this.MyProperty);
new TaskCompletionSource<int>(new object(), validEnum);
new TaskCompletionSource<int>(new object(), TaskCreationOptions.RunContinuationsAsynchronously);
new TaskCompletionSource<int>(new object(), this.MyProperty);
new TaskCompletionSource<int>(null, validEnum);
new TaskCompletionSource<int>(null, TaskCreationOptions.RunContinuationsAsynchronously);
new TaskCompletionSource<int>(null, this.MyProperty);
// We only pay attention to things of type TaskContinuationOptions
new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously.ToString());
Expand Down

0 comments on commit d89638c

Please sign in to comment.