-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
String.Concat optimization causes exception with MarshalByRefObject field access #37830
Comments
I agree, this looks like it was caused by the optimization, and I think we should make a slight adjustment to the optimization to access MarshalByRefObjects appropriately to call through the transparent proxy. |
We need to copy it to a local variable first. This was exposed by a new Roslyn optimization for String.Concat (see dotnet/roslyn#37830).
…6119) We need to copy it to a local variable first. This was exposed by a new Roslyn optimization for String.Concat (see dotnet/roslyn#37830).
…6119) We need to copy it to a local variable first. This was exposed by a new Roslyn optimization for String.Concat (see dotnet/roslyn#37830). (cherry picked from commit ec35e14)
@jcouv Could you take a look at this? I think we should consider it for 3.0 servicing |
I think the fix should be pretty simple -- checking to see if the receiver at roslyn/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs Line 430 in 2ac72ce
MarshalByRefObject is good enough to restore compat.
|
Are we sure this is the only bug of this nature? When implementing the Test verfiying the behavior: https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenReadonlyStructTests.cs#L2137 Don't we need to add the same check there to truly close out this bug? |
We actually emitted object.ToString calls on readonly refs to structs without a defensive copy even before the readonly members feature. See the following example using the Roslyn 2.9.0 compiler: https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgJgIwFgBQyDMABAM7ABOArgMbAEDKBA3jgSwWAHY1gDczr+BZOgBsggCwEAsgAoOdYgEpGfVqwD6BALzEAdABUA9rTIcA5tIW9sqgL44bQA=== |
Okay. I'm able to repro the issue. The old code would just load the field value: // Console.WriteLine("test_field: " + r.test_field);
IL_0021: ldstr "test_field: "
IL_0026: ldloc.2
IL_0027: ldfld int32 R1::test_field
IL_002c: box [mscorlib]System.Int32
IL_0031: call string [mscorlib]System.String::Concat(object, object)
IL_0036: call void [mscorlib]System.Console::WriteLine(string) But the new code (after // Console.WriteLine("test_field: " + r.test_field.ToString());
IL_0021: ldstr "test_field: "
IL_0026: ldloc.2
IL_0027: ldflda int32 R1::test_field
IL_002c: call instance string [mscorlib]System.Int32::ToString()
IL_0031: call string [mscorlib]System.String::Concat(string, string)
IL_0036: call void [mscorlib]System.Console::WriteLine(string) |
Fixed in 16.4 preview 2. |
Version Used: 3.3.0-beta3-19406-05 (a190599)
Steps to Reproduce:
We hit this while upgrading the Roslyn we use in Mono from 3.1 to 3.3 and one of our unit tests broke (the repro code is a stripped down version of the test).
This is almost certainly because of the String.Concat optimization from #35006 and might be considered by design, but we still wanted to at least start a conversation.
Especially since this code doesn't trigger a CS1690 warning that would show up if you just did
string s = o.test_field.ToString();
./cc @jaredpar @marek-safar
The text was updated successfully, but these errors were encountered: