-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CompoundAssignment.Bug1021941 fail in .net7p6 #63221
Comments
This appears to be a regression in the runtime execution here. Can confirm the same code behaves according to the tests in |
I think compilers code gen is wrong. The address of the receiver is getting popped from the stack as part of the method invocation and that is when the underlying value is supposed to be obtained and dereferenced. We should be able to adjust compiler's code gen to enforce correct behavior by using a reference to a compiler generated temp for the case when receiver is a reference type, thus preventing unexpected receiver change. I think we are doing something like that for conditional access code gen. Hopefully that shouldn't bloat IL too much. |
On desktop framework I can observe an incorrect behavior for the following code in C#:
Observed:
Expected:
Note that conditional access without a class constraint also behaves incorrectly. Equivalent VB code produces the same output as C#:
Looking at IL for
VB:
Both functions push the same reference to the stack. I expect both languages to generate IL that captures argument in a temp and then uses address of that temp for constrained calls. Or some other form of IL that doesn't use references as receivers for the calls. For Shift2, C# version of IL uses
vs. VB version
Expected IL for this case should avoid copying a value type and should copy a reference type. IL for Conditional1 is equivalent for both languages:
Note, that it doesn't use constrained call and doesn't use argument reference as a receiver. The IL looks good to me and it behaves as expected. For Conditional2, IL looks equivalent and problematic for both languages:
|
It looks like there is a problem with just a call: using System;
interface IMoveable
{
void GetName(int x);
}
class Item : IMoveable
{
public string Name {get; set;}
public void GetName(int x)
{
Console.WriteLine("Position GetName for item '{0}'", Name);
}
}
class Program
{
static void Main()
{
var item1 = new Item {Name = "1"};
Call1(item1);
var item2 = new Item {Name = "2"};
Call2(item2);
}
static void Call1<T>(T item) where T : class, IMoveable
{
item.GetName(GetOffset(ref item));
}
static void Call2<T>(T item) where T : IMoveable
{
item.GetName(GetOffset(ref item));
}
static int value = 0;
static int GetOffset<T>(ref T item)
{
item = (T)(IMoveable)new Item {Name = (--value).ToString()};
return 0;
}
} Observed:
Expected:
Equivalent VB code:
Observed:
IL for C#:
IL for VB:
C# version of Call1 doesn't use constrained call, that is why it behaves as expected. |
For some reason unit-tests when executed in VS produce expected output. |
The check that we used to detect value types at runtime didn’t quite work for nullable value types due to special boxing behavior for them. Switching to `typeof(T).IsValueType` check instead. Fixes dotnet#66162. Related to dotnet#63221.
Related to dotnet#63221 Related to dotnet#70256 Related to dotnet#70257 Related to dotnet#70267
Related to dotnet#63221 Related to dotnet#70256 Related to dotnet#70257 Related to dotnet#70267
Found in #63062 - disabling per infraswat to unblock upgrade to .net7p6, integration tests, and merge of -vs-deps back to main
These tests consistently fail (in all legs on multiple retries) on .net7p6 with an error similar to
https://dev.azure.com/dnceng/public/_build/results?buildId=1921926&view=ms.vss-test-web.build-test-results-tab&runId=49765824&resultId=145381&paneView=debug
The text was updated successfully, but these errors were encountered: