提交 2021f8f2 编写于 作者: A AlekseyTs

Prevent SemanticModel.GetSymbolInfo from crashing when Me/this is used outside...

Prevent SemanticModel.GetSymbolInfo from crashing when Me/this is used outside of a valid member context. (changeset 1367667)
上级 e424e2ab
......@@ -3113,50 +3113,62 @@ private static void CheckForNullArgument<T>(ImmutableArray<T> argument, string p
private static ParameterSymbol GetThisParameter(TypeSymbol typeOfThis, NamedTypeSymbol containingType, Symbol containingMember, out LookupResultKind resultKind)
{
ParameterSymbol thisParam;
if ((object)containingMember == null || (object)containingType == null)
{
// not in a member of a type (can happen when speculating)
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, typeOfThis);
resultKind = LookupResultKind.NotReferencable;
return new ThisParameterSymbol(containingMember as MethodSymbol, typeOfThis);
}
if (containingMember.IsStatic)
{
// in a static member
resultKind = LookupResultKind.StaticInstanceMismatch;
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, containingType);
}
else
ParameterSymbol thisParam;
switch (containingMember.Kind)
{
if (typeOfThis == ErrorTypeSymbol.UnknownResultType)
{
// in an instance member, but binder considered this/base unreferencable
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, containingType);
resultKind = LookupResultKind.NotReferencable;
}
else
{
switch (containingMember.Kind)
case SymbolKind.Method:
case SymbolKind.Field:
case SymbolKind.Property:
if (containingMember.IsStatic)
{
case SymbolKind.Method:
resultKind = LookupResultKind.Viable;
thisParam = containingMember.EnclosingThisSymbol();
break;
// Fields and properties can't access 'this' since
// initializers are run in the constructor
case SymbolKind.Field:
case SymbolKind.Property:
// in a static member
resultKind = LookupResultKind.StaticInstanceMismatch;
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, containingType);
}
else
{
if (typeOfThis == ErrorTypeSymbol.UnknownResultType)
{
// in an instance member, but binder considered this/base unreferencable
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, containingType);
resultKind = LookupResultKind.NotReferencable;
thisParam = containingMember.EnclosingThisSymbol() ?? new ThisParameterSymbol(null, containingType);
break;
default:
throw ExceptionUtilities.UnexpectedValue(containingMember.Kind);
}
else
{
switch (containingMember.Kind)
{
case SymbolKind.Method:
resultKind = LookupResultKind.Viable;
thisParam = containingMember.EnclosingThisSymbol();
break;
// Fields and properties can't access 'this' since
// initializers are run in the constructor
case SymbolKind.Field:
case SymbolKind.Property:
resultKind = LookupResultKind.NotReferencable;
thisParam = containingMember.EnclosingThisSymbol() ?? new ThisParameterSymbol(null, containingType);
break;
default:
throw ExceptionUtilities.UnexpectedValue(containingMember.Kind);
}
}
}
}
break;
default:
thisParam = new ThisParameterSymbol(containingMember as MethodSymbol, typeOfThis);
resultKind = LookupResultKind.NotReferencable;
break;
}
return thisParam;
......
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
{
......@@ -2313,5 +2315,49 @@ class Program
static void Main() { }
}").VerifyDiagnostics();
}
[Fact, WorkItem(1068547, "DevDiv")]
public void Bug1068547_01()
{
var source =
@"
class Program
{
[System.Diagnostics.DebuggerDisplay(this)]
static void Main(string[] args)
{
}
}";
var comp = CreateCompilationWithMscorlib(source);
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var node = tree.GetRoot().DescendantNodes().Where(n => n.CSharpKind() == SyntaxKind.ThisExpression).Cast<ThisExpressionSyntax>().Single();
var symbolInfo = model.GetSymbolInfo(node);
Assert.Null(symbolInfo.Symbol);
Assert.Equal(CandidateReason.NotReferencable, symbolInfo.CandidateReason);
}
[Fact, WorkItem(1068547, "DevDiv")]
public void Bug1068547_02()
{
var source =
@"
[System.Diagnostics.DebuggerDisplay(this)]
";
var comp = CreateCompilationWithMscorlib(source);
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var node = tree.GetRoot().DescendantNodes().Where(n => n.CSharpKind() == SyntaxKind.ThisExpression).Cast<ThisExpressionSyntax>().Single();
var symbolInfo = model.GetSymbolInfo(node);
Assert.Null(symbolInfo.Symbol);
Assert.Equal(CandidateReason.NotReferencable, symbolInfo.CandidateReason);
}
}
}
......@@ -1199,30 +1199,37 @@ _Default:
containingMember As Symbol,
ByRef resultKind As LookupResultKind) As ParameterSymbol
Dim meParam As ParameterSymbol
If containingMember Is Nothing OrElse containingType Is Nothing Then
' not in a member of a type (can happen when speculating)
meParam = New MeParameterSymbol(containingMember, referenceType)
resultKind = LookupResultKind.NotReferencable
Return New MeParameterSymbol(containingMember, referenceType)
End If
If containingMember.IsShared Then
' in a static member
resultKind = LookupResultKind.MustNotBeInstance
meParam = New MeParameterSymbol(containingMember, containingType)
Dim meParam As ParameterSymbol
Else
If referenceType = ErrorTypeSymbol.UnknownResultType Then
' in an instance member, but binder considered Me/MyBase/MyClass unreferencable
meParam = New MeParameterSymbol(containingMember, containingType)
Select Case containingMember.Kind
Case SymbolKind.Method, SymbolKind.Field, SymbolKind.Property
If containingMember.IsShared Then
' in a static member
resultKind = LookupResultKind.MustNotBeInstance
meParam = New MeParameterSymbol(containingMember, containingType)
Else
If referenceType = ErrorTypeSymbol.UnknownResultType Then
' in an instance member, but binder considered Me/MyBase/MyClass unreferencable
meParam = New MeParameterSymbol(containingMember, containingType)
resultKind = LookupResultKind.NotReferencable
Else
' should be good
resultKind = LookupResultKind.Good
meParam = containingMember.GetMeParameter()
End If
End If
Case Else
meParam = New MeParameterSymbol(containingMember, referenceType)
resultKind = LookupResultKind.NotReferencable
Else
' should be good
resultKind = LookupResultKind.Good
meParam = containingMember.GetMeParameter()
End If
End If
End Select
Return meParam
End Function
......
......@@ -5894,5 +5894,52 @@ BC30516: Overload resolution failed because no accessible 'N' accepts this numbe
Dim conversionC = model.ClassifyConversion(methodGroupSyntax, typeFuncC)
Assert.Equal(ConversionKind.DelegateRelaxationLevelNone, conversionC.Kind)
End Sub
<Fact, WorkItem(1068547, "DevDiv")>
Public Sub Bug1068547_01()
Dim source = <compilation>
<file name="a.vb"><![CDATA[
Module Program
<System.Diagnostics.DebuggerDisplay(Me)>
Sub Main(args As String())
End Sub
End Module
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
Dim tree = comp.SyntaxTrees(0)
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().Where(Function(n) n.VBKind() = SyntaxKind.MeExpression).Cast(Of MeExpressionSyntax)().Single()
Dim symbolInfo = model.GetSymbolInfo(node)
Assert.Null(symbolInfo.Symbol)
Assert.Equal(CandidateReason.NotReferencable, symbolInfo.CandidateReason)
End Sub
<Fact, WorkItem(1068547, "DevDiv")>
Public Sub Bug1068547_02()
Dim source = <compilation>
<file name="a.vb"><![CDATA[
<System.Diagnostics.DebuggerDisplay(Me)>
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
Dim tree = comp.SyntaxTrees(0)
Dim model = comp.GetSemanticModel(tree)
Dim node = tree.GetRoot().DescendantNodes().Where(Function(n) n.VBKind() = SyntaxKind.MeExpression).Cast(Of MeExpressionSyntax)().Single()
Dim symbolInfo = model.GetSymbolInfo(node)
Assert.Null(symbolInfo.Symbol)
Assert.Equal(CandidateReason.NotReferencable, symbolInfo.CandidateReason)
End Sub
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册