[libcxx] r201021 - Fix for PR18735 - self-assignment for map/multimap gives incorrect results in C++03

Marshall Clow mclow.lists at gmail.com
Fri Feb 7 20:03:15 PST 2014


Author: marshall
Date: Fri Feb  7 22:03:14 2014
New Revision: 201021

URL: http://llvm.org/viewvc/llvm-project?rev=201021&view=rev
Log:
Fix for PR18735 - self-assignment for map/multimap gives incorrect results in C++03

Modified:
    libcxx/trunk/include/map
    libcxx/trunk/include/unordered_map
    libcxx/trunk/test/containers/associative/map/map.cons/copy_assign.pass.cpp
    libcxx/trunk/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp
    libcxx/trunk/test/containers/associative/multiset/multiset.cons/copy_assign.pass.cpp
    libcxx/trunk/test/containers/associative/set/set.cons/copy_assign.pass.cpp
    libcxx/trunk/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
    libcxx/trunk/test/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp

Modified: libcxx/trunk/include/map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/include/map (original)
+++ libcxx/trunk/include/map Fri Feb  7 22:03:14 2014
@@ -884,10 +884,12 @@ public:
 #if __cplusplus >= 201103L
             __tree_ = __m.__tree_;
 #else
-            __tree_.clear();
-            __tree_.value_comp() = __m.__tree_.value_comp();
-            __tree_.__copy_assign_alloc(__m.__tree_);
-            insert(__m.begin(), __m.end());
+            if (this != &__m) {
+                __tree_.clear();
+                __tree_.value_comp() = __m.__tree_.value_comp();
+                __tree_.__copy_assign_alloc(__m.__tree_);
+                insert(__m.begin(), __m.end());
+            }
 #endif
             return *this;
         }
@@ -1616,10 +1618,12 @@ public:
 #if __cplusplus >= 201103L
             __tree_ = __m.__tree_;
 #else
-            __tree_.clear();
-            __tree_.value_comp() = __m.__tree_.value_comp();
-            __tree_.__copy_assign_alloc(__m.__tree_);
-            insert(__m.begin(), __m.end());
+            if (this != &__m) {
+                __tree_.clear();
+                __tree_.value_comp() = __m.__tree_.value_comp();
+                __tree_.__copy_assign_alloc(__m.__tree_);
+                insert(__m.begin(), __m.end());
+            }
 #endif
             return *this;
         }

Modified: libcxx/trunk/include/unordered_map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/include/unordered_map (original)
+++ libcxx/trunk/include/unordered_map Fri Feb  7 22:03:14 2014
@@ -831,12 +831,14 @@ public:
 #if __cplusplus >= 201103L
         __table_ = __u.__table_;
 #else
-        __table_.clear();
-        __table_.hash_function() = __u.__table_.hash_function();
-        __table_.key_eq() = __u.__table_.key_eq();
-        __table_.max_load_factor() = __u.__table_.max_load_factor();
-        __table_.__copy_assign_alloc(__u.__table_);
-        insert(__u.begin(), __u.end());
+        if (this != &__u) {
+            __table_.clear();
+            __table_.hash_function() = __u.__table_.hash_function();
+            __table_.key_eq() = __u.__table_.key_eq();
+            __table_.max_load_factor() = __u.__table_.max_load_factor();
+            __table_.__copy_assign_alloc(__u.__table_);
+            insert(__u.begin(), __u.end());
+        }
 #endif
         return *this;
     }
@@ -1567,12 +1569,14 @@ public:
 #if __cplusplus >= 201103L
         __table_ = __u.__table_;
 #else
-        __table_.clear();
-        __table_.hash_function() = __u.__table_.hash_function();
-        __table_.key_eq() = __u.__table_.key_eq();
-        __table_.max_load_factor() = __u.__table_.max_load_factor();
-        __table_.__copy_assign_alloc(__u.__table_);
-        insert(__u.begin(), __u.end());
+        if (this != &__u) {
+            __table_.clear();
+            __table_.hash_function() = __u.__table_.hash_function();
+            __table_.key_eq() = __u.__table_.key_eq();
+            __table_.max_load_factor() = __u.__table_.max_load_factor();
+            __table_.__copy_assign_alloc(__u.__table_);
+            insert(__u.begin(), __u.end());
+        }
 #endif
         return *this;
     }

Modified: libcxx/trunk/test/containers/associative/map/map.cons/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/map/map.cons/copy_assign.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/associative/map/map.cons/copy_assign.pass.cpp (original)
+++ libcxx/trunk/test/containers/associative/map/map.cons/copy_assign.pass.cpp Fri Feb  7 22:03:14 2014
@@ -59,6 +59,21 @@ int main()
     }
     {
         typedef std::pair<const int, double> V;
+        const V ar[] =
+        {
+            V(1, 1),
+            V(2, 1),
+            V(3, 1),
+        };
+        std::map<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        std::map<int, double> *p = &m;
+        m = *p;
+
+        assert(m.size() == 3);
+        assert(std::equal(m.begin(), m.end(), ar));
+    }
+    {
+        typedef std::pair<const int, double> V;
         V ar[] =
         {
             V(1, 1),

Modified: libcxx/trunk/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp (original)
+++ libcxx/trunk/test/containers/associative/multimap/multimap.cons/copy_assign.pass.cpp Fri Feb  7 22:03:14 2014
@@ -50,6 +50,26 @@ int main()
     }
     {
         typedef std::pair<const int, double> V;
+        const V ar[] =
+        {
+            V(1, 1),
+            V(1, 1.5),
+            V(1, 2),
+            V(2, 1),
+            V(2, 1.5),
+            V(2, 2),
+            V(3, 1),
+            V(3, 1.5),
+            V(3, 2),
+        };
+        std::multimap<int, double> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        std::multimap<int, double> *p = &m;
+        m = *p;
+        assert(m.size() == sizeof(ar)/sizeof(ar[0]));
+        assert(std::equal(m.begin(), m.end(), ar));
+    }
+    {
+        typedef std::pair<const int, double> V;
         V ar[] =
         {
             V(1, 1),

Modified: libcxx/trunk/test/containers/associative/multiset/multiset.cons/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multiset/multiset.cons/copy_assign.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/associative/multiset/multiset.cons/copy_assign.pass.cpp (original)
+++ libcxx/trunk/test/containers/associative/multiset/multiset.cons/copy_assign.pass.cpp Fri Feb  7 22:03:14 2014
@@ -70,6 +70,26 @@ int main()
     }
     {
         typedef int V;
+        const V ar[] =
+        {
+            1,
+            1,
+            1,
+            2,
+            2,
+            2,
+            3,
+            3,
+            3
+        };
+        std::multiset<int> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        std::multiset<int> *p = &m;
+        m = *p;
+        assert(m.size() == 9);
+        assert(std::equal(m.begin(), m.end(), ar));
+    }
+    {
+        typedef int V;
         V ar[] =
         {
             1,

Modified: libcxx/trunk/test/containers/associative/set/set.cons/copy_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/set/set.cons/copy_assign.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/associative/set/set.cons/copy_assign.pass.cpp (original)
+++ libcxx/trunk/test/containers/associative/set/set.cons/copy_assign.pass.cpp Fri Feb  7 22:03:14 2014
@@ -58,6 +58,21 @@ int main()
     }
     {
         typedef int V;
+        const V ar[] =
+        {
+            1,
+            2,
+            3
+        };
+        std::set<int> m(ar, ar+sizeof(ar)/sizeof(ar[0]));
+        std::set<int> *p = &m;
+        m = *p;
+
+        assert(m.size() == 3);
+        assert(std::equal(m.begin(), m.end(), ar));
+    }
+    {
+        typedef int V;
         V ar[] =
         {
             1,

Modified: libcxx/trunk/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.map/unord.map.cnstr/assign_copy.pass.cpp Fri Feb  7 22:03:14 2014
@@ -73,6 +73,24 @@ int main()
         assert(c.max_load_factor() == 1);
     }
     {
+        typedef std::unordered_map<int, std::string> C;
+        typedef std::pair<const int, std::string> P;
+        const P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C *p = &c;
+		c = *p;
+        assert(c.size() == 4);
+        assert(std::is_permutation(c.begin(), c.end(), a));
+    }
+    {
         typedef other_allocator<std::pair<const int, std::string> > A;
         typedef std::unordered_map<int, std::string,
                                    test_hash<std::hash<int> >,

Modified: libcxx/trunk/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.pass.cpp Fri Feb  7 22:03:14 2014
@@ -87,6 +87,24 @@ int main()
         assert(c.max_load_factor() == 1);
     }
     {
+        typedef std::unordered_multimap<int, std::string> C;
+        typedef std::pair<const int, std::string> P;
+        const P a[] =
+        {
+            P(1, "one"),
+            P(2, "two"),
+            P(3, "three"),
+            P(4, "four"),
+            P(1, "four"),
+            P(2, "four"),
+        };
+        C c(a, a+sizeof(a)/sizeof(a[0]));
+        C *p = &c;
+        c = *p;
+        assert(c.size() == 6);
+        assert(std::is_permutation(c.begin(), c.end(), a));
+    }
+    {
         typedef other_allocator<std::pair<const int, std::string> > A;
         typedef std::unordered_multimap<int, std::string,
                                    test_hash<std::hash<int> >,

Modified: libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.pass.cpp Fri Feb  7 22:03:14 2014
@@ -80,6 +80,25 @@ int main()
         assert(c.max_load_factor() == 1);
     }
     {
+        typedef std::unordered_multiset<int> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C *p = &c;
+        c = *p;
+
+        assert(c.size() == 6);
+        assert(std::is_permutation(c.begin(), c.end(), a));
+    }
+    {
         typedef other_allocator<int> A;
         typedef std::unordered_multiset<int,
                                    test_hash<std::hash<int> >,

Modified: libcxx/trunk/test/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp?rev=201021&r1=201020&r2=201021&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.set/unord.set.cnstr/assign_copy.pass.cpp Fri Feb  7 22:03:14 2014
@@ -72,6 +72,24 @@ int main()
         assert(c.max_load_factor() == 1);
     }
     {
+        typedef std::unordered_set<int> C;
+        typedef int P;
+        P a[] =
+        {
+            P(1),
+            P(2),
+            P(3),
+            P(4),
+            P(1),
+            P(2)
+        };
+        C c(a, a + sizeof(a)/sizeof(a[0]));
+        C *p = &c;
+        c = *p;
+        assert(c.size() == 4);
+        assert(std::is_permutation(c.begin(), c.end(), a));
+    }
+    {
         typedef other_allocator<int> A;
         typedef std::unordered_set<int,
                                    test_hash<std::hash<int> >,





More information about the cfe-commits mailing list