Fix AD0001: NRE in SE for declaration pattern
As reported here and observed inside ascx.cs file:
CSC : error AD0001: Analyzer 'SonarAnalyzer.Rules.CSharp.SymbolicExecutionRunner' threw an exception of type 'SonarAnalyzer.SymbolicExecution.SymbolicExecutionException' with message 'Error processing method: collectiveResultRepeater_ItemDataBound
Inner exception: System.NullReferenceException: Object reference not set to an instance of an object.
at SonarAnalyzer.Helpers.TypeHelper.<>c__DisplayClass20_0.<Implements>b__0(INamedTypeSymbol x)
at System.Linq.ImmutableArrayExtensions.Any[T](ImmutableArray`1 immutableArray, Func`2 predicate)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors.IsPattern.BoolConstraintFromDeclarationPattern(ObjectConstraint valueConstraint, IDeclarationPatternOperationWrapper declaration)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors.IsPattern.BoolConstraintFromPattern(ProgramState state, SymbolicValue value, IPatternOperationWrapper pattern)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors.IsPattern.BoolConstraintFromOperation(ProgramState state, IIsPatternOperationWrapper operation, Boolean isLoopCondition, Int32 visitCount)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors.BranchingProcessor`1.Process(SymbolicContext context, T operation)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationProcessors.MultiProcessor`1.Process(SymbolicContext context)
at SonarAnalyzer.SymbolicExecution.Roslyn.OperationDispatcher.Process(SymbolicContext context)
at SonarAnalyzer.SymbolicExecution.Roslyn.RoslynSymbolicExecution.<ProcessOperation>d__17.MoveNext()
at SonarAnalyzer.SymbolicExecution.Roslyn.RoslynSymbolicExecution.Execute()
at SonarAnalyzer.Rules.SymbolicExecutionRunnerBase.AnalyzeRoslyn(SonarAnalysisContext analysisContext, SonarSyntaxNodeReportingContext nodeContext, ISymbol symbol)'.
We don't have a reproducer (yet).
The only place where this can happen is this line, if declaration.InputType is null. Then, the null value ends up in the extension methods where an NRE is thrown.
I couldn't yet replicate it. I tried with using object, dynamic or generic types in declaration patterns.
The user shared the code. It looks harmless:
var collectiveEmployee = e.Item.DataItem as CollectiveBaseDto;
...
if (collectiveEmployee is CollectiveEmployeeEpldto CollectiveEPLDTOEmp)
Do you know where the call to .Any comes from in the stack trace?
In case InputType is null, then InputType.DerivesOrImplements returns false , because it's null-tolerant everywhere.
I looked again at the stack trace: It is this line:
private static bool Implements(this ITypeSymbol typeSymbol, ISymbol type) =>
typeSymbol is { }
&& typeSymbol.AllInterfaces.Any(x => type.IsDefinition ? x.OriginalDefinition.Equals(type) : x.Equals(type));
It can throw an NRE if type, x or x.OriginalDefinition are null.
-
typeis null ifdeclaration.NarrowedTypeisnull. -
xis null iftypeSymbol.AllInterfacescontains a null reference (probably not possible?). - Can
x.OriginalDefinitionbenull?
The first one seems the most likely to me, but I'm not sure.
This makes sense.
typeis null ifdeclaration.NarrowedTypeisnull.
AllInterfaces returns ImmutableArray that is a struct and cannot be null
OriginalDefinition cannot be null, it defaults to this.
I tried with VSBuild Tools 2019 and 2022. I could not reproduce it.