未验证 提交 429e61ea 编写于 作者: A AlekseyTs 提交者: GitHub

Fix NullReferenceException thrown while building IOperation node for dynamic...

Fix NullReferenceException thrown while building IOperation node for dynamic object member initializer. (#23162)

Fixes #23154.
上级 a604cefe
......@@ -591,7 +591,9 @@ private IObjectOrCollectionInitializerOperation CreateBoundCollectionInitializer
private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitializerMember boundObjectInitializerMember)
{
Lazy<IOperation> instance = boundObjectInitializerMember.MemberSymbol.IsStatic ?
Symbol memberSymbol = boundObjectInitializerMember.MemberSymbol;
Lazy<IOperation> instance = memberSymbol?.IsStatic == true ?
OperationFactory.NullOperation :
new Lazy<IOperation>(() =>
new InstanceReferenceExpression(
......@@ -606,17 +608,27 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia
Optional<object> constantValue = ConvertToOptional(boundObjectInitializerMember.ConstantValue);
bool isImplicit = boundObjectInitializerMember.WasCompilerGenerated;
switch (boundObjectInitializerMember.MemberSymbol.Kind)
if ((object)memberSymbol == null)
{
Debug.Assert(boundObjectInitializerMember.Type.IsDynamic());
Lazy<ImmutableArray<IOperation>> arguments = new Lazy<ImmutableArray<IOperation>>(() => boundObjectInitializerMember.Arguments.SelectAsArray(n => Create(n)));
ImmutableArray<string> argumentNames = boundObjectInitializerMember.ArgumentNamesOpt.NullToEmpty();
ImmutableArray<RefKind> argumentRefKinds = boundObjectInitializerMember.ArgumentRefKindsOpt.NullToEmpty();
return new LazyDynamicIndexerAccessExpression(instance, arguments, argumentNames, argumentRefKinds, _semanticModel, syntax, type, constantValue, isImplicit);
}
switch (memberSymbol.Kind)
{
case SymbolKind.Field:
var field = (FieldSymbol)boundObjectInitializerMember.MemberSymbol;
var field = (FieldSymbol)memberSymbol;
bool isDeclaration = false;
return new LazyFieldReferenceExpression(field, isDeclaration, instance, _semanticModel, syntax, type, constantValue, isImplicit);
case SymbolKind.Event:
var eventSymbol = (EventSymbol)boundObjectInitializerMember.MemberSymbol;
var eventSymbol = (EventSymbol)memberSymbol;
return new LazyEventReferenceExpression(eventSymbol, instance, _semanticModel, syntax, type, constantValue, isImplicit);
case SymbolKind.Property:
var property = (PropertySymbol)boundObjectInitializerMember.MemberSymbol;
var property = (PropertySymbol)memberSymbol;
Lazy<ImmutableArray<IArgumentOperation>> arguments;
if (!boundObjectInitializerMember.Arguments.Any())
{
......
......@@ -604,5 +604,183 @@ public void M1()
VerifyOperationTreeAndDiagnosticsForTest<ObjectCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
[WorkItem(23154, "https://github.com/dotnet/roslyn/issues/23154")]
public void ObjectCreationWithDynamicMemberInitializer_01()
{
string source = @"
#pragma warning disable 0169
class A
{
dynamic this[int x, int y]
{
get
{
return new A();
}
}
dynamic this[string x, string y]
{
get
{
throw null;
}
}
int X, Y, Z;
static void Main()
{
dynamic x = 1;
new A {/*<bind>*/[y: x, x: x] = { X = 1, Y = 1, Z = 1 }/*</bind>*/ };
}
}
";
string expectedOperationTree = @"
IMemberInitializerOperation (OperationKind.MemberInitializer, Type: dynamic) (Syntax: '[y: x, x: x ... 1, Z = 1 }')
InitializedMember:
IDynamicIndexerAccessOperation (OperationKind.DynamicIndexerAccess, Type: dynamic) (Syntax: '[y: x, x: x]')
Expression:
IInstanceReferenceOperation (OperationKind.InstanceReference, Type: A, IsImplicit) (Syntax: '[y: x, x: x]')
Arguments(2):
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ArgumentNames(2):
""y""
""x""
ArgumentRefKinds(0)
Initializer:
IObjectOrCollectionInitializerOperation (OperationKind.ObjectOrCollectionInitializer, Type: dynamic) (Syntax: '{ X = 1, Y = 1, Z = 1 }')
Initializers(3):
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: dynamic) (Syntax: 'X = 1')
Left:
IOperation: (OperationKind.None, Type: null) (Syntax: 'X')
Right:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: dynamic) (Syntax: 'Y = 1')
Left:
IOperation: (OperationKind.None, Type: null) (Syntax: 'Y')
Right:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: dynamic) (Syntax: 'Z = 1')
Left:
IOperation: (OperationKind.None, Type: null) (Syntax: 'Z')
Right:
ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 1) (Syntax: '1')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
[WorkItem(23154, "https://github.com/dotnet/roslyn/issues/23154")]
public void ObjectCreationWithDynamicMemberInitializer_02()
{
string source = @"
#pragma warning disable 0169
class A
{
dynamic this[int x, int y]
{
get
{
return new A();
}
}
dynamic this[string x, string y]
{
get
{
throw null;
}
}
int X, Y, Z;
static void Main()
{
dynamic x = 1;
new A {/*<bind>*/[y: x, x: x] = { }/*</bind>*/ };
}
}
";
string expectedOperationTree = @"
IMemberInitializerOperation (OperationKind.MemberInitializer, Type: dynamic) (Syntax: '[y: x, x: x] = { }')
InitializedMember:
IDynamicIndexerAccessOperation (OperationKind.DynamicIndexerAccess, Type: dynamic) (Syntax: '[y: x, x: x]')
Expression:
IInstanceReferenceOperation (OperationKind.InstanceReference, Type: A, IsImplicit) (Syntax: '[y: x, x: x]')
Arguments(2):
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ArgumentNames(2):
""y""
""x""
ArgumentRefKinds(0)
Initializer:
IObjectOrCollectionInitializerOperation (OperationKind.ObjectOrCollectionInitializer, Type: dynamic) (Syntax: '{ }')
Initializers(0)
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<AssignmentExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
[WorkItem(23154, "https://github.com/dotnet/roslyn/issues/23154")]
public void ObjectCreationWithDynamicMemberInitializer_03()
{
string source = @"
#pragma warning disable 0169
class A
{
dynamic this[int x, int y]
{
get
{
return new A();
}
}
dynamic this[string x, string y]
{
get
{
throw null;
}
}
int X, Y, Z;
static void Main()
{
dynamic x = 1;
new A {/*<bind>*/[y: x, x: x]/*</bind>*/ = { } };
}
}
";
string expectedOperationTree = @"
IDynamicIndexerAccessOperation (OperationKind.DynamicIndexerAccess, Type: dynamic) (Syntax: '[y: x, x: x]')
Expression:
IInstanceReferenceOperation (OperationKind.InstanceReference, Type: A, IsImplicit) (Syntax: '[y: x, x: x]')
Arguments(2):
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ILocalReferenceOperation: x (OperationKind.LocalReference, Type: dynamic) (Syntax: 'x')
ArgumentNames(2):
""y""
""x""
ArgumentRefKinds(0)
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<ExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册