提交 194da7ce 编写于 作者: K Kevin Halverson

Merge pull request #5658 from KevinH-MS/BadConst

Work around issue with ISymUnmanagedConstant.GetSignature...
......@@ -519,6 +519,10 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui
Debug.Assert(!info.IsByRef);
Debug.Assert(!info.IsPinned);
var type = info.Type;
if (type.IsErrorType())
{
continue;
}
var constantValue = PdbHelpers.GetConstantValue(type.EnumUnderlyingType(), rawValue);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.DiaSymReader;
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
......@@ -3009,6 +3010,36 @@ .maxstack 1
testData.GetMethodData("<>x.<>m0").VerifyIL(tIL);
}
[WorkItem(955, "https://github.com/aspnet/Home/issues/955")]
[Fact]
public void ConstantWithErrorType()
{
const string source = @"
class Program
{
static void Main()
{
const int a = 1;
}
}";
var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugExe);
var runtime = CreateRuntimeInstance(comp);
var badConst = new MockSymUnmanagedConstant(
"a",
1,
(int bufferLength, out int count, byte[] name) =>
{
count = 0;
return DiaSymReader.SymUnmanagedReaderExtensions.E_NOTIMPL;
});
var debugInfo = new MethodDebugInfoBytes.Builder(constants: new[] {badConst}).Build();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
GetLocals(runtime, "Program.Main", debugInfo, locals, count: 0);
locals.Free();
}
private static void GetLocals(RuntimeInstance runtime, string methodName, bool argumentsOnly, ArrayBuilder<LocalAndMethod> locals, int count, out string typeName, out CompilationTestData testData)
{
var context = CreateMethodContext(runtime, methodName);
......@@ -3025,5 +3056,44 @@ private static void GetLocals(RuntimeInstance runtime, string methodName, bool a
}
Assert.Equal(count, locals.Count);
}
private static void GetLocals(RuntimeInstance runtime, string methodName, MethodDebugInfoBytes debugInfo, ArrayBuilder<LocalAndMethod> locals, int count)
{
ImmutableArray<MetadataBlock> blocks;
Guid moduleVersionId;
ISymUnmanagedReader unused;
int methodToken;
int localSignatureToken;
GetContextState(runtime, methodName, out blocks, out moduleVersionId, out unused, out methodToken, out localSignatureToken);
var symReader = new MockSymUnmanagedReader(
new Dictionary<int, MethodDebugInfoBytes>()
{
{methodToken, debugInfo}
}.ToImmutableDictionary());
var context = EvaluationContext.CreateMethodContext(
default(CSharpMetadataContext),
blocks,
symReader,
moduleVersionId,
methodToken,
methodVersion: 1,
ilOffset: 0,
localSignatureToken: localSignatureToken);
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: null);
Assert.NotNull(assembly);
if (count == 0)
{
Assert.Equal(0, assembly.Count);
}
else
{
Assert.InRange(assembly.Count, 0, int.MaxValue);
}
Assert.Equal(count, locals.Count);
}
}
}
......@@ -33,7 +33,7 @@ internal sealed class Builder
private ArrayBuilder<byte> _bytesBuilder;
private int _recordCount;
public Builder(string[][] importStringGroups = null, bool suppressUsingInfo = false)
public Builder(string[][] importStringGroups = null, bool suppressUsingInfo = false, ISymUnmanagedConstant[] constants = null)
{
_bytesBuilder = ArrayBuilder<byte>.GetInstance();
if (importStringGroups != null && !suppressUsingInfo)
......@@ -45,7 +45,7 @@ public Builder(string[][] importStringGroups = null, bool suppressUsingInfo = fa
var namespaces = importStringGroups == null
? default(ImmutableArray<ISymUnmanagedNamespace>)
: importStringGroups.SelectMany(names => names.Select(name => (ISymUnmanagedNamespace)new MockSymUnmanagedNamespace(name))).ToImmutableArray();
var childScope = new MockSymUnmanagedScope(default(ImmutableArray<ISymUnmanagedScope>), namespaces);
var childScope = new MockSymUnmanagedScope(default(ImmutableArray<ISymUnmanagedScope>), namespaces, constants);
var rootScope = new MockSymUnmanagedScope(ImmutableArray.Create<ISymUnmanagedScope>(childScope), default(ImmutableArray<ISymUnmanagedNamespace>));
_method = new MockSymUnmanagedMethod(rootScope);
}
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.DiaSymReader;
using Roslyn.Utilities;
......@@ -229,13 +230,15 @@ internal sealed class MockSymUnmanagedScope : ISymUnmanagedScope, ISymUnmanagedS
{
private readonly ImmutableArray<ISymUnmanagedScope> _children;
private readonly ImmutableArray<ISymUnmanagedNamespace> _namespaces;
private readonly ISymUnmanagedConstant[] _constants;
private readonly int _startOffset;
private readonly int _endOffset;
public MockSymUnmanagedScope(ImmutableArray<ISymUnmanagedScope> children, ImmutableArray<ISymUnmanagedNamespace> namespaces, int startOffset = 0, int endOffset = 1)
public MockSymUnmanagedScope(ImmutableArray<ISymUnmanagedScope> children, ImmutableArray<ISymUnmanagedNamespace> namespaces, ISymUnmanagedConstant[] constants = null, int startOffset = 0, int endOffset = 1)
{
_children = children;
_namespaces = namespaces;
_constants = constants ?? new ISymUnmanagedConstant[0];
_startOffset = startOffset;
_endOffset = endOffset;
}
......@@ -288,13 +291,17 @@ public int GetParent(out ISymUnmanagedScope pRetVal)
public int GetConstantCount(out int pRetVal)
{
pRetVal = 0;
pRetVal = _constants.Length;
return SymUnmanagedReaderExtensions.S_OK;
}
public int GetConstants(int cConstants, out int pcConstants, ISymUnmanagedConstant[] constants)
{
pcConstants = 0;
pcConstants = _constants.Length;
if (constants != null)
{
Array.Copy(_constants, constants, constants.Length);
}
return SymUnmanagedReaderExtensions.S_OK;
}
}
......@@ -331,6 +338,44 @@ int ISymUnmanagedNamespace.GetVariables(int cVars, out int pcVars, ISymUnmanaged
}
}
internal delegate int GetSignatureDelegate(int bufferLength, out int count, byte[] signature);
internal sealed class MockSymUnmanagedConstant : ISymUnmanagedConstant
{
private readonly string _name;
private readonly object _value;
private readonly GetSignatureDelegate _getSignature;
public MockSymUnmanagedConstant(string name, object value, GetSignatureDelegate getSignature)
{
_name = name;
_value = value;
_getSignature = getSignature;
}
int ISymUnmanagedConstant.GetName(int bufferLength, out int count, char[] name)
{
count = _name.Length + 1; // + 1 for null terminator
Debug.Assert((bufferLength == 0) || (bufferLength == count));
for (int i = 0; i < bufferLength - 1; i++)
{
name[i] = _name[i];
}
return SymUnmanagedReaderExtensions.S_OK;
}
int ISymUnmanagedConstant.GetSignature(int bufferLength, out int count, byte[] signature)
{
return _getSignature(bufferLength, out count, signature);
}
int ISymUnmanagedConstant.GetValue(out object value)
{
value = _value;
return SymUnmanagedReaderExtensions.S_OK;
}
}
internal static class MockSymUnmanagedHelpers
{
public static void TwoPhaseCopy<T>(this ImmutableArray<T> source, int numDesired, out int numRead, T[] destination)
......
......@@ -603,6 +603,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Debug.Assert(Not info.IsByRef)
Debug.Assert(Not info.IsPinned)
Dim type As TypeSymbol = info.Type
If type.IsErrorType() Then
Continue For
End If
Dim constantValue = PdbHelpers.GetConstantValue(type.GetEnumUnderlyingTypeOrSelf(), rawValue)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.Collections.ObjectModel
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation
Imports Roslyn.Test.PdbUtilities
Imports Roslyn.Test.Utilities
......@@ -3194,10 +3193,72 @@ End Class
testData.GetMethodData("<>x.<>m0").VerifyIL(xIL)
End Sub
<WorkItem(955, "https://github.com/aspnet/Home/issues/955")>
<Fact>
Public Sub ConstantWithErrorType()
Const source = "
Module Module1
Sub Main()
Const a = 1
End Sub
End Module"
Dim comp = CreateCompilationWithMscorlib({source}, {MsvbRef}, options:=TestOptions.DebugExe)
Dim runtime = CreateRuntimeInstance(comp)
Dim badConst = New MockSymUnmanagedConstant(
"a",
1,
Function(bufferLength As Integer, ByRef count As Integer, name() As Byte)
count = 0
Return DiaSymReader.SymUnmanagedReaderExtensions.E_NOTIMPL
End Function)
Dim debugInfo = New MethodDebugInfoBytes.Builder(constants:={badConst}).Build()
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
GetLocals(runtime, "Module1.Main", debugInfo, locals, count:=0)
locals.Free()
End Sub
Private Shared Sub GetLocals(runtime As RuntimeInstance, methodName As String, argumentsOnly As Boolean, locals As ArrayBuilder(Of LocalAndMethod), count As Integer, ByRef typeName As String, ByRef testData As CompilationTestData)
Dim context = CreateMethodContext(runtime, methodName)
testData = New CompilationTestData()
Dim assembly = context.CompileGetLocals(locals, argumentsOnly, typeName, testData)
Assert.NotNull(assembly)
If count = 0 Then
Assert.Equal(0, assembly.Count)
Else
Assert.InRange(assembly.Count, 0, Integer.MaxValue)
End If
Assert.Equal(count, locals.Count)
End Sub
Private Shared Sub GetLocals(runtime As RuntimeInstance, methodName As String, debugInfo As MethodDebugInfoBytes, locals As ArrayBuilder(Of LocalAndMethod), count As Integer)
Dim blocks As ImmutableArray(Of MetadataBlock) = Nothing
Dim moduleVersionId As Guid = Nothing
Dim methodToken = 0
Dim localSignatureToken = 0
GetContextState(runtime, methodName, blocks, moduleVersionId, symReader:=Nothing, methodOrTypeToken:=methodToken, localSignatureToken:=localSignatureToken)
Dim symReader = New MockSymUnmanagedReader(
New Dictionary(Of Integer, MethodDebugInfoBytes)() From
{
{methodToken, debugInfo}
}.ToImmutableDictionary())
Dim context = EvaluationContext.CreateMethodContext(
Nothing,
blocks,
MakeDummyLazyAssemblyReaders(),
symReader,
moduleVersionId,
methodToken,
methodVersion:=1,
ilOffset:=0,
localSignatureToken:=localSignatureToken)
Dim assembly = context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=Nothing, testData:=Nothing)
Assert.NotNull(assembly)
If count = 0 Then
Assert.Equal(0, assembly.Count)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册