Skip to content

Linker produces unknown value for merged value assigned to array element #117174

@sbomer

Description

@sbomer

Example:

Type[] arr = new Type[1];
arr[0] = string.Empty.Length == 0 ? GetMethods() : GetFields();
// IL2062 (Unknown value)
RequireAll(arr[0]);

I would expect this to instead produce two instances of IL2072, warning about GetMethods/GetFields, like what happens in this example:

Type[] arr = new Type[1];
if (string.Empty.Length == 0)
    arr[0] = GetMethods();
else
    arr[0] = GetFields();
RequireAll(arr[0]); // IL2072 (GetMethods/GetFields)

I debugged this a little - what happens is this:

  • We put a reference to an ArrayValue on the stack.
  • After the call to GetMethods() in one branch, and GetFields() in another, we merge stacks
  • Merging stacks allocates a new dictionary of array values for the merged stack slot holding the array reference.
    • This dictionary is now a different one than the original dictionary of values tracked in the locals of the method
  • We assign a merged value to the new dictionary.
  • We read arr[0] from the original ArrayValue which doesn't have any elements assigned.

I think this is a specific case of dotnet/linker#2158 - we need to ensure that the array reference on the stack and that in the tracked locals are the same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-Tools-ILLink.NET linker development as well as trimming analyzers

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions