提交 0feafba7 编写于 作者: V VSadov

Merge pull request #7739 from VSadov/fix7388

Fix for unverifiable codegen for conditional access when result constrained to class
......@@ -2486,15 +2486,18 @@ private void EmitDefaultValue(TypeSymbol type, bool used, CSharpSyntaxNode synta
{
if (used)
{
var constantValue = type.GetDefaultValue();
if (constantValue != null)
// default type parameter values must be emitted as 'initobj' regardless of constraints
if (!type.IsTypeParameter())
{
_builder.EmitConstantValue(constantValue);
}
else
{
EmitInitObj(type, true, syntaxNode);
var constantValue = type.GetDefaultValue();
if (constantValue != null)
{
_builder.EmitConstantValue(constantValue);
return;
}
}
EmitInitObj(type, true, syntaxNode);
}
}
......
......@@ -31,7 +31,7 @@ private enum ConditionalAccessLoweringKind
// IL gen can generate more compact code for certain conditional accesses
// by utilizing stack dup/pop instructions
internal BoundExpression RewriteConditionalAccess(BoundConditionalAccess node, bool used, BoundExpression rewrittenWhenNull = null)
internal BoundExpression RewriteConditionalAccess(BoundConditionalAccess node, bool used)
{
Debug.Assert(!_inExpressionLambda);
......@@ -41,7 +41,7 @@ internal BoundExpression RewriteConditionalAccess(BoundConditionalAccess node, b
// Check trivial case
if (loweredReceiver.IsDefaultValue())
{
return rewrittenWhenNull ?? _factory.Default(node.Type);
return _factory.Default(node.Type);
}
ConditionalAccessLoweringKind loweringKind;
......@@ -154,7 +154,7 @@ internal BoundExpression RewriteConditionalAccess(BoundConditionalAccess node, b
GetNullableMethod(node.Syntax, loweredReceiver.Type, SpecialMember.System_Nullable_T_get_HasValue) :
null,
loweredAccessExpression,
rewrittenWhenNull,
null,
currentConditionalAccessID,
type);
......@@ -180,7 +180,7 @@ internal BoundExpression RewriteConditionalAccess(BoundConditionalAccess node, b
result = RewriteConditionalOperator(node.Syntax,
condition,
consequence,
rewrittenWhenNull ?? _factory.Default(nodeType),
_factory.Default(nodeType),
null,
nodeType);
......
......@@ -6843,5 +6843,56 @@ .locals init (int? V_0)
}
");
}
[WorkItem(7388, "https://github.com/dotnet/roslyn/issues/7388")]
[Fact]
public void ConditionalClassConstrained001()
{
var source = @"
using System;
namespace ConsoleApplication9
{
class Program
{
static void Main(string[] args)
{
var v = new A<object>();
System.Console.WriteLine(A<object>.Test(v));
}
public class A<T> : object where T : class
{
public T Value { get { return (T)(object)42; }}
public static T Test(A<T> val)
{
return val?.Value;
}
}
}
}
";
var verifier = CompileAndVerify(source, expectedOutput: @"42");
verifier.VerifyIL("ConsoleApplication9.Program.A<T>.Test(ConsoleApplication9.Program.A<T>)", @"
{
// Code size 20 (0x14)
.maxstack 1
.locals init (T V_0)
IL_0000: ldarg.0
IL_0001: brtrue.s IL_000d
IL_0003: ldloca.s V_0
IL_0005: initobj ""T""
IL_000b: ldloc.0
IL_000c: ret
IL_000d: ldarg.0
IL_000e: call ""T ConsoleApplication9.Program.A<T>.Value.get""
IL_0013: ret
}");
}
}
}
......@@ -141,7 +141,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Dim typeTo = conversion.Type
If conversion.Operand.IsNothingLiteral Then
Debug.Assert(typeTo.IsValueType AndAlso Not typeTo.IsTypeParameter)
Debug.Assert(typeTo.IsValueType OrElse typeTo.IsTypeParameter)
If used Then
'TODO: used
......
......@@ -2436,6 +2436,62 @@ C1
End Sub
<Fact(), WorkItem(7388, "https://github.com/dotnet/roslyn/issues/7388")>
Public Sub ConstrainedToClass()
Dim compilationDef =
<compilation>
<file name="a.vb"><![CDATA[
Module Module1
Sub Main()
Dim v As New A(Of Object)
System.Console.WriteLine(A(Of Object).test(v))
End Sub
End Module
Public Class A(Of T As Class)
Public ReadOnly Property Value As T
Get
Return CType(CObj(42), T)
End Get
End Property
Public Shared Function test(val As A(Of T)) As T
Return val?.Value
End Function
End Class
]]></file>
</compilation>
Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(compilationDef, TestOptions.ReleaseExe)
Dim verifier = CompileAndVerify(compilation, expectedOutput:=
<![CDATA[
42
]]>)
verifier.VerifyIL("A(Of T).test(A(Of T))",
<![CDATA[
{
// Code size 20 (0x14)
.maxstack 1
.locals init (T V_0)
IL_0000: ldarg.0
IL_0001: brtrue.s IL_000d
IL_0003: ldloca.s V_0
IL_0005: initobj "T"
IL_000b: ldloc.0
IL_000c: ret
IL_000d: ldarg.0
IL_000e: call "Function A(Of T).get_Value() As T"
IL_0013: ret
}
]]>)
End Sub
<Fact()>
Public Sub CodeGen_01()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册