Skip to content

NRE for CFG involving indexer with interpolation handler in object initializer #82273

@jcouv

Description

@jcouv

This test shows the problem in main branch.
Note: this issue is also referenced in skipped tests in the features/extensions feature branch.

    [Fact]
    public void InterpolationHandler_Indexer_InObjectInitializer_NonExtension()
    {
        var code = """
            public class Program
            {
                public static void Main()
                {
                    /*<bind>*/
                    _ = new C() { [$"{1}"] = 1 };
                    /*</bind>*/
                }
            }

            public class C
            {
                public int this[[System.Runtime.CompilerServices.InterpolatedStringHandlerArgument("")] CustomHandler h]
                {
                    get => throw null!;
                }
            }

            [System.Runtime.CompilerServices.InterpolatedStringHandler]
            public struct CustomHandler
            {
                public CustomHandler(int literalLength, int formattedCount, C c)
                {
                }

                public void AppendFormatted(int i) {}
            }
            """;

        DiagnosticDescription[] expectedDiagnostics = [
            // (6,24): error CS8976: Interpolated string handler conversions that reference the instance being indexed cannot be used in indexer member initializers.
            //         _ = new C() { [$"{1}"] = 1 };
            Diagnostic(ErrorCode.ERR_InterpolatedStringsReferencingInstanceCannotBeInObjectInitializers, @"$""{1}""").WithLocation(6, 24)
            ];

        var comp = CreateCompilation(code, targetFramework: TargetFramework.NetCoreApp);
        comp.VerifyDiagnostics(expectedDiagnostics);

        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var mainDeclaration = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().First();

        var (graph, symbol) = ControlFlowGraphVerifier.GetControlFlowGraph(mainDeclaration.Body, model);
        ControlFlowGraphVerifier.VerifyGraph(comp, """
... throws or hits assertion ...
""", graph, symbol);
    }

In release mode, we get an NRE:

Message: 
  System.NullReferenceException : Object reference not set to an instance of an object.

Stack Trace: 
  ControlFlowGraphBuilder.VisitInterpolatedStringHandlerArgumentPlaceholder(IInterpolatedStringHandlerArgumentPlaceholderOperation operation, Nullable`1 captureIdForResult) line 6976
  InterpolatedStringHandlerArgumentPlaceholderOperation.Accept[TArgument,TResult](OperationVisitor`2 visitor, TArgument argument) line 10286
  OperationVisitor`2.Visit(IOperation operation, TArgument argument) line 11551
  ControlFlowGraphBuilder.Visit(IOperation operation, Nullable`1 argument) line 7893
  ControlFlowGraphBuilder.VisitAndPushArguments(ImmutableArray`1 arguments, Boolean instancePushed) line 2084
  ...

In debug mode, we get an assertion:

Message: 
  System.InvalidOperationException : _currentInterpolatedStringHandlerArgumentContext != null

Stack Trace: 
  ThrowingTraceListener.Fail(String message, String detailMessage) line 26
  TraceInternal.Fail(String message, String detailMessage)
  Debug.Fail(String message, String detailMessage)
  ControlFlowGraphBuilder.AssertContainingContextIsForThisCreation(IOperation placeholderOperation, Boolean assertArgumentContext) line 63
  ControlFlowGraphBuilder.VisitInterpolatedStringHandlerArgumentPlaceholder(IInterpolatedStringHandlerArgumentPlaceholderOperation operation, Nullable`1 captureIdForResult) line 6974
  InterpolatedStringHandlerArgumentPlaceholderOperation.Accept[TArgument,TResult](OperationVisitor`2 visitor, TArgument argument) line 10286
  OperationVisitor`2.Visit(IOperation operation, TArgument argument) line 11551
  ControlFlowGraphBuilder.Visit(IOperation operation, Nullable`1 argument) line 7893
  ControlFlowGraphBuilder.VisitAndPushArguments(ImmutableArray`1 arguments, Boolean instancePushed) line 2084
  ControlFlowGraphBuilder.VisitArguments(ImmutableArray`1 arguments, Boolean instancePushed) line 2037
  <45 more frames...>
  MethodBodyOperation.Accept[TArgument,TResult](OperationVisitor`2 visitor, TArgument argument) line 8720
  OperationVisitor`2.Visit(IOperation operation, TArgument argument) line 11551
  ControlFlowGraphBuilder.VisitStatement(IOperation operation) line 1248
  ControlFlowGraphBuilder.Create(IOperation body, ControlFlowGraph parent, ControlFlowRegion enclosing, CaptureIdDispenser captureIdDispenser, Context& context) line 136
  ControlFlowGraph.CreateCore(IOperation operation, String argumentNameForException, CancellationToken cancellationToken) line 190
  ControlFlowGraph.Create(IMethodBodyOperation methodBody, CancellationToken cancellationToken) line 167
  ControlFlowGraphVerifier.GetControlFlowGraph(SyntaxNode syntaxNode, SemanticModel model) line 49
  ExtensionTests.InterpolationHandler_Indexer_InObjectInitializer_NonExtension() line 24934
  MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
  MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Metadata

Metadata

Assignees

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions