Skip to content

EBNF incorrect: stackalloc_initializer can be empty (draft-v8). #1607

@kaby76

Description

@kaby76

Describe the bug
Consider the following program.

using System;

unsafe class Program
{
    static void Main()
    {
        // Empty stackalloc initializer -- allocates a zero-length block.
        // Valid C# (accepted by Roslyn); the grammar rule for
        // stackalloc_initializer should allow an empty initializer list.
        int* p = stackalloc int[] {};
        Console.WriteLine("Empty stackalloc: length inferred as 0, pointer is non-null: " + ((IntPtr)p != IntPtr.Zero));

        // Non-empty for contrast
        int* q = stackalloc int[] { 1, 2, 3 };
        Console.WriteLine("Non-empty stackalloc[0]: " + q[0]);
    }
}

This code compiles and runs fine in version 8 of the C# Roslyn compiler. In fact, it explicitly tests this for version 8 of the C# language.

foo.zip

https://github.com/dotnet/roslyn/blob/2ad4aabc7a9dada097e54e544ebba48ab1c05074/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStackAllocInitializerTests.cs#L369

However, the draft-v8 spec is wrong:

stackalloc_initializer
: '{' stackalloc_initializer_element_list '}'
;
stackalloc_initializer_element_list
: stackalloc_element_initializer (',' stackalloc_element_initializer)* ','?
;

The rule should be:

stackalloc_initializer
     : '{' stackalloc_initializer_element_list? '}'
     ;

Or, stackalloc_initializer_element_list should allow for empty.

This feature was introduced in C# 7, so that EBNF is probably wrong as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions