From 0e976990f42f5f1aae5c5b022d27637563452fa3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 23 May 2016 21:40:07 -0700 Subject: [PATCH 01/13] Bug 217740: Repro and test harness for C# --- .../AttributeTests_WellKnownAttributes.cs | 51 ++++++++++++++++++- .../Core/Portable/MetadataReader/PEModule.cs | 2 +- .../Symbols/Attributes/CommonAttributeData.cs | 11 +++- .../AttributeTests_WellKnownAttributes.vb | 45 ++++++++++++++++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index ad7f9138a28a3..7d8020ddda553 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using System.Text; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; @@ -416,6 +417,54 @@ public static void Main() {} CompileAndVerify(text, additionalRefs: new[] { SystemRef }, sourceSymbolValidator: attributeValidator); } + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttribute() + { + #region "Source" + var source = @" +using System; +using System.Runtime.CompilerServices; + +public class Bar +{ + public void Method([DateTimeConstant(-1)]DateTime p1) { } +} +"; + #endregion + + // The native C# compiler emits this: + // .param[1] + // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( + // 01 00 ff ff ff ff ff ff ff ff 00 00 + // ) + Action verifier = (module) => + { + var bar = (NamedTypeSymbol)((ModuleSymbol)module).GlobalNamespace.GetMember("Bar"); + var method = (MethodSymbol)bar.GetMember("Method"); + var parameters = method.GetParameters(); + var theParameter = (PEParameterSymbol)parameters[0]; + var peModule = (PEModuleSymbol)module; + + Assert.Equal(ParameterAttributes.None, theParameter.Flags); + + // let's find the attribute in the PE metadata + var attributeInfo = PEModule.FindTargetAttribute(peModule.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute); + Assert.True(attributeInfo.HasValue); + + long attributeValue; + Assert.True(peModule.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, out attributeValue)); + Assert.Equal(-1L, attributeValue); // check the attribute is constructed with a -1 + + // check .param has no value + var constantHandle = peModule.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue(); + Assert.True(constantHandle.IsNil); + }; + + var comp = CompileAndVerify(source, additionalRefs: new[] { SystemRef }, symbolValidator: verifier); + comp.VerifyDiagnostics(); + } + [Fact] public void TestDecimalConstantAttribute() { @@ -3176,7 +3225,7 @@ public static int Main () // the resulting code does not need to verify // This is consistent with Dev10 behavior - CompileAndVerify(source, options: TestOptions.ReleaseDll, verify:false, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator); + CompileAndVerify(source, options: TestOptions.ReleaseDll, verify: false, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator); } [Fact, WorkItem(544507, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544507")] diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 36bc839f422cc..b2160249f3d82 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1242,7 +1242,7 @@ internal bool TryExtractStringValueFromAttribute(CustomAttributeHandle handle, o return TryExtractValueFromAttribute(handle, out value, s_attributeStringValueExtractor); } - private bool TryExtractLongValueFromAttribute(CustomAttributeHandle handle, out long value) + internal bool TryExtractLongValueFromAttribute(CustomAttributeHandle handle, out long value) { return TryExtractValueFromAttribute(handle, out value, s_attributeLongValueExtractor); } diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs index 4aa49f21909ce..d94a9f4ba60bb 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs @@ -183,7 +183,16 @@ internal ConstantValue DecodeDecimalConstantValue() internal ConstantValue DecodeDateTimeConstantValue() { - return ConstantValue.Create(new DateTime(this.CommonConstructorArguments[0].DecodeValue(SpecialType.System_Int64))); + long value = this.CommonConstructorArguments[0].DecodeValue(SpecialType.System_Int64); + + // if value is outside this range, DateTime would throw when constructed + if (value < DateTime.MinValue.Ticks || value > DateTime.MaxValue.Ticks) + { + // Treat as-is parameter doesn't have default + return ConstantValue.Unset; + } + + return ConstantValue.Create(new DateTime(value)); } #endregion diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index b90a6a7389387..d46c217fbf269 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -10,6 +10,7 @@ Imports System.Reflection.Metadata Imports System.Reflection.Metadata.Ecma335 Imports System.Runtime.InteropServices Imports System.Text +Imports Microsoft.CodeAnalysis Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics Public Class AttributeTests_WellKnownAttributes @@ -433,6 +434,50 @@ End Class CompileAndVerify(source, sourceSymbolValidator:=attributeValidator) End Sub + + + Public Sub DateTimeConstantAttribute() + Dim source = + + p1 As DateTime) + End Sub +End Class +]]> + + + + Dim symValidator As Action(Of ModuleSymbol) = + Sub(peModule) + + Dim bar = peModule.GlobalNamespace.GetMember(Of NamedTypeSymbol)("Bar") + Dim method = bar.GetMember(Of MethodSymbol)("Method") + Dim parameters = method.Parameters + Dim theParameter = DirectCast(parameters(0), PEParameterSymbol) + Dim peModuleSymbol = DirectCast(peModule, PEModuleSymbol) + + Assert.Equal(ParameterAttributes.None, theParameter.ParamFlags) + + ' let's find the attribute in the PE metadata + Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) + Assert.True(attributeInfo.HasValue) + + Dim attributeValue As Long + Assert.True(peModuleSymbol.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, attributeValue)) + Assert.Equal(-1L, attributeValue) + + ' check .param has no value + Dim constantHandle = peModuleSymbol.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue() + Assert.True(constantHandle.IsNil) + End Sub + + CompileAndVerify(source, symbolValidator:=symValidator) + End Sub + Public Sub TestDecimalConstantAttribute() From 255d39d8583aa7e63dfba9e7bcf2a2dd7ca19666 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 24 May 2016 12:01:39 -0700 Subject: [PATCH 02/13] Testing and fixing loading scenario in C# and VB --- .../AttributeTests_WellKnownAttributes.cs | 52 ++++++++++++++++ .../Core/Portable/MetadataReader/PEModule.cs | 11 +++- .../AttributeTests_WellKnownAttributes.vb | 62 +++++++++++++++++-- 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 7d8020ddda553..4d59e2e467848 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -465,6 +465,58 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } comp.VerifyDiagnostics(); } + [Fact, WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void LoadingDateTimeConstantWithBadValue() + { + var ilsource = @" +.class public auto ansi beforefieldinit C + extends [mscorlib]System.Object +{ + .method public hidebysig instance valuetype [mscorlib]System.DateTime + Method([opt] valuetype [mscorlib]System.DateTime p) cil managed + { + .param [1] + .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 FF FF FF FF FF FF FF FF 00 00 ) + // Code size 7 (0x7) + .maxstack 1 + .locals init (valuetype [mscorlib]System.DateTime V_0) + IL_0000: nop + IL_0001: ldarg.1 + IL_0002: stloc.0 + IL_0003: br.s IL_0005 + + IL_0005: ldloc.0 + IL_0006: ret + } // end of method C::Method + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method C::.ctor + +} // end of class C + +"; + + var cssource = @" +public class D +{ + public static void Main() + { + System.Console.WriteLine(new C().Method().Ticks); + } +} +"; + + var ilReference = CompileIL(ilsource); + CompileAndVerify(cssource, expectedOutput: "0", additionalRefs: new[] { ilReference }); + } + [Fact] public void TestDecimalConstantAttribute() { diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index b2160249f3d82..41bd0fdad7a5d 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1046,7 +1046,16 @@ internal bool HasDateTimeConstantAttribute(EntityHandle token, out ConstantValue AttributeInfo info = FindLastTargetAttribute(token, AttributeDescription.DateTimeConstantAttribute); if (info.HasValue && TryExtractLongValueFromAttribute(info.Handle, out value)) { - defaultValue = ConstantValue.Create(new DateTime(value)); + // if value is outside this range, DateTime would throw when constructed + if (value < DateTime.MinValue.Ticks || value > DateTime.MaxValue.Ticks) + { + defaultValue = ConstantValue.Bad; + } + else + { + defaultValue = ConstantValue.Create(new DateTime(value)); + } + return true; } diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index d46c217fbf269..bacb7c6512c2f 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -1,9 +1,5 @@ ' 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 Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.CodeAnalysis.VisualBasic.Symbols -Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE -Imports Roslyn.Test.Utilities Imports System.Collections.Immutable Imports System.Reflection Imports System.Reflection.Metadata @@ -11,6 +7,10 @@ Imports System.Reflection.Metadata.Ecma335 Imports System.Runtime.InteropServices Imports System.Text Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE +Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics Public Class AttributeTests_WellKnownAttributes @@ -478,6 +478,60 @@ End Class CompileAndVerify(source, symbolValidator:=symValidator) End Sub + + + Public Sub LoadingDateTimeConstantWithBadValue() + Dim ilSource = + + Dim source = + + + + + + Dim ilReference = CompileIL(ilSource.Value) + CompileAndVerify(source, expectedOutput:="0", additionalRefs:={ilReference}) + End Sub + Public Sub TestDecimalConstantAttribute() From 8cfaf3407a15e8eea294a1cc1710144beba2aca2 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 24 May 2016 13:12:58 -0700 Subject: [PATCH 03/13] Verifying VB case using attribute on field --- .../AttributeTests_WellKnownAttributes.cs | 1 + .../AttributeTests_WellKnownAttributes.vb | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 4d59e2e467848..7d92b9952c67b 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -515,6 +515,7 @@ public static void Main() var ilReference = CompileIL(ilsource); CompileAndVerify(cssource, expectedOutput: "0", additionalRefs: new[] { ilReference }); + // The native compiler would produce a working exe, but that exe would fail at runtime } [Fact] diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index bacb7c6512c2f..0b4760e856c9e 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -478,6 +478,72 @@ End Class CompileAndVerify(source, symbolValidator:=symValidator) End Sub + + + Public Sub LoadingDateTimeConstantWithBadValueOnField() + Dim ilSource = + + Dim source = + + + + + + Dim ilReference = CompileIL(ilSource.Value) + CompileAndVerify(source, expectedOutput:="621558279390000000", additionalRefs:={ilReference}) + ' This behavior hasn't changed from native VB compiler + End Sub + Public Sub LoadingDateTimeConstantWithBadValue() @@ -530,6 +596,7 @@ End Class Dim ilReference = CompileIL(ilSource.Value) CompileAndVerify(source, expectedOutput:="0", additionalRefs:={ilReference}) + ' The native compiler would produce a working exe, but that exe would fail at runtime End Sub From 1b0abed5426124e9cf550359cbd8ba7617f2103e Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 25 May 2016 09:28:18 -0700 Subject: [PATCH 04/13] Adding more tests --- .../AttributeTests_WellKnownAttributes.cs | 95 ++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 7d92b9952c67b..d8ce7a73db2a0 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -461,7 +461,100 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } Assert.True(constantHandle.IsNil); }; - var comp = CompileAndVerify(source, additionalRefs: new[] { SystemRef }, symbolValidator: verifier); + var comp = CompileAndVerify(source, symbolValidator: verifier); + comp.VerifyDiagnostics(); + } + + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttributeReferencedViaCompilationRef() + { + #region "Source" + var source1 = @" +using System; +using System.Runtime.CompilerServices; + +public class Bar +{ + public void Method([DateTimeConstant(-1)]DateTime p1) { } +} +"; + + var source2 = @" +public class Consumer +{ + public static void M() + { + new Bar().Method(); + } +} +"; + #endregion + + var libComp = CreateCompilationWithMscorlib(source1); + var libCompRef = new CSharpCompilationReference(libComp); + + var comp2 = CreateCompilationWithMscorlib(source2, new[] { libCompRef }); + comp2.VerifyDiagnostics( + // (6,19): error CS7036: There is no argument given that corresponds to the required formal parameter 'p1' of 'Bar.Method(DateTime)' + // new Bar().Method(); + Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "Method").WithArguments("p1", "Bar.Method(System.DateTime)").WithLocation(6, 19) + ); + + var libAssemblyRef = libComp.EmitToImageReference(); + var comp3 = CreateCompilationWithMscorlib(source2, new[] { libAssemblyRef }); + comp3.VerifyDiagnostics( + // (6,19): error CS7036: There is no argument given that corresponds to the required formal parameter 'p1' of 'Bar.Method(DateTime)' + // new Bar().Method(); + Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "Method").WithArguments("p1", "Bar.Method(System.DateTime)").WithLocation(6, 19) + ); + } + + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttributeWithDefaultValue() + { + #region "Source" + var source = @" +using System; +using System.Runtime.CompilerServices; + +public class Bar +{ + public void M1([DateTimeConstant(-1)] DateTime x = default(DateTime)) { } +} +"; + #endregion + + // The native C# compiler emits this: + // .method public hidebysig instance void M1([opt] valuetype[mscorlib] System.DateTime x) cil managed + // { + // .param [1] = nullref + // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 FF FF FF FF FF FF FF FF 00 00 ) + Action verifier = (module) => + { + var bar = (NamedTypeSymbol)((ModuleSymbol)module).GlobalNamespace.GetMember("Bar"); + var method = (MethodSymbol)bar.GetMember("M1"); + var parameters = method.GetParameters(); + var theParameter = (PEParameterSymbol)parameters[0]; + var peModule = (PEModuleSymbol)module; + + Assert.Equal(ParameterAttributes.Optional | ParameterAttributes.HasDefault, theParameter.Flags); + + // let's find the attribute in the PE metadata + var attributeInfo = PEModule.FindTargetAttribute(peModule.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute); + Assert.True(attributeInfo.HasValue); + + long attributeValue; + Assert.True(peModule.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, out attributeValue)); + Assert.Equal(-1L, attributeValue); // check the attribute is constructed with a -1 + + // check .param has no value + var constantValue = peModule.Module.GetParamDefaultValue(theParameter.Handle); + Assert.Equal(ConstantValue.Null, constantValue); + }; + + var comp = CompileAndVerify(source, symbolValidator: verifier); comp.VerifyDiagnostics(); } From a2072f07cb2e5e702a1af8dc4c1af7e9c0a73a4b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 25 May 2016 09:57:24 -0700 Subject: [PATCH 05/13] Adding VB tests --- .../AttributeTests_WellKnownAttributes.cs | 10 +- .../AttributeTests_WellKnownAttributes.vb | 119 +++++++++++++++--- 2 files changed, 111 insertions(+), 18 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index d8ce7a73db2a0..b71f67523cb9f 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -467,7 +467,7 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } [Fact] [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] - public void DateTimeConstantAttributeReferencedViaCompilationRef() + public void DateTimeConstantAttributeReferencedViaRef() { #region "Source" var source1 = @" @@ -521,7 +521,11 @@ public void DateTimeConstantAttributeWithDefaultValue() public class Bar { - public void M1([DateTimeConstant(-1)] DateTime x = default(DateTime)) { } + public DateTime M1([DateTimeConstant(-1)] DateTime x = default(DateTime)) { return x; } + public static void Main() + { + Console.WriteLine(new Bar().M1().Ticks); + } } "; #endregion @@ -554,7 +558,7 @@ public class Bar Assert.Equal(ConstantValue.Null, constantValue); }; - var comp = CompileAndVerify(source, symbolValidator: verifier); + var comp = CompileAndVerify(source, expectedOutput: "0", symbolValidator: verifier); comp.VerifyDiagnostics(); } diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index 0b4760e856c9e..5fa7186bd3263 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -478,6 +478,107 @@ End Class CompileAndVerify(source, symbolValidator:=symValidator) End Sub + + + Public Sub DateTimeConstantAttributeWithDefaultValue() + Dim source = + + Optional p1 As DateTime = # 8/23/1970 3:45:39AM #) As DateTime + Return p1 + End Function + Public Shared Sub Main() + Console.WriteLine(New Bar().Method().Ticks) + End Sub +End Class +]]> + + + + ' The native VB compiler emits this: + ' .method public instance void Method([opt] valuetype [mscorlib]System.DateTime p1) cil managed + ' { + ' .param [1] + ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 80 73 3E 42 F6 37 A0 08 00 00 ) + ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 FF FF FF FF FF FF FF FF 00 00 ) + Dim symValidator As Action(Of ModuleSymbol) = + Sub(peModule) + + Dim bar = peModule.GlobalNamespace.GetMember(Of NamedTypeSymbol)("Bar") + Dim method = bar.GetMember(Of MethodSymbol)("Method") + Dim parameters = method.Parameters + Dim theParameter = DirectCast(parameters(0), PEParameterSymbol) + Dim peModuleSymbol = DirectCast(peModule, PEModuleSymbol) + + Assert.Equal(ParameterAttributes.Optional, theParameter.ParamFlags) + + ' let's find the attribute in the PE metadata + Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) + Assert.True(attributeInfo.HasValue) + + Dim attributeValue As Long + Assert.True(peModuleSymbol.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, attributeValue)) + Assert.Equal(621558279390000000, attributeValue) + + ' check .param has no value + Dim constantHandle = peModuleSymbol.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue() + Assert.True(constantHandle.IsNil) + End Sub + + ' This is the same output as the native VB compiler + CompileAndVerify(source, expectedOutput:="621558279390000000", symbolValidator:=symValidator) + End Sub + + + + + Public Sub DateTimeConstantAttributeReferencedViaRef() + Dim source1 = + + p1 As DateTime) + End Sub +End Class +]]> + + + + Dim source2 = + + + + + + Dim libComp = CreateCompilationWithMscorlib(source1) + Dim libCompRef = New VisualBasicCompilationReference(libComp) + + Dim comp2 = CreateCompilationWithMscorlib(source2, references:={libCompRef}) + comp2.VerifyDiagnostics( + Diagnostic(ERRID.ERR_OmittedArgument2, "Method").WithArguments("p1", "Public Sub Method(p1 As Date)").WithLocation(4, 14) + ) + + Dim libAssemblyRef = libComp.EmitToImageReference() + Dim comp3 = CreateCompilationWithMscorlib(source2, references:={libAssemblyRef}) + comp3.VerifyDiagnostics( + Diagnostic(ERRID.ERR_OmittedArgument2, "Method").WithArguments("p1", "Public Sub Method(p1 As Date)").WithLocation(4, 14) + ) + End Sub + Public Sub LoadingDateTimeConstantWithBadValueOnField() @@ -501,23 +602,11 @@ End Class { // Code size 29 (0x1d) .maxstack 2 - .locals init (valuetype [mscorlib]System.DateTime V_0, - valuetype [mscorlib]System.DateTime V_1, - valuetype [mscorlib]System.DateTime V_2, - valuetype [mscorlib]System.DateTime V_3, - valuetype [mscorlib]System.DateTime V_4, - valuetype [mscorlib]System.DateTime V_5, - valuetype [mscorlib]System.DateTime V_6, - valuetype [mscorlib]System.DateTime V_7, - valuetype [mscorlib]System.DateTime V_8, - valuetype [mscorlib]System.DateTime V_9, - valuetype [mscorlib]System.DateTime V_10, - valuetype [mscorlib]System.DateTime V_11, - valuetype [mscorlib]System.DateTime V_12) + .locals init (valuetype [mscorlib]System.DateTime V_0) IL_0000: ldc.i8 0x8a037f6423e7380 IL_0009: newobj instance void [mscorlib]System.DateTime::.ctor(int64) - IL_000e: stloc.s V_12 - IL_0010: ldloca.s V_12 + IL_000e: stloc.s V_0 + IL_0010: ldloca.s V_0 IL_0012: call instance int64 [mscorlib]System.DateTime::get_Ticks() IL_0017: call void [mscorlib]System.Console::WriteLine(int64) IL_001c: ret From 95233090342f0bb4e13f9b465e3f05c0830dbda9 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 25 May 2016 19:39:13 -0700 Subject: [PATCH 06/13] Adding tests --- .../AttributeTests_WellKnownAttributes.cs | 42 +++++++- .../AttributeTests_WellKnownAttributes.vb | 100 +++++++++++++----- 2 files changed, 112 insertions(+), 30 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index b71f67523cb9f..5f02c89820351 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -446,7 +446,7 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } var theParameter = (PEParameterSymbol)parameters[0]; var peModule = (PEModuleSymbol)module; - Assert.Equal(ParameterAttributes.None, theParameter.Flags); + Assert.Equal(ParameterAttributes.HasDefault, theParameter.Flags); // let's find the attribute in the PE metadata var attributeInfo = PEModule.FindTargetAttribute(peModule.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute); @@ -457,8 +457,10 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } Assert.Equal(-1L, attributeValue); // check the attribute is constructed with a -1 // check .param has no value - var constantHandle = peModule.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue(); - Assert.True(constantHandle.IsNil); + //var constantHandle = peModule.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue(); + //Assert.True(constantHandle.IsNil); + var constantValue = peModule.Module.GetParamDefaultValue(theParameter.Handle); + Assert.Equal(ConstantValue.Null, constantValue); }; var comp = CompileAndVerify(source, symbolValidator: verifier); @@ -512,7 +514,7 @@ public static void M() [Fact] [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] - public void DateTimeConstantAttributeWithDefaultValue() + public void DateTimeConstantAttributeWithBadDefaultValue() { #region "Source" var source = @" @@ -562,6 +564,38 @@ public static void Main() comp.VerifyDiagnostics(); } + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttributeWithValidDefaultValue() + { + #region "Source" + var source = @" +using System; +using System.Runtime.CompilerServices; + +public class Bar +{ + public DateTime M1([DateTimeConstant(42)] DateTime x = default(DateTime)) { return x; } + public static void Main() + { + Console.WriteLine(new Bar().M1().Ticks); + } +} +"; + #endregion + + // The native C# compiler emits this: + // .param [1] = nullref + // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = (01 00 2A 00 00 00 00 00 00 00 00 00 ) + + var comp = CreateCompilationWithMscorlib(source); + comp.VerifyDiagnostics( + // (7,60): error CS8017: The parameter has multiple distinct default values. + // public DateTime M1([DateTimeConstant(42)] DateTime x = default(DateTime)) { return x; } + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "default(DateTime)").WithLocation(7, 60) + ); + } + [Fact, WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] public void LoadingDateTimeConstantWithBadValue() { diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index 5fa7186bd3263..eb129b377670a 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -480,7 +480,7 @@ End Class - Public Sub DateTimeConstantAttributeWithDefaultValue() + Public Sub DateTimeConstantAttributeWithBadDefaultValue() Dim source = + + + + + Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) + + Dim libAssemblyRef = libComp.EmitToImageReference() + Dim comp3 = CompileAndVerify(source2, expectedOutput:="0", additionalRefs:={libAssemblyRef}) End Sub + + + Public Sub DateTimeConstantAttributeWithValidDefaultValue() + Dim source = + + Optional p1 As DateTime = # 8/23/1970 3:45:39AM #) As DateTime + Return p1 + End Function + Public Shared Sub Main() + Console.WriteLine(New Bar().Method().Ticks) + End Sub +End Class +]]> + + + + ' The native VB compiler emits this: + ' .method public instance valuetype [mscorlib]System.DateTime + ' Method([opt] valuetype [mscorlib]System.DateTime p1) cil managed + ' { + ' .param [1] + ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 2A 00 00 00 00 00 00 00 00 00 ) + ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 80 73 3E 42 F6 37 A0 08 00 00 ) + + Dim comp = CreateCompilationWithMscorlib(source) + AssertTheseDiagnostics(comp, + Optional p1 As DateTime = # 8/23/1970 3:45:39AM #) As DateTime + ~~~~~~~~~~~~~~~~~~~~~~~ +]]>) + End Sub @@ -568,15 +626,21 @@ End Class Dim libCompRef = New VisualBasicCompilationReference(libComp) Dim comp2 = CreateCompilationWithMscorlib(source2, references:={libCompRef}) - comp2.VerifyDiagnostics( - Diagnostic(ERRID.ERR_OmittedArgument2, "Method").WithArguments("p1", "Public Sub Method(p1 As Date)").WithLocation(4, 14) - ) + AssertTheseDiagnostics(comp2, + ) Dim libAssemblyRef = libComp.EmitToImageReference() Dim comp3 = CreateCompilationWithMscorlib(source2, references:={libAssemblyRef}) - comp3.VerifyDiagnostics( - Diagnostic(ERRID.ERR_OmittedArgument2, "Method").WithArguments("p1", "Public Sub Method(p1 As Date)").WithLocation(4, 14) - ) + AssertTheseDiagnostics(comp3, + ) End Sub @@ -586,7 +650,7 @@ End Class .class public auto ansi C extends [mscorlib]System.Object { - .field private static initonly valuetype [mscorlib]System.DateTime f + .field public static initonly valuetype [mscorlib]System.DateTime F .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 ff ff ff ff ff ff ff ff 00 00 ) .method public specialname rtspecialname instance void .ctor() cil managed @@ -597,21 +661,6 @@ End Class IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method C::.ctor - - .method public instance void Method() cil managed - { - // Code size 29 (0x1d) - .maxstack 2 - .locals init (valuetype [mscorlib]System.DateTime V_0) - IL_0000: ldc.i8 0x8a037f6423e7380 - IL_0009: newobj instance void [mscorlib]System.DateTime::.ctor(int64) - IL_000e: stloc.s V_0 - IL_0010: ldloca.s V_0 - IL_0012: call instance int64 [mscorlib]System.DateTime::get_Ticks() - IL_0017: call void [mscorlib]System.Console::WriteLine(int64) - IL_001c: ret - } // end of method C::Method - } // end of class C ]]> @@ -620,8 +669,7 @@ End Class From 77443815062c30f95a76b12c27a8e266937a4619 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 25 May 2016 20:19:20 -0700 Subject: [PATCH 07/13] More tests on fields with double-attributes --- .../AttributeTests_WellKnownAttributes.cs | 63 ++++++++ .../Core/Portable/MetadataReader/PEModule.cs | 2 +- .../AttributeTests_WellKnownAttributes.vb | 150 +++++++++++++++++- 3 files changed, 212 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 5f02c89820351..e07086af58559 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -596,6 +596,69 @@ public static void Main() ); } + + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttributeWithBadDefaultValueOnField() + { + #region "Source" + var source = @" +using System; +using System.Runtime.CompilerServices; + +public class C +{ + [DateTimeConstant(-1)] + public DateTime F = default(DateTime); + + public static void Main() + { + System.Console.WriteLine(new C().F.Ticks); + } +} +"; + #endregion + + // The native C# compiler emits this: + // .field public valuetype[mscorlib] System.DateTime F + // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 FF FF FF FF FF FF FF FF 00 00 ) + + // using the native compiler, this code outputs 0 + var comp = CompileAndVerify(source, expectedOutput: "0"); + comp.VerifyDiagnostics(); + } + + [Fact] + [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] + public void DateTimeConstantAttributeWithValidDefaultValueOnField() + { + #region "Source" + var source = @" +using System; +using System.Runtime.CompilerServices; + +public class C +{ + [DateTimeConstant(42)] + public DateTime F = default(DateTime); + + public static void Main() + { + System.Console.WriteLine(new C().F.Ticks); + } +} +"; + #endregion + + // The native C# compiler emits this: + // .field public valuetype[mscorlib] System.DateTime F + // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 2A 00 00 00 00 00 00 00 00 00 ) + + // Using the native compiler, the code executes to output 0 + var comp = CompileAndVerify(source, expectedOutput: "0"); + comp.VerifyDiagnostics(); + } + [Fact, WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] public void LoadingDateTimeConstantWithBadValue() { diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 41bd0fdad7a5d..60bd17401849d 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1995,7 +1995,7 @@ internal int GetTargetAttributeSignatureIndex(CustomAttributeHandle customAttrib /// signatures array, -1 if /// this is not the target attribute. /// - private static int GetTargetAttributeSignatureIndex(MetadataReader metadataReader, CustomAttributeHandle customAttribute, AttributeDescription description) + internal static int GetTargetAttributeSignatureIndex(MetadataReader metadataReader, CustomAttributeHandle customAttribute, AttributeDescription description) { const int No = -1; EntityHandle ctor; diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index eb129b377670a..c9847c30fabb8 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -516,6 +516,11 @@ End Class Assert.Equal(ParameterAttributes.Optional, theParameter.ParamFlags) + ' verify only one instance of the attribute + Dim attributes = peModuleSymbol.Module.MetadataReader.GetCustomAttributes(theParameter.Handle) + Dim datetimeAttributes = attributes.Where(Function(attribute) CodeAnalysis.PEModule.GetTargetAttributeSignatureIndex(peModuleSymbol.Module.MetadataReader, attribute, AttributeDescription.DateTimeConstantAttribute) <> -1) + Assert.Equal(1, datetimeAttributes.Count()) + ' let's find the attribute in the PE metadata Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) Assert.True(attributeInfo.HasValue) @@ -592,6 +597,138 @@ BC37226: The parameter has multiple distinct default values. ]]>) End Sub + + + + Public Sub DateTimeConstantAttributeWithBadDefaultValueOnField() + Dim source = + + + Public F As DateTime = # 8/23/1970 3:45:39AM # + + Public Shared Sub Main() + Console.WriteLine(New Bar().F.Ticks) + End Sub +End Class +]]> + + + + ' The native VB compiler emits this: + Dim symValidator As Action(Of ModuleSymbol) = + Sub(peModule) + + 'Dim bar = peModule.GlobalNamespace.GetMember(Of NamedTypeSymbol)("Bar") + 'Dim method = bar.GetMember(Of MethodSymbol)("F") + 'Dim parameters = method.Parameters + 'Dim theParameter = DirectCast(parameters(0), PEParameterSymbol) + 'Dim peModuleSymbol = DirectCast(peModule, PEModuleSymbol) + + 'Assert.Equal(ParameterAttributes.Optional, theParameter.ParamFlags) + + '' let's find the attribute in the PE metadata + 'Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) + 'Assert.True(attributeInfo.HasValue) + + 'Dim attributeValue As Long + 'Assert.True(peModuleSymbol.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, attributeValue)) + 'Assert.Equal(621558279390000000, attributeValue) + + '' check .param has no value + 'Dim constantHandle = peModuleSymbol.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue() + 'Assert.True(constantHandle.IsNil) + End Sub + + ' This is the same output as the native VB compiler + Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000", symbolValidator:=symValidator) + comp.VerifyDiagnostics() + + Dim libComp = CreateCompilationWithMscorlib(source) + Dim libCompRef = New VisualBasicCompilationReference(libComp) + + Dim source2 = + + + + + + Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) + + ' Using the native compiler, this code crashes at runtime: Unhandled Exception: System.ArgumentOutOfRangeException: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks. + ' Also the compiler gives a warning: warning BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. + Dim libAssemblyRef = libComp.EmitToImageReference() + Dim comp3 = CreateCompilationWithMscorlib(source2, references:={libAssemblyRef}) + comp3.AssertTheseDiagnostics() + + End Sub + + + + Public Sub DateTimeConstantAttributeWithValidDefaultValueOnField() + Dim source = + + + Public F As DateTime = # 8/23/1970 3:45:39AM # + + Public Shared Sub Main() + Console.WriteLine(New Bar().F.Ticks) + End Sub +End Class +]]> + + + + ' The native VB compiler emits this: + + ' With the native VB compiler, this code outputs 621558279390000000 + Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000") + comp.VerifyDiagnostics() + + Dim libComp = CreateCompilationWithMscorlib(source) + Dim libCompRef = New VisualBasicCompilationReference(libComp) + + Dim source2 = + + + + + + Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) + + ' With the native compiler, this code outputs 42 + ' But it gives a warning: warning BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. + Dim libAssemblyRef = libComp.EmitToImageReference() + Dim comp3 = CompileAndVerify(source2, expectedOutput:="42", additionalRefs:={libAssemblyRef}) + AssertTheseDiagnostics(comp3.Compilation) + + End Sub + Public Sub DateTimeConstantAttributeReferencedViaRef() @@ -676,9 +813,18 @@ End Class + ' Using the native compiler, this code outputs 621558279390000000 Dim ilReference = CompileIL(ilSource.Value) - CompileAndVerify(source, expectedOutput:="621558279390000000", additionalRefs:={ilReference}) - ' This behavior hasn't changed from native VB compiler + Dim comp = CreateCompilationWithMscorlib(source, references:={ilReference}) + AssertTheseDiagnostics(comp, + ) End Sub From aab3bb87273ad3f5df6c815e561e8852162099cf Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 25 May 2016 20:49:21 -0700 Subject: [PATCH 08/13] New test constraint --- .../AttributeTests_WellKnownAttributes.cs | 1 - .../AttributeTests_WellKnownAttributes.vb | 58 +++---------------- 2 files changed, 7 insertions(+), 52 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index e07086af58559..322b2055ec88b 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -596,7 +596,6 @@ public static void Main() ); } - [Fact] [WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")] public void DateTimeConstantAttributeWithBadDefaultValueOnField() diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index c9847c30fabb8..f9cd31f270327 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -505,58 +505,14 @@ End Class ' .param [1] ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 80 73 3E 42 F6 37 A0 08 00 00 ) ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 FF FF FF FF FF FF FF FF 00 00 ) - Dim symValidator As Action(Of ModuleSymbol) = - Sub(peModule) - - Dim bar = peModule.GlobalNamespace.GetMember(Of NamedTypeSymbol)("Bar") - Dim method = bar.GetMember(Of MethodSymbol)("Method") - Dim parameters = method.Parameters - Dim theParameter = DirectCast(parameters(0), PEParameterSymbol) - Dim peModuleSymbol = DirectCast(peModule, PEModuleSymbol) - - Assert.Equal(ParameterAttributes.Optional, theParameter.ParamFlags) - - ' verify only one instance of the attribute - Dim attributes = peModuleSymbol.Module.MetadataReader.GetCustomAttributes(theParameter.Handle) - Dim datetimeAttributes = attributes.Where(Function(attribute) CodeAnalysis.PEModule.GetTargetAttributeSignatureIndex(peModuleSymbol.Module.MetadataReader, attribute, AttributeDescription.DateTimeConstantAttribute) <> -1) - Assert.Equal(1, datetimeAttributes.Count()) - - ' let's find the attribute in the PE metadata - Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) - Assert.True(attributeInfo.HasValue) - - Dim attributeValue As Long - Assert.True(peModuleSymbol.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, attributeValue)) - Assert.Equal(621558279390000000, attributeValue) - - ' check .param has no value - Dim constantHandle = peModuleSymbol.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue() - Assert.True(constantHandle.IsNil) - End Sub - - ' This is the same output as the native VB compiler - Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000", symbolValidator:=symValidator) - comp.VerifyDiagnostics() - - Dim libComp = CreateCompilationWithMscorlib(source) - Dim libCompRef = New VisualBasicCompilationReference(libComp) - Dim source2 = - - - - - - Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) - - Dim libAssemblyRef = libComp.EmitToImageReference() - Dim comp3 = CompileAndVerify(source2, expectedOutput:="0", additionalRefs:={libAssemblyRef}) + Dim comp = CreateCompilationWithMscorlib(source) + AssertTheseDiagnostics(comp, + Optional p1 As DateTime = # 8/23/1970 3:45:39AM #) As DateTime + ~~~~~~~~~~~~~~~~~~~~~~~ +]]>) End Sub From 5654f9dec440a1351af20f4a9b34d9a9af94657b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 26 May 2016 11:19:35 -0700 Subject: [PATCH 09/13] Fixing VB side to new test constraints --- .../Symbols/Attributes/CommonAttributeData.cs | 2 +- .../Binding/EarlyWellKnownAttributeBinder.vb | 3 +- .../Symbols/Source/SourceParameterSymbol.vb | 3 +- .../AttributeTests_WellKnownAttributes.vb | 83 ++++--------------- .../Test/Emit/Emit/OptionalArgumentsTests.vb | 7 ++ 5 files changed, 28 insertions(+), 70 deletions(-) diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs index d94a9f4ba60bb..48d2a7eb10d65 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs @@ -189,7 +189,7 @@ internal ConstantValue DecodeDateTimeConstantValue() if (value < DateTime.MinValue.Ticks || value > DateTime.MaxValue.Ticks) { // Treat as-is parameter doesn't have default - return ConstantValue.Unset; + return ConstantValue.Bad; } return ConstantValue.Create(new DateTime(value)); diff --git a/src/Compilers/VisualBasic/Portable/Binding/EarlyWellKnownAttributeBinder.vb b/src/Compilers/VisualBasic/Portable/Binding/EarlyWellKnownAttributeBinder.vb index 30e11fcd5f00a..3c507a00c62b0 100644 --- a/src/Compilers/VisualBasic/Portable/Binding/EarlyWellKnownAttributeBinder.vb +++ b/src/Compilers/VisualBasic/Portable/Binding/EarlyWellKnownAttributeBinder.vb @@ -91,7 +91,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Case _ SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.GlobalName, - SyntaxKind.IdentifierName + SyntaxKind.IdentifierName, + SyntaxKind.PredefinedType ' References to constant type members or constant locals. ' References to members of enumeration types. Return True diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceParameterSymbol.vb index d791b02b27dff..1fc66e7d4c711 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceParameterSymbol.vb @@ -332,8 +332,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Dim data = GetEarlyDecodedWellKnownAttributeData() If data IsNot Nothing Then Dim attrValue = data.DefaultParameterValue - If Not attrValue.IsBad AndAlso - attrValue <> ConstantValue.Unset AndAlso + If attrValue <> ConstantValue.Unset AndAlso value <> attrValue Then Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_ParamDefaultValueDiffersFromAttribute) End If diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index f9cd31f270327..6ed43c7edfb37 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -565,43 +565,19 @@ Imports System.Runtime.CompilerServices Public Class Bar - Public F As DateTime = # 8/23/1970 3:45:39AM # + Public Const F As DateTime = # 8/23/1970 3:45:39AM # Public Shared Sub Main() - Console.WriteLine(New Bar().F.Ticks) + Console.WriteLine(Bar.F.Ticks) End Sub End Class ]]> - ' The native VB compiler emits this: - Dim symValidator As Action(Of ModuleSymbol) = - Sub(peModule) - - 'Dim bar = peModule.GlobalNamespace.GetMember(Of NamedTypeSymbol)("Bar") - 'Dim method = bar.GetMember(Of MethodSymbol)("F") - 'Dim parameters = method.Parameters - 'Dim theParameter = DirectCast(parameters(0), PEParameterSymbol) - 'Dim peModuleSymbol = DirectCast(peModule, PEModuleSymbol) - - 'Assert.Equal(ParameterAttributes.Optional, theParameter.ParamFlags) - - '' let's find the attribute in the PE metadata - 'Dim attributeInfo = CodeAnalysis.PEModule.FindTargetAttribute(peModuleSymbol.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute) - 'Assert.True(attributeInfo.HasValue) - - 'Dim attributeValue As Long - 'Assert.True(peModuleSymbol.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, attributeValue)) - 'Assert.Equal(621558279390000000, attributeValue) - - '' check .param has no value - 'Dim constantHandle = peModuleSymbol.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue() - 'Assert.True(constantHandle.IsNil) - End Sub ' This is the same output as the native VB compiler - Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000", symbolValidator:=symValidator) + Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000") comp.VerifyDiagnostics() Dim libComp = CreateCompilationWithMscorlib(source) @@ -612,7 +588,7 @@ End Class @@ -622,13 +598,12 @@ End Class Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) ' Using the native compiler, this code crashes at runtime: Unhandled Exception: System.ArgumentOutOfRangeException: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks. - ' Also the compiler gives a warning: warning BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. Dim libAssemblyRef = libComp.EmitToImageReference() Dim comp3 = CreateCompilationWithMscorlib(source2, references:={libAssemblyRef}) comp3.AssertTheseDiagnostics() End Sub @@ -644,44 +619,23 @@ Imports System.Runtime.CompilerServices Public Class Bar - Public F As DateTime = # 8/23/1970 3:45:39AM # + Public Const F As DateTime = # 8/23/1970 3:45:39AM # Public Shared Sub Main() - Console.WriteLine(New Bar().F.Ticks) + Console.WriteLine(Bar.F.Ticks) End Sub End Class ]]> - ' The native VB compiler emits this: - ' With the native VB compiler, this code outputs 621558279390000000 - Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000") - comp.VerifyDiagnostics() - - Dim libComp = CreateCompilationWithMscorlib(source) - Dim libCompRef = New VisualBasicCompilationReference(libComp) - - Dim source2 = - - - - - - Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) - - ' With the native compiler, this code outputs 42 - ' But it gives a warning: warning BC42025: Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated. - Dim libAssemblyRef = libComp.EmitToImageReference() - Dim comp3 = CompileAndVerify(source2, expectedOutput:="42", additionalRefs:={libAssemblyRef}) - AssertTheseDiagnostics(comp3.Compilation) + Dim comp = CreateCompilationWithMscorlib(source) + comp.AssertTheseDiagnostics( + ~~~~~~~~~~~~~~~~~~~~ +]]>) End Sub @@ -762,7 +716,7 @@ BC30455: Argument not specified for parameter 'p1' of 'Public Sub Method(p1 As D @@ -775,11 +729,8 @@ End Class AssertTheseDiagnostics(comp, ) End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/OptionalArgumentsTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/OptionalArgumentsTests.vb index c18a653d3a32f..0e646e3a974ed 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/OptionalArgumentsTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/OptionalArgumentsTests.vb @@ -1152,6 +1152,7 @@ Imports System.Runtime.InteropServices Interface I Sub M1( o As Decimal) Sub M2( o As Decimal) + Sub M3( o As Decimal) End Interface ]]> @@ -1160,9 +1161,15 @@ End Interface BC30002: Type 'C' is not defined. Sub M1( o As Decimal) ~ +BC37226: The parameter has multiple distinct default values. + Sub M1( o As Decimal) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BC30002: Type 'C' is not defined. Sub M2( o As Decimal) ~ +BC37226: The parameter has multiple distinct default values. + Sub M3( o As Decimal) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ]]>) End Sub From d722b1ce4f71a4ce3eefce5ba6da02dfc80f95ab Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 26 May 2016 11:20:22 -0700 Subject: [PATCH 10/13] Fixing C# side to new test constraints --- .../Source/SourceComplexParameterSymbol.cs | 3 +- .../AttributeTests_WellKnownAttributes.cs | 34 +++++-------------- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs index ac4f9e08b0363..f51abdc030503 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceComplexParameterSymbol.cs @@ -642,8 +642,7 @@ private void VerifyParamDefaultValueMatchesAttributeIfAny(ConstantValue value, C if (data != null) { var attrValue = data.DefaultParameterValue; - if (!attrValue.IsBad && - (attrValue != ConstantValue.Unset) && + if ((attrValue != ConstantValue.Unset) && (value != attrValue)) { // CS8017: The parameter has multiple distinct default values. diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 322b2055ec88b..966a62b7c1aa6 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -446,7 +446,7 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } var theParameter = (PEParameterSymbol)parameters[0]; var peModule = (PEModuleSymbol)module; - Assert.Equal(ParameterAttributes.HasDefault, theParameter.Flags); + Assert.Equal(ParameterAttributes.HasDefault, theParameter.Flags); // native compiler has None instead // let's find the attribute in the PE metadata var attributeInfo = PEModule.FindTargetAttribute(peModule.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute); @@ -532,36 +532,18 @@ public static void Main() "; #endregion - // The native C# compiler emits this: + // The native C# compiler would succeed and emit this: // .method public hidebysig instance void M1([opt] valuetype[mscorlib] System.DateTime x) cil managed // { // .param [1] = nullref // .custom instance void[mscorlib] System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 FF FF FF FF FF FF FF FF 00 00 ) - Action verifier = (module) => - { - var bar = (NamedTypeSymbol)((ModuleSymbol)module).GlobalNamespace.GetMember("Bar"); - var method = (MethodSymbol)bar.GetMember("M1"); - var parameters = method.GetParameters(); - var theParameter = (PEParameterSymbol)parameters[0]; - var peModule = (PEModuleSymbol)module; - - Assert.Equal(ParameterAttributes.Optional | ParameterAttributes.HasDefault, theParameter.Flags); - - // let's find the attribute in the PE metadata - var attributeInfo = PEModule.FindTargetAttribute(peModule.Module.MetadataReader, theParameter.Handle, AttributeDescription.DateTimeConstantAttribute); - Assert.True(attributeInfo.HasValue); - - long attributeValue; - Assert.True(peModule.Module.TryExtractLongValueFromAttribute(attributeInfo.Handle, out attributeValue)); - Assert.Equal(-1L, attributeValue); // check the attribute is constructed with a -1 - - // check .param has no value - var constantValue = peModule.Module.GetParamDefaultValue(theParameter.Handle); - Assert.Equal(ConstantValue.Null, constantValue); - }; - var comp = CompileAndVerify(source, expectedOutput: "0", symbolValidator: verifier); - comp.VerifyDiagnostics(); + var comp = CreateCompilationWithMscorlib(source); + comp.VerifyDiagnostics( + // (7,60): error CS8017: The parameter has multiple distinct default values. + // public DateTime M1([DateTimeConstant(-1)] DateTime x = default(DateTime)) { return x; } + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "default(DateTime)").WithLocation(7, 60) + ); } [Fact] From e7f5645bd2e90495f0cac9f20d1f1fd7615ff01b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 26 May 2016 12:17:01 -0700 Subject: [PATCH 11/13] Fixing remaining tests --- .../AttributeTests_WellKnownAttributes.cs | 3 +- .../Test/Emit/Emit/OptionalArgumentsTests.cs | 48 +++++++++++++------ .../Semantics/NamedAndOptionalTests.cs | 12 +++-- .../Core/Portable/MetadataReader/PEModule.cs | 2 +- .../Symbols/Attributes/CommonAttributeData.cs | 1 - 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs index 966a62b7c1aa6..661e855b59512 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.cs @@ -457,8 +457,6 @@ public void Method([DateTimeConstant(-1)]DateTime p1) { } Assert.Equal(-1L, attributeValue); // check the attribute is constructed with a -1 // check .param has no value - //var constantHandle = peModule.Module.MetadataReader.GetParameter(theParameter.Handle).GetDefaultValue(); - //Assert.True(constantHandle.IsNil); var constantValue = peModule.Module.GetParamDefaultValue(theParameter.Handle); Assert.Equal(ConstantValue.Null, constantValue); }; @@ -503,6 +501,7 @@ public static void M() Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "Method").WithArguments("p1", "Bar.Method(System.DateTime)").WithLocation(6, 19) ); + // The native compiler also gives an error: error CS1501: No overload for method 'Method' takes 0 arguments var libAssemblyRef = libComp.EmitToImageReference(); var comp3 = CreateCompilationWithMscorlib(source2, new[] { libAssemblyRef }); comp3.VerifyDiagnostics( diff --git a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs index 0f6d48385eb95..b707a38867a72 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/OptionalArgumentsTests.cs @@ -252,43 +252,53 @@ interface I CreateCompilationWithMscorlib(source, references: new[] { SystemRef }).VerifyDiagnostics( // (5,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute // void F1([DefaultParameterValue(1)]int o = 2); - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue"), + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(5, 14), // (6,14): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute // void F2([DefaultParameterValue(1)]decimal o = 2); - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue"), + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(6, 14), + // (6,51): error CS8017: The parameter has multiple distinct default values. + // void F2([DefaultParameterValue(1)]decimal o = 2); + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(6, 51), // (7,57): error CS8017: The parameter has multiple distinct default values. // void F4([DecimalConstant(0, 0, 0, 0, 1)]decimal o = 2); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(7, 57), // (8,35): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute // void F6([DateTimeConstant(1), DefaultParameterValue(1), DecimalConstant(0, 0, 0, 0, 1)]int o = 1); - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue"), + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(8, 35), // (8,61): error CS8017: The parameter has multiple distinct default values. // void F6([DateTimeConstant(1), DefaultParameterValue(1), DecimalConstant(0, 0, 0, 0, 1)]int o = 1); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 1)"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 1)").WithLocation(8, 61), // (8,100): error CS8017: The parameter has multiple distinct default values. // void F6([DateTimeConstant(1), DefaultParameterValue(1), DecimalConstant(0, 0, 0, 0, 1)]int o = 1); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "1"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "1").WithLocation(8, 100), // (9,35): error CS8017: The parameter has multiple distinct default values. // void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 2)"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 2)").WithLocation(9, 35), // (9,67): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute // void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2); - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue"), + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 67), // (9,104): error CS8017: The parameter has multiple distinct default values. // void F7([DateTimeConstant(2), DecimalConstant(0, 0, 0, 0, 2), DefaultParameterValue(2)]decimal o = 2); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 104), // (10,25): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute // object this[int a, [DefaultParameterValue(1)]int o = 2] { get; set; } - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue"), + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(10, 25), + // (10,58): error CS8017: The parameter has multiple distinct default values. + // object this[int a, [DefaultParameterValue(1)]int o = 2] { get; set; } + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(10, 58), // (11,44): error CS8017: The parameter has multiple distinct default values. // object this[[DefaultParameterValue(0), DecimalConstant(0, 0, 0, 0, 0), DateTimeConstant(0)]int o] { get; set; } - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 0)"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstant(0, 0, 0, 0, 0)").WithLocation(11, 44), // (11,76): error CS8017: The parameter has multiple distinct default values. // object this[[DefaultParameterValue(0), DecimalConstant(0, 0, 0, 0, 0), DateTimeConstant(0)]int o] { get; set; } - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DateTimeConstant(0)"), + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DateTimeConstant(0)").WithLocation(11, 76), + // (5,47): error CS8017: The parameter has multiple distinct default values. + // void F1([DefaultParameterValue(1)]int o = 2); + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(5, 47), // (13,61): error CS8017: The parameter has multiple distinct default values. // delegate void D([DecimalConstant(0, 0, 0, 0, 3)]decimal b = 4); - Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "4")); + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "4").WithLocation(13, 61) + ); } [WorkItem(529684, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529684")] @@ -334,14 +344,22 @@ interface I { void M1([DefaultParameterValue(typeof(C)), DecimalConstantAttribute(0, 0, 0, 0, 0)] decimal o); void M2([DefaultParameterValue(0), DecimalConstantAttribute(0, 0, 0, 0, typeof(C))] decimal o); + void M3([DefaultParameterValue(0), DecimalConstantAttribute(0, 0, 0, 0, 0)] decimal o); }"; CreateCompilationWithMscorlib(source, references: new[] { SystemRef }).VerifyDiagnostics( + // (7,40): error CS8017: The parameter has multiple distinct default values. + // void M3([DefaultParameterValue(0), DecimalConstantAttribute(0, 0, 0, 0, 0)] decimal o); + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstantAttribute(0, 0, 0, 0, 0)").WithLocation(7, 40), // (6,84): error CS0246: The type or namespace name 'C' could not be found (are you missing a using directive or an assembly reference?) // void M2([DefaultParameterValue(0), DecimalConstantAttribute(0, 0, 0, 0, typeof(C))] decimal o); - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C"), + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C").WithLocation(6, 84), // (5,43): error CS0246: The type or namespace name 'C' could not be found (are you missing a using directive or an assembly reference?) // void M1([DefaultParameterValue(typeof(C)), DecimalConstantAttribute(0, 0, 0, 0, 0)] decimal o); - Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C")); + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C").WithLocation(5, 43), + // (5,48): error CS8017: The parameter has multiple distinct default values. + // void M1([DefaultParameterValue(typeof(C)), DecimalConstantAttribute(0, 0, 0, 0, 0)] decimal o); + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "DecimalConstantAttribute(0, 0, 0, 0, 0)").WithLocation(5, 48) + ); } [WorkItem(529684, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529684")] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs index 79b38b427534b..e1f08a7cc9389 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NamedAndOptionalTests.cs @@ -932,10 +932,16 @@ public static int Main(){ } "; CreateCompilationWithMscorlib(source, new[] { SystemRef }).VerifyDiagnostics( - // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional"), // (9,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute - Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue")); + // public int Bar([DefaultParameterValue(1)]int i = 2) { + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "DefaultParameterValue").WithLocation(9, 21), + // (9,54): error CS8017: The parameter has multiple distinct default values. + // public int Bar([DefaultParameterValue(1)]int i = 2) { + Diagnostic(ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute, "2").WithLocation(9, 54), + // (5,21): error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute + // public int Foo([Optional]object i = null) { + Diagnostic(ErrorCode.ERR_DefaultValueUsedWithAttributes, "Optional").WithLocation(5, 21) + ); } [WorkItem(10290, "DevDiv_Projects/Roslyn")] diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 60bd17401849d..41bd0fdad7a5d 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1995,7 +1995,7 @@ internal int GetTargetAttributeSignatureIndex(CustomAttributeHandle customAttrib /// signatures array, -1 if /// this is not the target attribute. /// - internal static int GetTargetAttributeSignatureIndex(MetadataReader metadataReader, CustomAttributeHandle customAttribute, AttributeDescription description) + private static int GetTargetAttributeSignatureIndex(MetadataReader metadataReader, CustomAttributeHandle customAttribute, AttributeDescription description) { const int No = -1; EntityHandle ctor; diff --git a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs index 48d2a7eb10d65..b48048d719624 100644 --- a/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs +++ b/src/Compilers/Core/Portable/Symbols/Attributes/CommonAttributeData.cs @@ -188,7 +188,6 @@ internal ConstantValue DecodeDateTimeConstantValue() // if value is outside this range, DateTime would throw when constructed if (value < DateTime.MinValue.Ticks || value > DateTime.MaxValue.Ticks) { - // Treat as-is parameter doesn't have default return ConstantValue.Bad; } From 784703f07a9d6fa1b5b2263192d52912012886e7 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 26 May 2016 12:32:56 -0700 Subject: [PATCH 12/13] Adding comments --- .../Emit/Attributes/AttributeTests_WellKnownAttributes.vb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index 6ed43c7edfb37..2ae8b1f51a930 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -506,6 +506,8 @@ End Class ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 80 73 3E 42 F6 37 A0 08 00 00 ) ' .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute:: .ctor(Int64) = (1 00 FF FF FF FF FF FF FF FF 00 00 ) + ' Using the native compiler, the code would output 621558279390000000 + Dim comp = CreateCompilationWithMscorlib(source) AssertTheseDiagnostics(comp, ) End Sub - Public Sub DateTimeConstantAttributeWithBadDefaultValueOnField() @@ -575,7 +578,6 @@ End Class - ' This is the same output as the native VB compiler Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000") comp.VerifyDiagnostics() From 9da1381fe4113c3e44260e3bf181e49a5845ae56 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 26 May 2016 14:35:57 -0700 Subject: [PATCH 13/13] Fixing VB field scenario too --- .../Symbols/Source/SourceFieldSymbol.vb | 40 +++++++++---------- .../AttributeTests_WellKnownAttributes.vb | 36 ++++------------- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceFieldSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceFieldSymbol.vb index 47658544fb6fa..55d5e60bd09b0 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceFieldSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceFieldSymbol.vb @@ -342,34 +342,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ''' If not, report ERR_FieldHasMultipleDistinctConstantValues. ''' Private Sub VerifyConstantValueMatches(attrValue As ConstantValue, ByRef arguments As DecodeWellKnownAttributeArguments(Of AttributeSyntax, VisualBasicAttributeData, AttributeLocation)) - If Not attrValue.IsBad Then - Dim data = arguments.GetOrCreateData(Of CommonFieldWellKnownAttributeData)() - Dim constValue As ConstantValue + Dim data = arguments.GetOrCreateData(Of CommonFieldWellKnownAttributeData)() + Dim constValue As ConstantValue - If Me.IsConst Then - If Me.Type.IsDecimalType() OrElse Me.Type.IsDateTimeType() Then - constValue = Me.GetConstantValue(SymbolsInProgress(Of FieldSymbol).Empty) + If Me.IsConst Then + If Me.Type.IsDecimalType() OrElse Me.Type.IsDateTimeType() Then + constValue = Me.GetConstantValue(SymbolsInProgress(Of FieldSymbol).Empty) - If constValue IsNot Nothing AndAlso Not constValue.IsBad AndAlso constValue <> attrValue Then - arguments.Diagnostics.Add(ERRID.ERR_FieldHasMultipleDistinctConstantValues, arguments.AttributeSyntaxOpt.GetLocation()) - End If - Else + If constValue IsNot Nothing AndAlso Not constValue.IsBad AndAlso constValue <> attrValue Then arguments.Diagnostics.Add(ERRID.ERR_FieldHasMultipleDistinctConstantValues, arguments.AttributeSyntaxOpt.GetLocation()) End If - - If data.ConstValue = CodeAnalysis.ConstantValue.Unset Then - data.ConstValue = attrValue - End If Else - constValue = data.ConstValue + arguments.Diagnostics.Add(ERRID.ERR_FieldHasMultipleDistinctConstantValues, arguments.AttributeSyntaxOpt.GetLocation()) + End If - If constValue <> CodeAnalysis.ConstantValue.Unset Then - If constValue <> attrValue Then - arguments.Diagnostics.Add(ERRID.ERR_FieldHasMultipleDistinctConstantValues, arguments.AttributeSyntaxOpt.GetLocation()) - End If - Else - data.ConstValue = attrValue + If data.ConstValue = CodeAnalysis.ConstantValue.Unset Then + data.ConstValue = attrValue + End If + Else + constValue = data.ConstValue + + If constValue <> CodeAnalysis.ConstantValue.Unset Then + If constValue <> attrValue Then + arguments.Diagnostics.Add(ERRID.ERR_FieldHasMultipleDistinctConstantValues, arguments.AttributeSyntaxOpt.GetLocation()) End If + Else + data.ConstValue = attrValue End If End If End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index 2ae8b1f51a930..3cb5a05ea1055 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -578,34 +578,12 @@ End Class - ' This is the same output as the native VB compiler - Dim comp = CompileAndVerify(source, expectedOutput:="621558279390000000") - comp.VerifyDiagnostics() - - Dim libComp = CreateCompilationWithMscorlib(source) - Dim libCompRef = New VisualBasicCompilationReference(libComp) - - Dim source2 = - - - - - - Dim comp2 = CompileAndVerify(source2, expectedOutput:="621558279390000000", additionalRefs:={libCompRef}) - - ' Using the native compiler, this code crashes at runtime: Unhandled Exception: System.ArgumentOutOfRangeException: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks. - Dim libAssemblyRef = libComp.EmitToImageReference() - Dim comp3 = CreateCompilationWithMscorlib(source2, references:={libAssemblyRef}) - comp3.AssertTheseDiagnostics( + ~~~~~~~~~~~~~~~~~~~~ ]]>) End Sub @@ -725,7 +703,7 @@ End Class - ' Using the native compiler, this code outputs 621558279390000000 + ' Using the native compiler, this code crashed Dim ilReference = CompileIL(ilSource.Value) Dim comp = CreateCompilationWithMscorlib(source, references:={ilReference}) AssertTheseDiagnostics(comp,