Skip to content

Commit

Permalink
Merge pull request #11610 from vslsnap/merge-master-into-future201605…
Browse files Browse the repository at this point in the history
…27-150023

Merge master into future
  • Loading branch information
Paul Vick committed May 27, 2016
2 parents dbae4de + dd21101 commit 2e6c17d
Show file tree
Hide file tree
Showing 17 changed files with 1,016 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -387,28 +387,26 @@ public override Symbol VisitModule(ModuleSymbol module)
return null;
}

public override Symbol VisitAssembly(AssemblySymbol symbol)
public override Symbol VisitAssembly(AssemblySymbol assembly)
{
if (symbol.IsLinked)
if (assembly.IsLinked)
{
return symbol;
return assembly;
}

// the current source assembly:
if (symbol.Identity.Equals(_sourceAssembly.Identity))
// When we map synthesized symbols from previous generations to the latest compilation
// we might encounter a symbol that is defined in arbitrary preceding generation,
// not just the immediately preceding generation. If the source assembly uses time-based
// versioning assemblies of preceding generations might differ in their version number.
if (IdentityEqualIgnoringVersionWildcard(assembly, _sourceAssembly))
{
return _otherAssembly;
}

// find a referenced assembly with the exactly same source identity:
// find a referenced assembly with the same source identity (modulo assembly version patterns):
foreach (var otherReferencedAssembly in _otherAssembly.Modules[0].ReferencedAssemblySymbols)
{
var identity = symbol.Identity;
var otherIdentity = otherReferencedAssembly.Identity;

if (AssemblyIdentityComparer.SimpleNameComparer.Equals(identity.Name, otherIdentity.Name) &&
(symbol.AssemblyVersionPattern ?? symbol.Identity.Version).Equals(otherReferencedAssembly.AssemblyVersionPattern ?? otherReferencedAssembly.Identity.Version) &&
AssemblyIdentity.EqualIgnoringNameAndVersion(identity, otherIdentity))
if (IdentityEqualIgnoringVersionWildcard(assembly, otherReferencedAssembly))
{
return otherReferencedAssembly;
}
Expand All @@ -417,6 +415,16 @@ public override Symbol VisitAssembly(AssemblySymbol symbol)
return null;
}

private static bool IdentityEqualIgnoringVersionWildcard(AssemblySymbol left, AssemblySymbol right)
{
var leftIdentity = left.Identity;
var rightIdentity = right.Identity;

return AssemblyIdentityComparer.SimpleNameComparer.Equals(leftIdentity.Name, rightIdentity.Name) &&
(left.AssemblyVersionPattern ?? leftIdentity.Version).Equals(right.AssemblyVersionPattern ?? rightIdentity.Version) &&
AssemblyIdentity.EqualIgnoringNameAndVersion(leftIdentity, rightIdentity);
}

public override Symbol VisitNamespace(NamespaceSymbol @namespace)
{
var otherContainer = this.Visit(@namespace.ContainingSymbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -416,6 +417,281 @@ 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<IModuleSymbol> 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.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);
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();
}

[Fact]
[WorkItem(217740, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=217740")]
public void DateTimeConstantAttributeReferencedViaRef()
{
#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)
);

// 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(
// (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 DateTimeConstantAttributeWithBadDefaultValue()
{
#region "Source"
var source = @"
using System;
using System.Runtime.CompilerServices;
public class Bar
{
public DateTime M1([DateTimeConstant(-1)] DateTime x = default(DateTime)) { return x; }
public static void Main()
{
Console.WriteLine(new Bar().M1().Ticks);
}
}
";
#endregion

// 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 )

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]
[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 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()
{
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 });
// The native compiler would produce a working exe, but that exe would fail at runtime
}

[Fact]
public void TestDecimalConstantAttribute()
{
Expand Down Expand Up @@ -3176,7 +3452,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")]
Expand Down
Loading

0 comments on commit 2e6c17d

Please sign in to comment.