diff options
31 files changed, 443 insertions, 133 deletions
diff --git a/external/referencesource b/external/referencesource -Subproject 906778312bdc1ce3fa8fe84b1952b8fb9ad6837 +Subproject d679dd948c0ef887898f75ab855be9bb2ee5c24 diff --git a/mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs b/mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs index 8d4c63c6564..14613104d9b 100644 --- a/mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs +++ b/mcs/class/Mono.Posix/Test/Mono.Unix/UnixSignalTest.cs @@ -410,7 +410,6 @@ namespace MonoTests.Mono.Unix { const int StormCount = 100000; [Test] - [Category("NotOnMac")] // OSX signal storming will not deliver every one public void TestRaiseStorm () { UnixSignal[] usignals = CreateSignals (signals); @@ -424,7 +423,7 @@ namespace MonoTests.Mono.Unix { t.Start (); foreach (Thread t in threads) t.Join (); - AssertCount (usignals); + AssertCountSet (usignals); CloseSignals (usignals); } @@ -436,6 +435,13 @@ namespace MonoTests.Mono.Unix { Assert.AreEqual (sum, StormCount); } + static void AssertCountSet (UnixSignal[] usignals) + { + foreach (UnixSignal s in usignals) { + Assert.IsTrue (s.Count > 0); + } + } + static UnixSignal[] CreateSignals (Signum[] signals) { UnixSignal[] s = new UnixSignal [signals.Length]; @@ -462,7 +468,6 @@ namespace MonoTests.Mono.Unix { } [Test] - [Category("NotOnMac")] // OSX signal storming will not deliver every one public void TestAddRemove () { UnixSignal[] usignals = CreateSignals (signals); @@ -477,7 +482,7 @@ namespace MonoTests.Mono.Unix { foreach (Thread t in threads) t.Join (); - AssertCount (usignals); + AssertCountSet (usignals); CloseSignals (usignals); } @@ -497,7 +502,6 @@ namespace MonoTests.Mono.Unix { } [Test] - [Category("NotOnMac")] // OSX signal storming will not deliver every one public void TestWaitAny () { UnixSignal[] usignals = CreateSignals (signals); @@ -515,7 +519,7 @@ namespace MonoTests.Mono.Unix { foreach (Thread t in threads) t.Join (); - AssertCount (usignals); + AssertCountSet (usignals); CloseSignals (usignals); } diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs index e4cd69c5977..4e96356684f 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs @@ -244,6 +244,17 @@ namespace MonoTests.System.Linq.Expressions { } [Test] + public void CallMethodOnDateTime () + { + var left = Expression.Call (Expression.Constant (DateTime.Now), typeof(DateTime).GetMethod ("AddDays"), Expression.Constant (-5.0)); + var right = Expression.Constant (DateTime.Today); + var expr = Expression.GreaterThan (left, right); + + var eq = Expression.Lambda<Func<bool>> (expr).Compile (); + Assert.IsFalse (eq ()); + } + + [Test] [Category ("NotDotNet")] // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=339351 [ExpectedException (typeof (ArgumentException))] public void CallStaticMethodOnNonSenseInstanceExpression () @@ -398,7 +409,6 @@ namespace MonoTests.System.Linq.Expressions { } [Test] - [Category ("NotWorkingInterpreter")] public void Connect282702 () { var lambda = Expression.Lambda<Func<Func<int>>> ( diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs index 497955c4a4e..61e9ca19db8 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs @@ -94,6 +94,18 @@ namespace MonoTests.System.Linq.Expressions } [Test] + public void StringWithNull () + { + BinaryExpression expr = Expression.Equal (Expression.Constant ("a"), Expression.Constant (null)); + Assert.AreEqual (ExpressionType.Equal, expr.NodeType); + Assert.AreEqual (typeof (bool), expr.Type); + Assert.IsNull (expr.Method); + + var eq = Expression.Lambda<Func<bool>> (expr).Compile (); + Assert.IsFalse (eq ()); + } + + [Test] public void Nullable_LiftToNull_SetToFalse () { int? a = 1; diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_NotEqual.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_NotEqual.cs index 24722033eb2..6ac2a8a81fc 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_NotEqual.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_NotEqual.cs @@ -80,6 +80,30 @@ namespace MonoTests.System.Linq.Expressions } [Test] + public void PrimitiveNonNumeric () + { + BinaryExpression expr = Expression.NotEqual (Expression.Constant ('a'), Expression.Constant ('b')); + Assert.AreEqual (ExpressionType.NotEqual, expr.NodeType); + Assert.AreEqual (typeof (bool), expr.Type); + Assert.IsNull (expr.Method); + + var eq = Expression.Lambda<Func<bool>> (expr).Compile (); + Assert.IsTrue (eq ()); + } + + [Test] + public void StringWithNull () + { + BinaryExpression expr = Expression.NotEqual (Expression.Constant ("a"), Expression.Constant (null)); + Assert.AreEqual (ExpressionType.NotEqual, expr.NodeType); + Assert.AreEqual (typeof (bool), expr.Type); + Assert.IsNull (expr.Method); + + var eq = Expression.Lambda<Func<bool>> (expr).Compile (); + Assert.IsTrue (eq ()); + } + + [Test] public void Nullable_LiftToNull_SetToFalse () { int? a = 1; diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs index fbc2bff995e..59e3f322dd8 100755 --- a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs @@ -9,10 +9,8 @@ // using System; -using System.Linq; using System.Collections; using System.Threading; -using System.Text.RegularExpressions; using System.Net; using System.Net.Sockets; using NUnit.Framework; @@ -3479,37 +3477,6 @@ namespace MonoTests.System.Net.Sockets s.Close (); } - static bool supportsTcpReuse = false; - static bool supportsTcpReuseSet = false; - - static bool SupportsTcpReuse () - { - if (supportsTcpReuseSet) - return supportsTcpReuse; - - if (Path.DirectorySeparatorChar == '/') { - /* - * On UNIX OS - * Multiple threads listening to the same address and port are not possible - * before linux 3.9 kernel, where the socket option SO_REUSEPORT was introduced. - */ - Regex reg = new Regex(@"^#define\s*SO_REUSEPORT"); - foreach (string directory in Directory.GetDirectories ("/usr/include")) { - var f = Directory.GetFiles (directory, "socket.h").SingleOrDefault (); - if (f != null && File.ReadLines (f).Any (l => reg.Match (l).Success)) { - supportsTcpReuse = true; - break; - } - } - } else { - supportsTcpReuse = true; - } - - supportsTcpReuseSet = true; - - return supportsTcpReuse; - } - // Test case for bug #31557 [Test] public void TcpDoubleBind () @@ -3525,15 +3492,10 @@ namespace MonoTests.System.Net.Sockets ss.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - Exception ex = null; - try { - ss.Bind (new IPEndPoint (IPAddress.Any, 12345)); - ss.Listen(1); - } catch (SocketException e) { - ex = e; - } + ss.Bind (new IPEndPoint (IPAddress.Any, 12345)); + ss.Listen(1); - Assert.AreEqual (SupportsTcpReuse (), ex == null); + // If we make it this far, we succeeded. } } diff --git a/mcs/class/corlib/System/Console.cs b/mcs/class/corlib/System/Console.cs index deb3eaf4bf7..451ace2ad24 100644 --- a/mcs/class/corlib/System/Console.cs +++ b/mcs/class/corlib/System/Console.cs @@ -152,10 +152,7 @@ namespace System stdin = new CStreamReader (OpenStandardInput (0), inputEncoding); } else { #endif -// FULL_AOT_RUNTIME is used (instead of MONOTOUCH) since we only want this code when running on -// iOS (simulator or devices) and *not* when running tools (e.g. btouch #12179) that needs to use -// the mscorlib.dll shipped with Xamarin.iOS -#if MONOTOUCH && FULL_AOT_RUNTIME +#if MONOTOUCH stdout = new NSLogWriter (); #else stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding); @@ -163,7 +160,7 @@ namespace System #endif stdout = TextWriter.Synchronized (stdout); -#if MONOTOUCH && FULL_AOT_RUNTIME +#if MONOTOUCH stderr = new NSLogWriter (); #else stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding); diff --git a/mcs/class/corlib/System/Console.iOS.cs b/mcs/class/corlib/System/Console.iOS.cs index 00ebfb3e84f..3329b8046a5 100644 --- a/mcs/class/corlib/System/Console.iOS.cs +++ b/mcs/class/corlib/System/Console.iOS.cs @@ -7,7 +7,7 @@ // Copyright 2012-2014 Xamarin Inc. All rights reserved. // -#if FULL_AOT_RUNTIME +#if MONOTOUCH using System; using System.IO; diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs index d9267ac3230..2553a400be5 100644 --- a/mcs/class/corlib/System/Environment.cs +++ b/mcs/class/corlib/System/Environment.cs @@ -549,8 +549,7 @@ namespace System { return GetFolderPath (folder, SpecialFolderOption.None); } -// for monotouch, not monotouch_runtime -#if !(MONOTOUCH && FULL_AOT_RUNTIME) +#if !MONOTOUCH [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static string GetWindowsFolderPath (int folder); diff --git a/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs b/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs index d081bc0a0f2..d29068adeb6 100644 --- a/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs @@ -361,14 +361,20 @@ namespace MonoTests.System.Reflection IList<LocalVariableInfo> locals = mb.LocalVariables; - // This might break with different compilers etc. - Assert.AreEqual (2, locals.Count, "#3"); - - Assert.IsTrue ((locals [0].LocalType == typeof (byte[])) || (locals [1].LocalType == typeof (byte[])), "#4"); - if (locals [0].LocalType == typeof (byte[])) - Assert.AreEqual (false, locals [0].IsPinned, "#5"); - else - Assert.AreEqual (false, locals [1].IsPinned, "#6"); + bool foundPinnedBytePointer = false; + unsafe { + foreach (LocalVariableInfo lvi in locals) { + if (lvi.LocalType == typeof (byte[])) + // This is optimized out by CSC in .NET 4.6 + Assert.IsFalse (lvi.IsPinned, "#3-1"); + + if (/* mcs */ lvi.LocalType == typeof (byte*) || /* csc */ lvi.LocalType == typeof (byte).MakeByRefType ()) { + foundPinnedBytePointer = true; + Assert.IsTrue (lvi.IsPinned, "#3-2"); + } + } + } + Assert.IsTrue (foundPinnedBytePointer, "#4"); } public int return_parameter_test () @@ -804,21 +810,44 @@ namespace MonoTests.System.Reflection var type = typeof (GenericClass<>).GetMethod("Method").GetMethodBody().LocalVariables[0].LocalType; Assert.AreEqual (typeofT, type); Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType); + + bool foundTypeOfK = false; + bool foundExpectedType = false; + + MethodBody mb = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody(); + foreach (LocalVariableInfo lvi in mb.LocalVariables) { + if (lvi.LocalType == typeofK) { + foundTypeOfK = true; + Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#1-1"); + } else if (lvi.LocalType == typeofT) { + foundExpectedType = true; + Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#1-2"); + } + } - type = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody().LocalVariables[0].LocalType; - Assert.AreEqual (typeofT, type); - Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType); - - type = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody().LocalVariables[1].LocalType; - Assert.AreEqual (typeofK, type); - Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType); - - type = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody().LocalVariables[0].LocalType; - Assert.AreEqual (typeof (int), type); - - type = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody().LocalVariables[1].LocalType; - Assert.AreEqual (typeofK, type); - Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType); + Assert.IsTrue (foundTypeOfK, "#1-3"); + if (mb.LocalVariables.Count < 2) + Assert.Ignore ("Code built in release mode - 'T var0' optmized out"); + else + Assert.IsTrue (foundExpectedType, "#1-4"); + + foundTypeOfK = false; + foundExpectedType = false; + mb = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody(); + foreach (LocalVariableInfo lvi in mb.LocalVariables) { + if (lvi.LocalType == typeofK) { + foundTypeOfK = true; + Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#2-1"); + } else if (lvi.LocalType == typeof (int)) { + foundExpectedType = true; + } + } + + Assert.IsTrue (foundTypeOfK, "#2-3"); + if (mb.LocalVariables.Count < 2) + Assert.Ignore ("Code built in release mode - 'int var0' optmized out"); + else + Assert.IsTrue (foundExpectedType, "#2-4"); } #endif } diff --git a/mcs/class/corlib/Test/System.Threading/CancellationTokenSourceTest.cs b/mcs/class/corlib/Test/System.Threading/CancellationTokenSourceTest.cs index 5bf805aae0b..8d50a520cfe 100644 --- a/mcs/class/corlib/Test/System.Threading/CancellationTokenSourceTest.cs +++ b/mcs/class/corlib/Test/System.Threading/CancellationTokenSourceTest.cs @@ -33,7 +33,6 @@ using System; using System.Threading; using NUnit.Framework; using System.Threading.Tasks; -using MonoTests.System.Threading.Tasks; namespace MonoTests.System.Threading { @@ -447,10 +446,11 @@ namespace MonoTests.System.Threading Assert.IsTrue (canceled, "#3"); } + [Category ("NotWorking")] // why would linked token be imune to ObjectDisposedException on Cancel? [Test] public void ConcurrentCancelLinkedTokenSourceWhileDisposing () { - ParallelTestHelper.Repeat (delegate { + for (int i = 0, total = 500; i < total; ++i) { var src = new CancellationTokenSource (); var linked = CancellationTokenSource.CreateLinkedTokenSource (src.Token); var cntd = new CountdownEvent (2); @@ -470,20 +470,19 @@ namespace MonoTests.System.Threading t2.Start (); t1.Join (500); t2.Join (500); - }, 500); + } } #if NET_4_5 [Test] public void DisposeRace () { - for (int i = 0; i < 1000; ++i) { + for (int i = 0, total = 1000; i < total; ++i) { var c1 = new CancellationTokenSource (); - using (c1) { - var wh = c1.Token.WaitHandle; - c1.CancelAfter (1); - Thread.Sleep (1); - } + var wh = c1.Token.WaitHandle; + c1.CancelAfter (1); + Thread.Sleep (1); + c1.Dispose (); } } #endif diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs index 4da895bd203..ad4c33d19fb 100644 --- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs +++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs @@ -24,7 +24,7 @@ using Microsoft.Scripting.Utils; namespace Microsoft.Scripting.Interpreter { internal abstract class EqualInstruction : ComparisonInstruction { // Perf: EqualityComparer<T> but is 3/2 to 2 times slower. - private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double; + private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _String, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double; private static Instruction _BooleanLifted, _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted; @@ -64,6 +64,13 @@ namespace Microsoft.Scripting.Interpreter { } } + internal sealed class EqualString : EqualInstruction { + protected override object DoCalculate (object l, object r) + { + return (String)l == (String)r; + } + } + internal sealed class EqualInt32 : EqualInstruction { protected override object DoCalculate (object l, object r) { @@ -140,6 +147,7 @@ namespace Microsoft.Scripting.Interpreter { case TypeCode.SByte: return _SByte ?? (_SByte = new EqualSByte()); case TypeCode.Byte: return _Byte ?? (_Byte = new EqualByte()); case TypeCode.Char: return _Char ?? (_Char = new EqualChar()); + case TypeCode.String: return _String ?? (_String = new EqualString()); case TypeCode.Int16: return _Int16 ?? (_Int16 = new EqualInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new EqualInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new EqualInt64()); diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs index 396c3ff7159..ebf5e68885a 100644 --- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs +++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs @@ -24,7 +24,7 @@ using Microsoft.Scripting.Utils; namespace Microsoft.Scripting.Interpreter { internal abstract class NotEqualInstruction : ComparisonInstruction { // Perf: EqualityComparer<T> but is 3/2 to 2 times slower. - private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double; + private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _String, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double; private static Instruction _BooleanLifted, _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted; @@ -64,6 +64,13 @@ namespace Microsoft.Scripting.Interpreter { } } + internal sealed class NotEqualString : NotEqualInstruction { + protected override object DoCalculate (object l, object r) + { + return (String)l != (String)r; + } + } + internal sealed class NotEqualInt32 : NotEqualInstruction { protected override object DoCalculate (object l, object r) { @@ -140,6 +147,7 @@ namespace Microsoft.Scripting.Interpreter { case TypeCode.SByte: return _SByte ?? (_SByte = new NotEqualSByte()); case TypeCode.Byte: return _Byte ?? (_Byte = new NotEqualByte()); case TypeCode.Char: return _Char ?? (_Char = new NotEqualChar()); + case TypeCode.String: return _String ?? (_String = new NotEqualString()); case TypeCode.Int16: return _Int16 ?? (_Int16 = new NotEqualInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new NotEqualInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new NotEqualInt64()); diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs index c58b0353f91..779d93a1086 100644 --- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs +++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs @@ -1278,7 +1278,7 @@ namespace Microsoft.Scripting.Interpreter { // also could be a mutable value type, Delegate.CreateDelegate and MethodInfo.Invoke both can't handle this, we // need to generate code. if (!CollectionUtils.TrueForAll(parameters, (p) => !p.ParameterType.IsByRef) || - (!node.Method.IsStatic && node.Method.DeclaringType.IsValueType() && !node.Method.DeclaringType.IsPrimitive())) { + (!node.Method.IsStatic && node.Method.DeclaringType.IsValueType && node.Method.DeclaringType.Assembly != typeof (object).Assembly)) { #if MONO_INTERPRETER throw new NotImplementedException ("Interpreter of ref types"); #else diff --git a/mcs/errors/cs1918.cs b/mcs/errors/cs1918.cs index 245d6bef89a..b1f32542015 100644 --- a/mcs/errors/cs1918.cs +++ b/mcs/errors/cs1918.cs @@ -10,7 +10,7 @@ struct S class C { public S Value { - set { } + set; get; } static void Main () diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 4225b585eea..952a85f9aa4 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -7027,19 +7027,16 @@ namespace Mono.CSharp { protected override bool ResolveAutopropertyAssignment (ResolveContext rc, Expression rhs) { - var prop = best_candidate.MemberDefinition as Property; - if (prop == null) - return false; - if (!rc.HasSet (ResolveContext.Options.ConstructorScope)) return false; - if (prop.Parent.PartialContainer != rc.CurrentMemberDefinition.Parent.PartialContainer) { - var ps = MemberCache.FindMember (rc.CurrentType, MemberFilter.Property (prop.ShortName, prop.MemberType), BindingRestriction.DeclaredOnly) as PropertySpec; + var prop = best_candidate.MemberDefinition as Property; + if (prop == null || prop.Parent.PartialContainer != rc.CurrentMemberDefinition.Parent.PartialContainer) { + var ps = MemberCache.FindMember (rc.CurrentType, MemberFilter.Property (best_candidate.Name, best_candidate.MemberType), BindingRestriction.DeclaredOnly) as PropertySpec; if (ps == null) return false; - prop = (Property) ps.MemberDefinition; + prop = (Property)ps.MemberDefinition; } var spec = prop.BackingField; diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index acdcf32485d..f815830cd56 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -11674,6 +11674,10 @@ namespace Mono.CSharp return null; if (source is CollectionOrObjectInitializers) { + target = target.Resolve (ec); + if (target == null) + return null; + Expression previous = ec.CurrentInitializerVariable; ec.CurrentInitializerVariable = target; source = source.Resolve (ec); @@ -11683,6 +11687,7 @@ namespace Mono.CSharp eclass = source.eclass; type = source.Type; + return this; } @@ -11864,7 +11869,7 @@ namespace Mono.CSharp return false; } - target = new IndexerExpr (indexers, type, init, args, loc).Resolve (rc); + target = new IndexerExpr (indexers, type, init, args, loc); return true; } } diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 10fc1121961..4890a89176f 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -3367,7 +3367,7 @@ namespace Mono.CSharp { var parent_this_block = pb; while (parent_this_block.Parent != null) { parent_this_block = parent_this_block.Parent.ParametersBlock; - if (parent_this_block.StateMachine != null) { + if (parent_this_block.StateMachine != null && parent_this_block.StateMachine.HoistedThis != null) { break; } } diff --git a/mcs/tests/gtest-autoproperty-21-lib.cs b/mcs/tests/gtest-autoproperty-21-lib.cs new file mode 100644 index 00000000000..15e9fa97b4f --- /dev/null +++ b/mcs/tests/gtest-autoproperty-21-lib.cs @@ -0,0 +1,6 @@ +// Compiler options: -t:library + +public abstract class Base +{ + public abstract string Value { get; } +} diff --git a/mcs/tests/gtest-autoproperty-21.cs b/mcs/tests/gtest-autoproperty-21.cs new file mode 100644 index 00000000000..4a900c8ca90 --- /dev/null +++ b/mcs/tests/gtest-autoproperty-21.cs @@ -0,0 +1,16 @@ +// Compiler options: -r:gtest-autoproperty-21-lib.dll + +public class Subclass : Base +{ + public override string Value { get; } + + public Subclass () + { + Value = "test"; + } + + public static void Main () + { + new Subclass (); + } +}
\ No newline at end of file diff --git a/mcs/tests/test-async-80.cs b/mcs/tests/test-async-80.cs new file mode 100644 index 00000000000..3f2b1274a93 --- /dev/null +++ b/mcs/tests/test-async-80.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using System; + +class X +{ + public async Task Test<T, U> (int arg) + { + await Task.Run (async () => { + await Task.Run (async () => { + Console.WriteLine (this); + }); + return arg; + } + ); + } + + public static void Main () + { + new X().Test<int, long>(1).Wait (); + } +}
\ No newline at end of file diff --git a/mcs/tests/test-dictinit-05.cs b/mcs/tests/test-dictinit-05.cs new file mode 100644 index 00000000000..2d052130956 --- /dev/null +++ b/mcs/tests/test-dictinit-05.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +class A { + public A () + { + Info = new Dictionary<string, int>(); + } + + public Dictionary<string, int> Info { get; set; } +} + +class X +{ + public static void Main () + { + var x = new A () { + Info = { + ["x"] = 1, + ["y"] = 2 + } + }; + } +}
\ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index 4a970c00528..08b0ee8ce9d 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -20726,6 +20726,19 @@ </method> </type> </test> + <test name="gtest-autoproperty-21.cs"> + <type name="Subclass"> + <method name="System.String get_Value()" attrs="2246"> + <size>14</size> + </method> + <method name="Void Main()" attrs="150"> + <size>8</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>19</size> + </method> + </type> + </test> <test name="gtest-collectioninit-01.cs"> <type name="Test"> <method name="Void TestList(System.Collections.Generic.List`1[System.Int32], Int32)" attrs="145"> @@ -65290,6 +65303,54 @@ </method> </type> </test> + <test name="test-async-80.cs"> + <type name="X"> + <method name="System.Threading.Tasks.Task Test[T,U](Int32)" attrs="134"> + <size>49</size> + </method> + <method name="Void Main()" attrs="150"> + <size>18</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>7</size> + </method> + </type> + <type name="X+<Test>c__async0`2[T,U]"> + <method name="Void MoveNext()" attrs="486"> + <size>219</size> + </method> + <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486"> + <size>13</size> + </method> + </type> + <type name="X+<Test>c__async0`2+<Test>c__AnonStorey32[T,U]"> + <method name="System.Threading.Tasks.Task`1[System.Int32] <>m__0()" attrs="131"> + <size>54</size> + </method> + <method name="System.Threading.Tasks.Task <>m__1()" attrs="131"> + <size>46</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>7</size> + </method> + </type> + <type name="X+<Test>c__async0`2+<Test>c__AnonStorey32+<Test>c__async2B[T,U]"> + <method name="Void MoveNext()" attrs="486"> + <size>191</size> + </method> + <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486"> + <size>13</size> + </method> + </type> + <type name="X+<Test>c__async0`2+<Test>c__AnonStorey32+<Test>c__async31[T,U]"> + <method name="Void MoveNext()" attrs="486"> + <size>77</size> + </method> + <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486"> + <size>13</size> + </method> + </type> + </test> <test name="test-cls-00.cs"> <type name="CLSCLass_6"> <method name="Void add_Disposed(Delegate)" attrs="2182"> @@ -66846,6 +66907,27 @@ </method> </type> </test> + <test name="test-dictinit-05.cs"> + <type name="A"> + <method name="System.Collections.Generic.Dictionary`2[System.String,System.Int32] get_Info()" attrs="2182"> + <size>14</size> + </method> + <method name="Void set_Info(System.Collections.Generic.Dictionary`2[System.String,System.Int32])" attrs="2182"> + <size>8</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>19</size> + </method> + </type> + <type name="X"> + <method name="Void Main()" attrs="150"> + <size>44</size> + </method> + <method name="Void .ctor()" attrs="6278"> + <size>7</size> + </method> + </type> + </test> <test name="test-ex-filter-01.cs"> <type name="X"> <method name="Int32 Main()" attrs="150"> diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index b6a75789387..fdc9dc70205 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -45,6 +45,7 @@ #include <mono/utils/mono-counters.h> #include <mono/utils/mono-error-internals.h> #include <mono/utils/mono-tls.h> +#include <mono/utils/mono-path.h> MonoDefaults mono_defaults; @@ -1428,7 +1429,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char const char *new_scope; char *error_msg; char *full_name, *file_name, *found_name = NULL; - int i; + int i,j; MonoDl *module = NULL; gboolean cached = FALSE; @@ -1576,23 +1577,85 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } if (!module && !is_absolute) { - void *iter = NULL; - char *mdirname = g_path_get_dirname (image->name); - while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { - module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg); - if (!module) { - mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, - "DllImport error loading library '%s': '%s'.", - full_name, error_msg); - g_free (error_msg); - } else { - found_name = g_strdup (full_name); + void *iter; + char *mdirname; + + for (j = 0; j < 3; ++j) { + iter = NULL; + mdirname = NULL; + switch (j) { + case 0: + mdirname = g_path_get_dirname (image->name); + break; + case 1: /* @executable_path@/../lib */ + { + char buf [4096]; + int binl; + binl = mono_dl_get_executable_path (buf, sizeof (buf)); + if (binl != -1) { + char *base, *newbase; + char *resolvedname; + buf [binl] = 0; + resolvedname = mono_path_resolve_symlinks (buf); + + base = g_path_get_dirname (resolvedname); + newbase = g_path_get_dirname(base); + mdirname = g_strdup_printf ("%s/lib", newbase); + + g_free (resolvedname); + g_free (base); + g_free (newbase); + } + break; + } +#ifdef __MACH__ + case 2: /* @executable_path@/../Libraries */ + { + char buf [4096]; + int binl; + binl = mono_dl_get_executable_path (buf, sizeof (buf)); + if (binl != -1) { + char *base, *newbase; + char *resolvedname; + buf [binl] = 0; + resolvedname = mono_path_resolve_symlinks (buf); + + base = g_path_get_dirname (resolvedname); + newbase = g_path_get_dirname(base); + mdirname = g_strdup_printf ("%s/Libraries", newbase); + + g_free (resolvedname); + g_free (base); + g_free (newbase); + } + break; + } +#endif } - g_free (full_name); + + if (!mdirname) + continue; + + while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) { + module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg); + if (!module) { + mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, + "DllImport error loading library '%s': '%s'.", + full_name, error_msg); + g_free (error_msg); + } else { + found_name = g_strdup (full_name); + } + g_free (full_name); + if (module) + break; + + } + g_free (mdirname); if (module) break; } - g_free (mdirname); + } if (!module) { diff --git a/mono/metadata/threadpool-ms-io.c b/mono/metadata/threadpool-ms-io.c index b3cc7ba8d95..3ef8b8c8fce 100644 --- a/mono/metadata/threadpool-ms-io.c +++ b/mono/metadata/threadpool-ms-io.c @@ -290,6 +290,7 @@ wait_callback (gint fd, gint events, gpointer user_data) MonoGHashTable *states; MonoMList *list = NULL; gpointer k; + gboolean remove_fd = FALSE; g_assert (user_data); states = user_data; @@ -311,14 +312,23 @@ wait_callback (gint fd, gint events, gpointer user_data) mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares); } - mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list); + remove_fd = (events & EVENT_ERR) == EVENT_ERR; + if (!remove_fd) { + mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list); - events = get_events (list); + events = get_events (list); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: res fd %3d, events = %2s | %2s", - fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : ".."); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: res fd %3d, events = %2s | %2s | %2s", + fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..", (events & EVENT_ERR) ? "ERR" : "..."); - threadpool_io->backend.register_fd (fd, events, FALSE); + threadpool_io->backend.register_fd (fd, events, FALSE); + } else { + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: err fd %d", fd); + + mono_g_hash_table_remove (states, GINT_TO_POINTER (fd)); + + threadpool_io->backend.remove_fd (fd); + } } } @@ -368,8 +378,8 @@ selector_thread (gpointer data) events = get_events (list); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, events = %2s | %2s", - exists ? "mod" : "add", fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : ".."); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, events = %2s | %2s | %2s", + exists ? "mod" : "add", fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..", (events & EVENT_ERR) ? "ERR" : "..."); threadpool_io->backend.register_fd (fd, events, !exists); diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 0458c475516..9f1ffc219a3 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -2502,6 +2502,7 @@ typedef struct gboolean last_frame_set; MonoContext ctx; gpointer lmf; + MonoDomain *domain; } GetLastFrameUserData; static gboolean @@ -2521,19 +2522,32 @@ get_last_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data) /* Store the context/lmf for the frame above the last frame */ memcpy (&data->ctx, ctx, sizeof (MonoContext)); data->lmf = info->lmf; + data->domain = info->domain; return TRUE; } } +static void +copy_unwind_state_from_frame_data (MonoThreadUnwindState *to, GetLastFrameUserData *data, gpointer jit_tls) +{ + memcpy (&to->ctx, &data->ctx, sizeof (MonoContext)); + + to->unwind_data [MONO_UNWIND_DATA_DOMAIN] = data->domain; + to->unwind_data [MONO_UNWIND_DATA_LMF] = data->lmf; + to->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls; + to->valid = TRUE; +} + /* * thread_interrupt: * * Process interruption of a thread. This should be signal safe. + * + * This always runs in the debugger thread. */ static void thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) { - gboolean res; gpointer ip; MonoNativeThreadId tid; @@ -2556,7 +2570,6 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) * tls->suspending flag to avoid races when that happens. */ if (!tls->suspended && !tls->suspending) { - MonoContext ctx; GetLastFrameUserData data; // FIXME: printf is not signal safe, but this is only used during @@ -2582,15 +2595,12 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) data.last_frame_set = FALSE; mono_get_eh_callbacks ()->mono_walk_stack_with_state (get_last_frame, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &data); if (data.last_frame_set) { + gpointer jit_tls = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data; + memcpy (&tls->async_last_frame, &data.last_frame, sizeof (StackFrameInfo)); - res = mono_thread_state_init_from_monoctx (&tls->async_state, &ctx); - g_assert (res); - mono_thread_state_init_from_monoctx (&tls->context, &ctx); - g_assert (res); - memcpy (&tls->async_state.ctx, &data.ctx, sizeof (MonoContext)); - tls->async_state.unwind_data [MONO_UNWIND_DATA_LMF] = data.lmf; - tls->async_state.unwind_data [MONO_UNWIND_DATA_JIT_TLS] = ((MonoThreadInfo*)tls->thread->thread_info)->jit_data; + copy_unwind_state_from_frame_data (&tls->async_state, &data, jit_tls); + copy_unwind_state_from_frame_data (&tls->context, &data, jit_tls); } else { tls->async_state.valid = FALSE; } diff --git a/mono/mini/iltests.il.in b/mono/mini/iltests.il.in index 8510917341b..bf1153ccae0 100644 --- a/mono/mini/iltests.il.in +++ b/mono/mini/iltests.il.in @@ -2781,4 +2781,20 @@ END: IL_001d: ldc.i4.1 IL_001e: ret } // end of method Tests::test_0_fceq_r4 + + .method public static int32 test_0_switch_loop () cil managed + { + .maxstack 16 + .locals init (valuetype Tests/TailCallStruct V_0, int32 V_1) + ldc.i4.0 + ldloc.0 + ldloc.1 + brtrue L_1 + L_0: + ldc.i4.4 + switch (L_0) + L_1: + pop + ret + } } diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 24b171b7d02..cb63252e001 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -9845,6 +9845,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b handle_stack_args (cfg, stack_start, sp - stack_start); sp = stack_start; CHECK_UNVERIFIABLE (cfg); + + /* Undo the links */ + mono_unlink_bblock (cfg, cfg->cbb, default_bblock); + for (i = 0; i < n; ++i) + mono_unlink_bblock (cfg, cfg->cbb, targets [i]); } MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, src1->dreg, n); diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index 9415c88cdc5..1f737ffe0dd 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -1192,6 +1192,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti MonoJumpInfoVirtMethod *info = data; MonoClass *iface_class = info->method->klass; MonoMethod *method; + MonoError error; int ioffset, slot; gpointer addr; @@ -1208,6 +1209,8 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti g_assert (info->klass->vtable); method = info->klass->vtable [ioffset + slot]; + method = mono_class_inflate_generic_method_checked (method, context, &error); + addr = mono_compile_method (method); return mini_add_method_trampoline (method, addr, mono_method_needs_static_rgctx_invoke (method, FALSE), FALSE); } diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index a261c17d24d..666db656def 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -5455,6 +5455,9 @@ mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call) } else if (opcode == OP_LMOVE) { MONO_INST_NEW (cfg, ins, OP_LMOVE); ins->dreg = mono_alloc_lreg (cfg); + } else if (opcode == OP_RMOVE) { + MONO_INST_NEW (cfg, ins, OP_RMOVE); + ins->dreg = mono_alloc_freg (cfg); } else { MONO_INST_NEW (cfg, ins, OP_MOVE); ins->dreg = mono_alloc_ireg (cfg); diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index 68ec25d84b9..f3ba1f0f895 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -422,7 +422,7 @@ mono_threads_unregister_current_thread (MonoThreadInfo *info) MonoThreadInfo* mono_thread_info_current_unchecked (void) { - return thread_info_key ? (MonoThreadInfo*)mono_native_tls_get_value (thread_info_key) : NULL; + return mono_threads_inited ? (MonoThreadInfo*)mono_native_tls_get_value (thread_info_key) : NULL; } @@ -579,8 +579,6 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size) res = mono_native_tls_alloc (&thread_exited_key, (void *) thread_exited_dtor); #endif - g_assert (thread_info_key); - g_assert (res); #ifndef HAVE_KW_THREAD |