Merge branch 'master' of https://github.com/mono/mono into issue4328
authorKonrad M. Kruczynski <kkruczynski@antmicro.com>
Thu, 13 Sep 2012 14:19:53 +0000 (16:19 +0200)
committerKonrad M. Kruczynski <kkruczynski@antmicro.com>
Thu, 13 Sep 2012 14:19:53 +0000 (16:19 +0200)
Conflicts:
mcs/class/System/Test/System.Collections.Generic/SortedListTest.cs

1  2 
mcs/class/System/System.Collections.Generic/SortedList.cs
mcs/class/System/Test/System.Collections.Generic/SortedListTest.cs

index 2a4ccc4fc6f4a34697fd514845583442a68bfb14,259d0f8236f17714cf254a3f9dd41474103812c4..c1190b2ad26d67daeeecc6c79191814e56db3879
@@@ -305,12 -305,16 +305,12 @@@ namespace System.Collections.Generi
  
                void ICollection<KeyValuePair<TKey, TValue>>.Clear () 
                {
 -                      defaultCapacity = INITIAL_SIZE;
 -                      this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
 -                      inUse = 0;
 -                      modificationCount++;
 +                      Clear ();
                }
  
                public void Clear () 
                {
 -                      defaultCapacity = INITIAL_SIZE;
 -                      this.table = new KeyValuePair<TKey, TValue> [defaultCapacity];
 +                      Array.Clear (table, 0, table.Length);
                        inUse = 0;
                        modificationCount++;
                }
                        if (key == null)
                                throw new ArgumentNullException ("key");
  
-                       int indx = 0;
-                       try {
-                               indx = Find (key);
-                       } catch (Exception) {
-                               throw new InvalidOperationException();
-                       }
+                       int indx = Find (key);
  
                        return (indx | (indx >> 31));
                }
  
                        KeyValuePair<TKey, TValue> [] table = this.table;
  
-                       int freeIndx = -1;
-                       try {
-                               freeIndx = Find (key);
-                       } catch (Exception) {
-                               throw new InvalidOperationException();
-                       }
+                       int freeIndx = Find (key);
  
                        if (freeIndx >= 0) {
                                if (!overwrite)
                        }
                }
  
+               private int Compare (TKey a, TKey b)
+               {
+                       try {
+                               return comparer.Compare (a, b);
+                       } catch (Exception ex) {
+                               throw new InvalidOperationException ("Failed to compare two elements.", ex);
+                       }
+               }
                private int Find (TKey key)
                {
                        KeyValuePair<TKey, TValue> [] table = this.table;
                        while (left <= right) {
                                int guess = (left + right) >> 1;
  
-                               int cmp = comparer.Compare (table[guess].Key, key);
+                               int cmp = Compare (table[guess].Key, key);
                                if (cmp == 0) return guess;
  
                                if (cmp <  0) left = guess+1;
index fa9eedb1b15eca0c6a62413b9b0338a52e1a9240,dcacc78373d7c0efb80cdcc18c6f221903c86327..4ecaba16d467d10d6053b9b74c2c08936ebc79f2
@@@ -464,18 -464,45 +464,58 @@@ namespace MonoTests.System.Collections.
                        Assert.IsTrue(sl.Keys[2] == 3, "NCIC #D3");
                }
  
 +              [Test]
 +              public void ClearDoesNotTouchCapacity ()
 +              {
 +                      SortedList<int, int> sl = new SortedList<int, int> ();
 +                      for (int i = 0; i < 18; i++) {
 +                              sl.Add (i, i);
 +                      }
 +                      int capacityBeforeClear = sl.Capacity;
 +                      sl.Clear ();
 +                      int capacityAfterClear = sl.Capacity;
 +                      Assert.AreEqual (capacityBeforeClear, capacityAfterClear);
 +              }
++
+               class Uncomparable : IComparer<double>
+               {
+                       public int Compare (double x, double y)
+                       {
+                               throw new DivideByZeroException ();
+                       }
+               }
+               [Test]
+               // Bug #4327
+               public void UncomparableList ()
+               {
+                       var list = new SortedList<double, int> (new Uncomparable ());
+                       list.Add (Math.PI, 1);
+                       try {
+                               list.Add (Math.E, 2);
+                               Assert.Fail ("UC #1");
+                       } catch (Exception ex) {
+                               Assert.IsInstanceOfType (
+                                       typeof (InvalidOperationException), ex, "UC #2");
+                               Assert.That (ex.InnerException != null, "UC #3");
+                               Assert.IsInstanceOfType (
+                                       typeof (DivideByZeroException), ex.InnerException, "UC #4");
+                       }
+                       try {
+                               int a;
+                               list.TryGetValue (Math.E, out a);
+                               Assert.Fail ("UC #5");
+                       } catch (Exception ex) {
+                               Assert.IsInstanceOfType (
+                                       typeof (InvalidOperationException), ex, "UC #5");
+                               Assert.That (ex.InnerException != null, "UC #6");
+                               Assert.IsInstanceOfType (
+                                       typeof (DivideByZeroException), ex.InnerException, "UC #7");
+                       }
+               }
        }
  }