提交 bb42aa49 编写于 作者: R Rikki Gibson

Adjust tests and add reproducer

上级 c99ad715
......@@ -2692,7 +2692,7 @@ struct S1
public int field;
public static implicit operator S1(int arg) => new S1 {field = arg };
public void Mutate()
{
field = 42;
......@@ -2761,6 +2761,390 @@ .maxstack 1
IL_005a: ldfld ""int Program.S1.field""
IL_005f: call ""void System.Console.WriteLine(int)""
IL_0064: ret
}");
}
[Fact]
[WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")]
public void ConditionalAccessUnconstrainedTField()
{
var source = @"using System;
public class C<T>
{
public C(T t) => this.t = t;
public C(){}
private T t;
public void Print()
{
Console.WriteLine(t?.ToString());
Console.WriteLine(t);
}
}
public struct S
{
int a;
public override string ToString() => a++.ToString();
}
public static class Program
{
public static void Main()
{
new C<S>().Print();
new C<S?>().Print();
new C<S?>(new S()).Print();
new C<string>(""hello"").Print();
new C<string>().Print();
}
}";
var verify = CompileAndVerify(source, expectedOutput: @"0
1
0
0
hello
hello");
verify.VerifyIL("C<T>.Print()", @"
{
// Code size 75 (0x4b)
.maxstack 2
.locals init (T V_0)
IL_0000: ldarg.0
IL_0001: ldflda ""T C<T>.t""
IL_0006: ldloca.s V_0
IL_0008: initobj ""T""
IL_000e: ldloc.0
IL_000f: box ""T""
IL_0014: brtrue.s IL_002a
IL_0016: ldobj ""T""
IL_001b: stloc.0
IL_001c: ldloca.s V_0
IL_001e: ldloc.0
IL_001f: box ""T""
IL_0024: brtrue.s IL_002a
IL_0026: pop
IL_0027: ldnull
IL_0028: br.s IL_0035
IL_002a: constrained. ""T""
IL_0030: callvirt ""string object.ToString()""
IL_0035: call ""void System.Console.WriteLine(string)""
IL_003a: ldarg.0
IL_003b: ldfld ""T C<T>.t""
IL_0040: box ""T""
IL_0045: call ""void System.Console.WriteLine(object)""
IL_004a: ret
}");
}
[Fact]
[WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")]
public void ConditionalAccessReadonlyUnconstrainedTField()
{
var source = @"using System;
public class C<T>
{
public C(T t) => this.t = t;
public C(){}
readonly T t;
public void Print()
{
Console.WriteLine(t?.ToString());
Console.WriteLine(t);
}
}
public struct S
{
int a;
public override string ToString() => a++.ToString();
}
public static class Program
{
public static void Main()
{
new C<S>().Print();
new C<S?>().Print();
new C<S?>(new S()).Print();
new C<string>(""hello"").Print();
new C<string>().Print();
}
}
";
var verify = CompileAndVerify(source, expectedOutput: @"0
0
0
0
hello
hello");
verify.VerifyIL("C<T>.Print()", @"
{
// Code size 78 (0x4e)
.maxstack 2
.locals init (T V_0,
T V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.t""
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: ldloca.s V_1
IL_000b: initobj ""T""
IL_0011: ldloc.1
IL_0012: box ""T""
IL_0017: brtrue.s IL_002d
IL_0019: ldobj ""T""
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloc.1
IL_0022: box ""T""
IL_0027: brtrue.s IL_002d
IL_0029: pop
IL_002a: ldnull
IL_002b: br.s IL_0038
IL_002d: constrained. ""T""
IL_0033: callvirt ""string object.ToString()""
IL_0038: call ""void System.Console.WriteLine(string)""
IL_003d: ldarg.0
IL_003e: ldfld ""T C<T>.t""
IL_0043: box ""T""
IL_0048: call ""void System.Console.WriteLine(object)""
IL_004d: ret
}");
}
[Fact]
[WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")]
public void ConditionalAccessUnconstrainedTLocal()
{
var source = @"using System;
public class C<T>
{
public C(T t) => this.t = t;
public C(){}
private T t;
public void Print()
{
var temp = t;
Console.WriteLine(temp?.ToString());
Console.WriteLine(temp);
}
}
public struct S
{
int a;
public override string ToString() => a++.ToString();
}
public static class Program
{
public static void Main()
{
new C<S>().Print();
new C<S?>().Print();
new C<S?>(new S()).Print();
new C<string>(""hello"").Print();
new C<string>().Print();
}
}";
var verify = CompileAndVerify(source, expectedOutput: @"0
1
0
1
hello
hello");
verify.VerifyIL("C<T>.Print()", @"
{
// Code size 48 (0x30)
.maxstack 1
.locals init (T V_0) //temp
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.t""
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: box ""T""
IL_000d: brtrue.s IL_0012
IL_000f: ldnull
IL_0010: br.s IL_001f
IL_0012: ldloca.s V_0
IL_0014: constrained. ""T""
IL_001a: callvirt ""string object.ToString()""
IL_001f: call ""void System.Console.WriteLine(string)""
IL_0024: ldloc.0
IL_0025: box ""T""
IL_002a: call ""void System.Console.WriteLine(object)""
IL_002f: ret
}");
}
[Fact]
[WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")]
public void ConditionalAccessUnconstrainedTTemp()
{
var source = @"using System;
public class C<T>
{
public C(T t) => this.t = t;
public C(){}
T t;
T M() => t;
public void Print() => Console.WriteLine(M()?.ToString());
}
public static class Program
{
public static void Main()
{
new C<int>().Print();
new C<int?>().Print();
new C<int?>(0).Print();
new C<string>(""hello"").Print();
new C<string>().Print();
}
}
";
var verify = CompileAndVerify(source, expectedOutput: @"0
0
hello
");
verify.VerifyIL("C<T>.Print()", @"
{
// Code size 62 (0x3e)
.maxstack 2
.locals init (T V_0,
T V_1)
IL_0000: ldarg.0
IL_0001: call ""T C<T>.M()""
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: ldloca.s V_1
IL_000b: initobj ""T""
IL_0011: ldloc.1
IL_0012: box ""T""
IL_0017: brtrue.s IL_002d
IL_0019: ldobj ""T""
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloc.1
IL_0022: box ""T""
IL_0027: brtrue.s IL_002d
IL_0029: pop
IL_002a: ldnull
IL_002b: br.s IL_0038
IL_002d: constrained. ""T""
IL_0033: callvirt ""string object.ToString()""
IL_0038: call ""void System.Console.WriteLine(string)""
IL_003d: ret
}");
}
[Fact, WorkItem(40690, "https://github.com/dotnet/roslyn/issues/40690")]
public void ConditionalAccess_GenericExtension_ValueTuple()
{
var source = @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace bug
{
public static class Extension
{
public static String GetValue(this object value) => value?.ToString();
}
public partial class BGen<__T__>
{
public (Int64, __T__) Data { get; }
public BGen((Int64, __T__) data)
{
this.Data = data;
}
internal String Value
{
get
{
/// This works fine:
//var i2 = Data.Item2;
//var q2 = i2?.GetValue();
// This causes the AccessViolation:
var q2 = Data.Item2?.GetValue();
return q2;
}
}
}
class Program
{
static void Main(string[] args)
{
var i = new BGen<string>((0, ""foo""));
var r = i.Value;
Console.WriteLine($""Hello World: {{string.Join(',', r)}}"");
}
}
}
";
var verifier = CompileAndVerify(source);
verifier.VerifyIL("bug.BGen<__T__>.Value.get", @"
{
// Code size 65 (0x41)
.maxstack 2
.locals init (System.ValueTuple<long, __T__> V_0,
__T__ V_1)
IL_0000: ldarg.0
IL_0001: call ""System.ValueTuple<long, __T__> bug.BGen<__T__>.Data.get""
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: ldflda ""__T__ System.ValueTuple<long, __T__>.Item2""
IL_000e: ldloca.s V_1
IL_0010: initobj ""__T__""
IL_0016: ldloc.1
IL_0017: box ""__T__""
IL_001c: brtrue.s IL_0031
IL_001e: ldobj ""__T__""
IL_0023: stloc.1
IL_0024: ldloca.s V_1
IL_0026: ldloc.1
IL_0027: box ""__T__""
IL_002c: brtrue.s IL_0031
IL_002e: pop
IL_002f: ldnull
IL_0030: ret
IL_0031: ldobj ""__T__""
IL_0036: box ""__T__""
IL_003b: call ""string bug.Extension.GetValue(object)""
IL_0040: ret
}");
}
}
......
......@@ -5306,6 +5306,335 @@ C1
]]>)
End Sub
<Fact>
<WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")>
Public Sub CodeGen_ConditionalAccessUnconstrainedTField()
Dim c = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Public Class C(Of T)
Public Sub New(t As T)
field = t
End Sub
Public Sub New()
End Sub
Private field As T
Public Sub Print()
Console.WriteLine(field?.ToString())
Console.WriteLine(field)
End Sub
End Class
Public Structure S
Private a As Integer
Public Overrides Function ToString() As String
Dim result = a.ToString()
a = a + 1
Return result
End Function
End Structure
Module Program
Sub Main()
Call New C(Of S)().Print()
Call New C(Of S?)().Print()
Call New C(Of S?)(New S()).Print()
Call New C(Of String)("hello").Print()
Call New C(Of String)().Print()
End Sub
End Module
</file>
</compilation>, expectedOutput:="0
1
0
0
hello
hello")
c.VerifyIL("C(Of T).Print()",
<![CDATA[
{
// Code size 75 (0x4b)
.maxstack 2
.locals init (T V_0)
IL_0000: ldarg.0
IL_0001: ldflda "C(Of T).field As T"
IL_0006: ldloca.s V_0
IL_0008: initobj "T"
IL_000e: ldloc.0
IL_000f: box "T"
IL_0014: brtrue.s IL_002a
IL_0016: ldobj "T"
IL_001b: stloc.0
IL_001c: ldloca.s V_0
IL_001e: ldloc.0
IL_001f: box "T"
IL_0024: brtrue.s IL_002a
IL_0026: pop
IL_0027: ldnull
IL_0028: br.s IL_0035
IL_002a: constrained. "T"
IL_0030: callvirt "Function Object.ToString() As String"
IL_0035: call "Sub System.Console.WriteLine(String)"
IL_003a: ldarg.0
IL_003b: ldfld "C(Of T).field As T"
IL_0040: box "T"
IL_0045: call "Sub System.Console.WriteLine(Object)"
IL_004a: ret
}
]]>)
End Sub
<Fact>
<WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")>
Public Sub CodeGen_ConditionalAccessReadonlyUnconstrainedTField()
Dim c = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Public Class C(Of T)
Public Sub New(ByVal t As T)
field = t
End Sub
Public Sub New()
End Sub
ReadOnly field As T
Public Sub Print()
Console.WriteLine(field?.ToString())
Console.WriteLine(field)
End Sub
End Class
Public Structure S
Private a As Integer
Public Overrides Function ToString() As String
Return Math.Min(System.Threading.Interlocked.Increment(a), a - 1).ToString()
End Function
End Structure
Module Program
Sub Main()
Call New C(Of S)().Print()
Call New C(Of S?)().Print()
Call New C(Of S?)(New S()).Print()
Call New C(Of String)("hello").Print()
Call New C(Of String)().Print()
End Sub
End Module
</file>
</compilation>, expectedOutput:="0
0
0
0
hello
hello")
c.VerifyIL("C(Of T).Print()",
<![CDATA[
{
// Code size 78 (0x4e)
.maxstack 2
.locals init (T V_0,
T V_1)
IL_0000: ldarg.0
IL_0001: ldfld "C(Of T).field As T"
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: ldloca.s V_1
IL_000b: initobj "T"
IL_0011: ldloc.1
IL_0012: box "T"
IL_0017: brtrue.s IL_002d
IL_0019: ldobj "T"
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloc.1
IL_0022: box "T"
IL_0027: brtrue.s IL_002d
IL_0029: pop
IL_002a: ldnull
IL_002b: br.s IL_0038
IL_002d: constrained. "T"
IL_0033: callvirt "Function Object.ToString() As String"
IL_0038: call "Sub System.Console.WriteLine(String)"
IL_003d: ldarg.0
IL_003e: ldfld "C(Of T).field As T"
IL_0043: box "T"
IL_0048: call "Sub System.Console.WriteLine(Object)"
IL_004d: ret
}
]]>)
End Sub
<Fact>
<WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")>
Public Sub CodeGen_ConditionalAccessUnconstrainedTLocal()
Dim c = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Public Class C(Of T)
Public Sub New(ByVal t As T)
field = t
End Sub
Public Sub New()
End Sub
Private field As T
Public Sub Print()
Dim temp = field
Console.WriteLine(temp?.ToString())
Console.WriteLine(temp)
End Sub
End Class
Public Structure S
Private a As Integer
Public Overrides Function ToString() As String
Return Math.Min(System.Threading.Interlocked.Increment(a), a - 1).ToString()
End Function
End Structure
Module Program
Sub Main()
Call New C(Of S)().Print()
Call New C(Of S?)().Print()
Call New C(Of S?)(New S()).Print()
Call New C(Of String)("hello").Print()
Call New C(Of String)().Print()
End Sub
End Module
</file>
</compilation>, expectedOutput:="0
1
0
1
hello
hello")
c.VerifyIL("C(Of T).Print()",
<![CDATA[
{
// Code size 48 (0x30)
.maxstack 1
.locals init (T V_0) //temp
IL_0000: ldarg.0
IL_0001: ldfld "C(Of T).field As T"
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: box "T"
IL_000d: brtrue.s IL_0012
IL_000f: ldnull
IL_0010: br.s IL_001f
IL_0012: ldloca.s V_0
IL_0014: constrained. "T"
IL_001a: callvirt "Function Object.ToString() As String"
IL_001f: call "Sub System.Console.WriteLine(String)"
IL_0024: ldloc.0
IL_0025: box "T"
IL_002a: call "Sub System.Console.WriteLine(Object)"
IL_002f: ret
}
]]>)
End Sub
<Fact>
<WorkItem(3519, "https://github.com/dotnet/roslyn/issues/35319")>
Public Sub CodeGen_ConditionalAccessUnconstrainedTTemp()
Dim c = CompileAndVerify(
<compilation>
<file name="a.vb">
Imports System
Public Class C(Of T)
Public Sub New(ByVal t As T)
field = t
End Sub
Public Sub New()
End Sub
Private field As T
Private Function M() As T
Return field
End Function
Public Sub Print()
Console.WriteLine(M()?.ToString())
End Sub
End Class
Module Program
Sub Main()
Call New C(Of Integer)().Print()
Call New C(Of Integer?)().Print()
Call New C(Of Integer?)(0).Print()
Call New C(Of String)("hello").Print()
Call New C(Of String)().Print()
End Sub
End Module
</file>
</compilation>, expectedOutput:="0
0
hello
")
c.VerifyIL("C(Of T).Print()",
<![CDATA[
{
// Code size 62 (0x3e)
.maxstack 2
.locals init (T V_0,
T V_1)
IL_0000: ldarg.0
IL_0001: call "Function C(Of T).M() As T"
IL_0006: stloc.0
IL_0007: ldloca.s V_0
IL_0009: ldloca.s V_1
IL_000b: initobj "T"
IL_0011: ldloc.1
IL_0012: box "T"
IL_0017: brtrue.s IL_002d
IL_0019: ldobj "T"
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloc.1
IL_0022: box "T"
IL_0027: brtrue.s IL_002d
IL_0029: pop
IL_002a: ldnull
IL_002b: br.s IL_0038
IL_002d: constrained. "T"
IL_0033: callvirt "Function Object.ToString() As String"
IL_0038: call "Sub System.Console.WriteLine(String)"
IL_003d: ret
}
]]>)
End Sub
<Fact()>
Public Sub InlineNullableIsTrue_01()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册