Add Address Sanitizer support to std::vector

llvm-svn: 208319
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 5c520bd985ee51472d2396fe28a3ef8b30eb5a6c
diff --git a/include/__config b/include/__config
index fb775c6..ce39243 100644
--- a/include/__config
+++ b/include/__config
@@ -629,6 +629,11 @@
 #define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]]
 #endif
 
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" void __sanitizer_annotate_contiguous_container(
+  const void *, const void *, const void *, const void *);
+#endif
+
 // Try to find out if RTTI is disabled.
 // g++ and cl.exe have RTTI on by default and define a macro when it is.
 // g++ only defines the macro in 4.3.2 and onwards.
diff --git a/include/vector b/include/vector
index 6ac78d5..2cc23e5 100644
--- a/include/vector
+++ b/include/vector
@@ -483,6 +483,7 @@
 {
 private:
     typedef __vector_base<_Tp, _Allocator>           __base;
+    typedef allocator<_Tp>                           __default_allocator_type;
 public:
     typedef vector                                   __self;
     typedef _Tp                                      value_type;
@@ -749,7 +750,9 @@
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT
     {
+        size_type __old_size = size();
         __base::clear();
+        __annotate_shrink(__old_size);
         __invalidate_all_iterators();
     }
 
@@ -816,7 +819,9 @@
         }
         __get_db()->unlock();
 #endif
+        size_type __old_size = size();
         __base::__destruct_at_end(__new_last);
+        __annotate_shrink(__old_size);
     }
     template <class _Up>
         void
@@ -830,17 +835,52 @@
         void
         __emplace_back_slow_path(_Args&&... __args);
 #endif
+    // The following functions are no-ops outside of AddressSanitizer mode.
+    // We call annotatations only for the default Allocator because other allocators
+    // may not meet the AddressSanitizer alignment constraints.
+    // See the documentation for __sanitizer_annotate_contiguous_container for more details.
+    void __annotate_contiguous_container
+    (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid)
+    {
+#ifndef _LIBCPP_HAS_NO_ASAN
+      if (__beg && is_same<allocator_type, __default_allocator_type>::value)
+        __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid);
+#endif
+    }
+
+    void __annotate_new(size_type __current_size)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + capacity(), data() + __current_size);
+    }
+    void __annotate_delete()
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + size(), data() + capacity());
+    }
+    void __annotate_increase(size_type __n)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + size(), data() + size() + __n);
+    }
+    void __annotate_shrink(size_type __old_size)
+    {
+      __annotate_contiguous_container(data(), data() + capacity(),
+                                      data() + __old_size, data() + size());
+    }
 };
 
 template <class _Tp, class _Allocator>
 void
 vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v)
 {
+    __annotate_delete();
     __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_);
     _VSTD::swap(this->__begin_, __v.__begin_);
     _VSTD::swap(this->__end_, __v.__end_);
     _VSTD::swap(this->__end_cap(), __v.__end_cap());
     __v.__first_ = __v.__begin_;
+    __annotate_new(size());
     __invalidate_all_iterators();
 }
 
@@ -848,6 +888,7 @@
 typename vector<_Tp, _Allocator>::pointer
 vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p)
 {
+    __annotate_delete();
     pointer __r = __v.__begin_;
     __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_);
     __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_);
@@ -855,6 +896,7 @@
     _VSTD::swap(this->__end_, __v.__end_);
     _VSTD::swap(this->__end_cap(), __v.__end_cap());
     __v.__first_ = __v.__begin_;
+    __annotate_new(size());
     __invalidate_all_iterators();
     return __r;
 }
@@ -874,6 +916,7 @@
         this->__throw_length_error();
     this->__begin_ = this->__end_ = __alloc_traits::allocate(this->__alloc(), __n);
     this->__end_cap() = this->__begin_ + __n;
+    __annotate_new(0);
 }
 
 template <class _Tp, class _Allocator>
@@ -920,6 +963,7 @@
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
 {
     allocator_type& __a = this->__alloc();
+    __annotate_increase(__n);
     do
     {
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
@@ -940,6 +984,7 @@
 vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
 {
     allocator_type& __a = this->__alloc();
+    __annotate_increase(__n);
     do
     {
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
@@ -960,6 +1005,7 @@
     allocator_type& __a = this->__alloc();
     for (; __first != __last; ++__first)
     {
+        __annotate_increase(1);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
         ++this->__end_;
     }
@@ -972,6 +1018,7 @@
     allocator_type& __a = this->__alloc();
     for (; __first != __last; ++__first)
     {
+        __annotate_increase(1);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
                                   _VSTD::move(*__first));
         ++this->__end_;
@@ -1535,6 +1582,7 @@
 {
     if (this->__end_ != this->__end_cap())
     {
+        __annotate_increase(1);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_), __x);
         ++this->__end_;
@@ -1552,6 +1600,7 @@
 {
     if (this->__end_ < this->__end_cap())
     {
+        __annotate_increase(1);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_),
                                   _VSTD::move(__x));
@@ -1584,6 +1633,7 @@
 {
     if (this->__end_ < this->__end_cap())
     {
+        __annotate_increase(1);
         __alloc_traits::construct(this->__alloc(),
                                   _VSTD::__to_raw_pointer(this->__end_),
                                   _VSTD::forward<_Args>(__args)...);
@@ -1666,6 +1716,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
+        __annotate_increase(1);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1705,6 +1756,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
+        __annotate_increase(1);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1743,6 +1795,7 @@
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
+        __annotate_increase(1);
         if (__p == this->__end_)
         {
             __alloc_traits::construct(this->__alloc(),
@@ -1794,6 +1847,7 @@
             }
             if (__n > 0)
             {
+                __annotate_increase(__n);
                 __move_range(__p, __old_last, __p + __old_n);
                 const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
                 if (__p <= __xr && __xr < this->__end_)
@@ -1904,6 +1958,7 @@
             }
             if (__n > 0)
             {
+                __annotate_increase(__n);
                 __move_range(__p, __old_last, __p + __old_n);
                 _VSTD::copy(__first, __m, __p);
             }
diff --git a/test/containers/sequences/vector/asan.pass.cpp b/test/containers/sequences/vector/asan.pass.cpp
new file mode 100644
index 0000000..86c02b2
--- /dev/null
+++ b/test/containers/sequences/vector/asan.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// reference operator[](size_type n);
+
+#include <vector>
+#include <cassert>
+#include <cstdlib>
+
+#include "min_allocator.h"
+#include "asan_testing.h"
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" void __asan_set_error_exit_code(int);
+
+int main()
+{
+#if __cplusplus >= 201103L
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        c.reserve(2*c.size());
+        T foo = c[c.size()];    // bad, but not caught by ASAN
+    }
+#endif
+    
+    __asan_set_error_exit_code(0);
+    {
+        typedef int T;
+        typedef std::vector<T> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        c.reserve(2*c.size());
+        assert(is_contiguous_container_asan_correct(c)); 
+        assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity()));
+        T foo = c[c.size()];    // should trigger ASAN
+        assert(false);          // if we got here, ASAN didn't trigger
+    }
+}
+#else
+int main () { return 0; }
+#endif
diff --git a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
index a22c6da..21082c8 100644
--- a/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/capacity.pass.cpp
@@ -15,29 +15,34 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     {
         std::vector<int> v;
         assert(v.capacity() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int> v(100);
         assert(v.capacity() == 100);
         v.push_back(0);
         assert(v.capacity() > 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v;
         assert(v.capacity() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, min_allocator<int>> v(100);
         assert(v.capacity() == 100);
         v.push_back(0);
         assert(v.capacity() > 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
index 2914af9..4df5702 100644
--- a/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/reserve.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -22,6 +23,7 @@
         std::vector<int> v;
         v.reserve(10);
         assert(v.capacity() >= 10);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int> v(100);
@@ -32,6 +34,7 @@
         v.reserve(150);
         assert(v.size() == 100);
         assert(v.capacity() == 150);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, stack_allocator<int, 250> > v(100);
@@ -42,12 +45,14 @@
         v.reserve(150);
         assert(v.size() == 100);
         assert(v.capacity() == 150);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v;
         v.reserve(10);
         assert(v.capacity() >= 10);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, min_allocator<int>> v(100);
@@ -58,6 +63,7 @@
         v.reserve(150);
         assert(v.size() == 100);
         assert(v.capacity() == 150);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
index e415cee..a47c513 100644
--- a/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/resize_size.pass.cpp
@@ -16,6 +16,7 @@
 #include "../../../stack_allocator.h"
 #include "../../../MoveOnly.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -25,18 +26,22 @@
         v.resize(50);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<MoveOnly, stack_allocator<MoveOnly, 300> > v(100);
         v.resize(50);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
     {
@@ -44,18 +49,22 @@
         v.resize(50);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, stack_allocator<int, 300> > v(100);
         v.resize(50);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #if __cplusplus >= 201103L
@@ -64,9 +73,11 @@
         v.resize(50);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
index 49f373a..de5126b 100644
--- a/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/resize_size_value.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -27,6 +28,7 @@
         v.resize(200, 1);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
         for (unsigned i = 0; i < 50; ++i)
             assert(v[i] == 0);
         for (unsigned i = 50; i < 200; ++i)
@@ -40,6 +42,7 @@
         v.resize(200, 1);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
@@ -47,10 +50,12 @@
         v.resize(50, 1);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert((v == std::vector<int, min_allocator<int>>(50)));
         v.resize(200, 1);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
         for (unsigned i = 0; i < 50; ++i)
             assert(v[i] == 0);
         for (unsigned i = 50; i < 200; ++i)
@@ -61,9 +66,11 @@
         v.resize(50, 1);
         assert(v.size() == 50);
         assert(v.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.resize(200, 1);
         assert(v.size() == 200);
         assert(v.capacity() >= 200);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
index 6b0cce4..49ab9cc 100644
--- a/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/shrink_to_fit.pass.cpp
@@ -15,39 +15,48 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     {
         std::vector<int> v(100);
         v.push_back(1);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.shrink_to_fit();
         assert(v.capacity() == 101);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, stack_allocator<int, 401> > v(100);
         v.push_back(1);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.shrink_to_fit();
         assert(v.capacity() == 101);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #ifndef _LIBCPP_NO_EXCEPTIONS
     {
         std::vector<int, stack_allocator<int, 400> > v(100);
         v.push_back(1);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.shrink_to_fit();
         assert(v.capacity() == 200);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v(100);
         v.push_back(1);
+        assert(is_contiguous_container_asan_correct(v)); 
         v.shrink_to_fit();
         assert(v.capacity() == 101);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
index 46d8403..f3d9289 100644
--- a/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
+++ b/test/containers/sequences/vector/vector.capacity/swap.pass.cpp
@@ -15,27 +15,36 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     {
         std::vector<int> v1(100);
         std::vector<int> v2(200);
+        assert(is_contiguous_container_asan_correct(v1)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
         v1.swap(v2);
         assert(v1.size() == 200);
         assert(v1.capacity() == 200);
+        assert(is_contiguous_container_asan_correct(v1)); 
         assert(v2.size() == 100);
         assert(v2.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v2)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v1(100);
         std::vector<int, min_allocator<int>> v2(200);
+        assert(is_contiguous_container_asan_correct(v1)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
         v1.swap(v2);
         assert(v1.size() == 200);
         assert(v1.capacity() == 200);
+        assert(is_contiguous_container_asan_correct(v1)); 
         assert(v2.size() == 100);
         assert(v2.capacity() == 100);
+        assert(is_contiguous_container_asan_correct(v2)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
index c0dafce..f5c06b1 100644
--- a/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/assign_initializer_list.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -23,6 +24,7 @@
     std::vector<int> d;
     d.assign({3, 4, 5, 6});
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
@@ -33,6 +35,7 @@
     std::vector<int, min_allocator<int>> d;
     d.assign({3, 4, 5, 6});
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
diff --git a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
index 1365038..d87ac86 100644
--- a/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/assign_move.pass.cpp
@@ -16,6 +16,7 @@
 #include "../../../MoveOnly.h"
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -28,54 +29,72 @@
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, test_allocator<MoveOnly> > l2(test_allocator<MoveOnly>(5));
         l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5));
         std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, test_allocator<MoveOnly> > l2(test_allocator<MoveOnly>(6));
         l2 = std::move(l);
         assert(l2 == lo);
         assert(!l.empty());
         assert(l2.get_allocator() == test_allocator<MoveOnly>(6));
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5));
         std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, other_allocator<MoveOnly> > l2(other_allocator<MoveOnly>(6));
         l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
         std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, min_allocator<MoveOnly> > l2(min_allocator<MoveOnly>{});
         l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
 #endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
index 48c8cf8..75772be 100644
--- a/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_default.pass.cpp
@@ -18,6 +18,7 @@
 #include "../../../NotConstructible.h"
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -27,11 +28,13 @@
     assert(c.__invariants());
     assert(c.empty());
     assert(c.get_allocator() == typename C::allocator_type());
+    assert(is_contiguous_container_asan_correct(c)); 
 #if __cplusplus >= 201103L
     C c1 = {};
     assert(c1.__invariants());
     assert(c1.empty());
     assert(c1.get_allocator() == typename C::allocator_type());
+    assert(is_contiguous_container_asan_correct(c1)); 
 #endif
 }
 
@@ -43,6 +46,7 @@
     assert(c.__invariants());
     assert(c.empty());
     assert(c.get_allocator() == a);
+    assert(is_contiguous_container_asan_correct(c)); 
 }
 
 int main()
diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
index 8dde17f..36e231a 100644
--- a/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter.pass.cpp
@@ -17,6 +17,7 @@
 #include "test_iterators.h"
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C, class Iterator>
 void
@@ -25,6 +26,7 @@
     C c(first, last);
     assert(c.__invariants());
     assert(c.size() == std::distance(first, last));
+    assert(is_contiguous_container_asan_correct(c)); 
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first)
         assert(*i == *first);
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
index 9edc10c..7fa748a 100644
--- a/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_iter_iter_alloc.pass.cpp
@@ -18,6 +18,7 @@
 #include "test_iterators.h"
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C, class Iterator, class A>
 void
@@ -26,6 +27,7 @@
     C c(first, last, a);
     assert(c.__invariants());
     assert(c.size() == std::distance(first, last));
+    assert(is_contiguous_container_asan_correct(c)); 
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i, ++first)
         assert(*i == *first);
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
index c6bbf6e..e033895 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size.pass.cpp
@@ -17,6 +17,7 @@
 #include "DefaultOnly.h"
 #include "min_allocator.h"
 #include "test_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -27,6 +28,7 @@
     assert(c.__invariants());
     assert(c.size() == n);
     assert(c.get_allocator() == a);
+    assert(is_contiguous_container_asan_correct(c)); 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
         assert(*i == typename C::value_type());
@@ -42,6 +44,7 @@
     assert(c.__invariants());
     assert(c.size() == n);
     assert(c.get_allocator() == typename C::allocator_type());
+    assert(is_contiguous_container_asan_correct(c)); 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
         assert(*i == typename C::value_type());
diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
index 6a52d52..5b6c498 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size_value.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -24,6 +25,7 @@
     C c(n, x);
     assert(c.__invariants());
     assert(c.size() == n);
+    assert(is_contiguous_container_asan_correct(c)); 
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
         assert(*i == x);
 }
diff --git a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
index 5653521..c62b841 100644
--- a/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/construct_size_value_alloc.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -24,6 +25,7 @@
     assert(c.__invariants());
     assert(a == c.get_allocator());
     assert(c.size() == n);
+    assert(is_contiguous_container_asan_correct(c)); 
     for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e; ++i)
         assert(*i == x);
 }
diff --git a/test/containers/sequences/vector/vector.cons/copy.pass.cpp b/test/containers/sequences/vector/vector.cons/copy.pass.cpp
index 6962f70..677963d 100644
--- a/test/containers/sequences/vector/vector.cons/copy.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/copy.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -25,6 +26,7 @@
     assert(c.__invariants());
     assert(c.size() == s);
     assert(c == x);
+    assert(is_contiguous_container_asan_correct(c)); 
 }
 
 int main()
@@ -37,15 +39,23 @@
     {
         std::vector<int, test_allocator<int> > v(3, 2, test_allocator<int>(5));
         std::vector<int, test_allocator<int> > v2 = v;
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
         assert(v2 == v);
         assert(v2.get_allocator() == v.get_allocator());
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
     }
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
     {
         std::vector<int, other_allocator<int> > v(3, 2, other_allocator<int>(5));
         std::vector<int, other_allocator<int> > v2 = v;
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
         assert(v2 == v);
         assert(v2.get_allocator() == other_allocator<int>(-2));
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
     }
 #endif  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
 #if __cplusplus >= 201103L
@@ -57,8 +67,12 @@
     {
         std::vector<int, min_allocator<int> > v(3, 2, min_allocator<int>());
         std::vector<int, min_allocator<int> > v2 = v;
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
         assert(v2 == v);
         assert(v2.get_allocator() == v.get_allocator());
+        assert(is_contiguous_container_asan_correct(v)); 
+        assert(is_contiguous_container_asan_correct(v2)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
index 7ff2a1e..128328c 100644
--- a/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/copy_alloc.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 template <class C>
 void
@@ -25,6 +26,7 @@
     assert(c.__invariants());
     assert(c.size() == s);
     assert(c == x);
+    assert(is_contiguous_container_asan_correct(c)); 
 }
 
 int main()
diff --git a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
index f231fcf..7eb834f 100644
--- a/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/initializer_list.pass.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 #include <cassert>
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -21,6 +22,7 @@
     {
     std::vector<int> d = {3, 4, 5, 6};
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
@@ -30,6 +32,7 @@
     {
     std::vector<int, min_allocator<int>> d = {3, 4, 5, 6};
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
diff --git a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
index b57d2ed..5d7ae88 100644
--- a/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/initializer_list_alloc.pass.cpp
@@ -16,6 +16,7 @@
 
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -24,6 +25,7 @@
     std::vector<int, test_allocator<int>> d({3, 4, 5, 6}, test_allocator<int>(3));
     assert(d.get_allocator() == test_allocator<int>(3));
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
@@ -34,6 +36,7 @@
     std::vector<int, min_allocator<int>> d({3, 4, 5, 6}, min_allocator<int>());
     assert(d.get_allocator() == min_allocator<int>());
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
diff --git a/test/containers/sequences/vector/vector.cons/move.pass.cpp b/test/containers/sequences/vector/vector.cons/move.pass.cpp
index f09e346..bb61d54 100644
--- a/test/containers/sequences/vector/vector.cons/move.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/move.pass.cpp
@@ -16,6 +16,7 @@
 #include "../../../MoveOnly.h"
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -23,58 +24,79 @@
     {
         std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5));
         std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, test_allocator<MoveOnly> > l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5));
         std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, other_allocator<MoveOnly> > l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
         std::vector<int>::const_iterator i = c1.begin();
         std::vector<int> c2 = std::move(c1);
+        assert(is_contiguous_container_asan_correct(c2)); 
         std::vector<int>::iterator j = c2.erase(i);
         assert(*j == 3);
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
         std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, min_allocator<MoveOnly> > l2 = std::move(l);
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == lo.get_allocator());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
         std::vector<int, min_allocator<int>>::const_iterator i = c1.begin();
         std::vector<int, min_allocator<int>> c2 = std::move(c1);
+        assert(is_contiguous_container_asan_correct(c2)); 
         std::vector<int, min_allocator<int>>::iterator j = c2.erase(i);
         assert(*j == 3);
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
index 0aac64d..1923e68 100644
--- a/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/move_alloc.pass.cpp
@@ -16,6 +16,7 @@
 #include "../../../MoveOnly.h"
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -23,55 +24,75 @@
     {
         std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5));
         std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, test_allocator<MoveOnly> > l2(std::move(l), test_allocator<MoveOnly>(6));
         assert(l2 == lo);
         assert(!l.empty());
         assert(l2.get_allocator() == test_allocator<MoveOnly>(6));
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         std::vector<MoveOnly, test_allocator<MoveOnly> > l(test_allocator<MoveOnly>(5));
         std::vector<MoveOnly, test_allocator<MoveOnly> > lo(test_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, test_allocator<MoveOnly> > l2(std::move(l), test_allocator<MoveOnly>(5));
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == test_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
     {
         std::vector<MoveOnly, other_allocator<MoveOnly> > l(other_allocator<MoveOnly>(5));
         std::vector<MoveOnly, other_allocator<MoveOnly> > lo(other_allocator<MoveOnly>(5));
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, other_allocator<MoveOnly> > l2(std::move(l), other_allocator<MoveOnly>(4));
         assert(l2 == lo);
         assert(!l.empty());
         assert(l2.get_allocator() == other_allocator<MoveOnly>(4));
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<MoveOnly, min_allocator<MoveOnly> > l(min_allocator<MoveOnly>{});
         std::vector<MoveOnly, min_allocator<MoveOnly> > lo(min_allocator<MoveOnly>{});
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         for (int i = 1; i <= 3; ++i)
         {
             l.push_back(i);
             lo.push_back(i);
         }
+        assert(is_contiguous_container_asan_correct(l)); 
+        assert(is_contiguous_container_asan_correct(lo)); 
         std::vector<MoveOnly, min_allocator<MoveOnly> > l2(std::move(l), min_allocator<MoveOnly>());
         assert(l2 == lo);
         assert(l.empty());
         assert(l2.get_allocator() == min_allocator<MoveOnly>());
+        assert(is_contiguous_container_asan_correct(l2)); 
     }
 #endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
index 13ec845..592b714 100644
--- a/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.cons/op_equal_initializer_list.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -23,6 +24,7 @@
     std::vector<int> d;
     d = {3, 4, 5, 6};
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
@@ -33,6 +35,7 @@
     std::vector<int, min_allocator<int>> d;
     d = {3, 4, 5, 6};
     assert(d.size() == 4);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(d[0] == 3);
     assert(d[1] == 4);
     assert(d[2] == 5);
diff --git a/test/containers/sequences/vector/vector.data/data.pass.cpp b/test/containers/sequences/vector/vector.data/data.pass.cpp
index 4bda599..aed56bc 100644
--- a/test/containers/sequences/vector/vector.data/data.pass.cpp
+++ b/test/containers/sequences/vector/vector.data/data.pass.cpp
@@ -15,25 +15,30 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     {
         std::vector<int> v;
         assert(v.data() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int> v(100);
         assert(v.data() == &v.front());
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v;
         assert(v.data() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, min_allocator<int>> v(100);
         assert(v.data() == &v.front());
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.data/data_const.pass.cpp b/test/containers/sequences/vector/vector.data/data_const.pass.cpp
index 7cb64f8..cb60626 100644
--- a/test/containers/sequences/vector/vector.data/data_const.pass.cpp
+++ b/test/containers/sequences/vector/vector.data/data_const.pass.cpp
@@ -15,25 +15,30 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     {
         const std::vector<int> v;
         assert(v.data() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         const std::vector<int> v(100);
         assert(v.data() == &v.front());
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
         const std::vector<int, min_allocator<int>> v;
         assert(v.data() == 0);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         const std::vector<int, min_allocator<int>> v(100);
         assert(v.data() == &v.front());
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
index 37298a5..8af6bda 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -66,6 +67,7 @@
         assert(c.size() == 1);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         i = c.emplace(c.cend(), 3, 4.5);
         assert(i == c.end()-1);
         assert(c.size() == 2);
@@ -73,6 +75,7 @@
         assert(c.front().getd() == 3.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         i = c.emplace(c.cbegin()+1, 4, 6.5);
         assert(i == c.begin()+1);
         assert(c.size() == 3);
@@ -82,6 +85,7 @@
         assert(c[1].getd() == 6.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
     }
     {
         std::vector<A, stack_allocator<A, 7> > c;
@@ -90,6 +94,7 @@
         assert(c.size() == 1);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         i = c.emplace(c.cend(), 3, 4.5);
         assert(i == c.end()-1);
         assert(c.size() == 2);
@@ -97,6 +102,7 @@
         assert(c.front().getd() == 3.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         i = c.emplace(c.cbegin()+1, 4, 6.5);
         assert(i == c.begin()+1);
         assert(c.size() == 3);
@@ -106,6 +112,7 @@
         assert(c[1].getd() == 6.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
     }
 #if _LIBCPP_DEBUG >= 1
     {
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
index a399433..bbf91a4 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace_back.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
@@ -61,12 +62,14 @@
         assert(c.size() == 1);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         c.emplace_back(3, 4.5);
         assert(c.size() == 2);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
     }
     {
         std::vector<A, stack_allocator<A, 4> > c;
@@ -74,12 +77,14 @@
         assert(c.size() == 1);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         c.emplace_back(3, 4.5);
         assert(c.size() == 2);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
     }
 #if __cplusplus >= 201103L
     {
@@ -88,12 +93,14 @@
         assert(c.size() == 1);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
+        assert(is_contiguous_container_asan_correct(c)); 
         c.emplace_back(3, 4.5);
         assert(c.size() == 2);
         assert(c.front().geti() == 2);
         assert(c.front().getd() == 3.5);
         assert(c.back().geti() == 3);
         assert(c.back().getd() == 4.5);
+        assert(is_contiguous_container_asan_correct(c)); 
     }
 #endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
diff --git a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
index 04ff228..85a4707 100644
--- a/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/emplace_extra.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -22,31 +23,39 @@
     {
         std::vector<int> v;
         v.reserve(3);
+        assert(is_contiguous_container_asan_correct(v)); 
         v = { 1, 2, 3 };
         v.emplace(v.begin(), v.back());
         assert(v[0] == 3);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int> v;
         v.reserve(4);
+        assert(is_contiguous_container_asan_correct(v)); 
         v = { 1, 2, 3 };
         v.emplace(v.begin(), v.back());
         assert(v[0] == 3);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> v;
         v.reserve(3);
+        assert(is_contiguous_container_asan_correct(v)); 
         v = { 1, 2, 3 };
         v.emplace(v.begin(), v.back());
         assert(v[0] == 3);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
     {
         std::vector<int, min_allocator<int>> v;
         v.reserve(4);
+        assert(is_contiguous_container_asan_correct(v)); 
         v = { 1, 2, 3 };
         v.emplace(v.begin(), v.back());
         assert(v[0] == 3);
+        assert(is_contiguous_container_asan_correct(v)); 
     }
 #endif
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
index fb9d808..7a850ed 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -22,6 +23,7 @@
     int a1[] = {1, 2, 3};
     std::vector<int> l1(a1, a1+3);
     std::vector<int>::const_iterator i = l1.begin();
+    assert(is_contiguous_container_asan_correct(l1)); 
     ++i;
     std::vector<int>::iterator j = l1.erase(i);
     assert(l1.size() == 2);
@@ -29,21 +31,25 @@
     assert(*j == 3);
     assert(*l1.begin() == 1);
     assert(*next(l1.begin()) == 3);
+    assert(is_contiguous_container_asan_correct(l1)); 
     j = l1.erase(j);
     assert(j == l1.end());
     assert(l1.size() == 1);
     assert(distance(l1.begin(), l1.end()) == 1);
     assert(*l1.begin() == 1);
+    assert(is_contiguous_container_asan_correct(l1)); 
     j = l1.erase(l1.begin());
     assert(j == l1.end());
     assert(l1.size() == 0);
     assert(distance(l1.begin(), l1.end()) == 0);
+    assert(is_contiguous_container_asan_correct(l1)); 
     }
 #if __cplusplus >= 201103L
     {
     int a1[] = {1, 2, 3};
     std::vector<int, min_allocator<int>> l1(a1, a1+3);
     std::vector<int, min_allocator<int>>::const_iterator i = l1.begin();
+    assert(is_contiguous_container_asan_correct(l1)); 
     ++i;
     std::vector<int, min_allocator<int>>::iterator j = l1.erase(i);
     assert(l1.size() == 2);
@@ -51,15 +57,18 @@
     assert(*j == 3);
     assert(*l1.begin() == 1);
     assert(*next(l1.begin()) == 3);
+    assert(is_contiguous_container_asan_correct(l1)); 
     j = l1.erase(j);
     assert(j == l1.end());
     assert(l1.size() == 1);
     assert(distance(l1.begin(), l1.end()) == 1);
     assert(*l1.begin() == 1);
+    assert(is_contiguous_container_asan_correct(l1)); 
     j = l1.erase(l1.begin());
     assert(j == l1.end());
     assert(l1.size() == 0);
     assert(distance(l1.begin(), l1.end()) == 0);
+    assert(is_contiguous_container_asan_correct(l1)); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
index e82d3a0..bfc18bc 100644
--- a/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
@@ -15,84 +15,113 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
     int a1[] = {1, 2, 3};
     {
         std::vector<int> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int>::iterator i = l1.erase(l1.cbegin(), l1.cbegin());
         assert(l1.size() == 3);
         assert(distance(l1.cbegin(), l1.cend()) == 3);
         assert(i == l1.begin());
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin()));
         assert(l1.size() == 2);
         assert(distance(l1.cbegin(), l1.cend()) == 2);
         assert(i == l1.begin());
         assert(l1 == std::vector<int>(a1+1, a1+3));
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2));
         assert(l1.size() == 1);
         assert(distance(l1.cbegin(), l1.cend()) == 1);
         assert(i == l1.begin());
         assert(l1 == std::vector<int>(a1+2, a1+3));
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3));
         assert(l1.size() == 0);
         assert(distance(l1.cbegin(), l1.cend()) == 0);
         assert(i == l1.begin());
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<std::vector<int> > outer(2, std::vector<int>(1));
+        assert(is_contiguous_container_asan_correct(outer)); 
+        assert(is_contiguous_container_asan_correct(outer[0])); 
+        assert(is_contiguous_container_asan_correct(outer[1])); 
         outer.erase(outer.begin(), outer.begin());
         assert(outer.size() == 2);
         assert(outer[0].size() == 1);
         assert(outer[1].size() == 1);
+        assert(is_contiguous_container_asan_correct(outer)); 
+        assert(is_contiguous_container_asan_correct(outer[0])); 
+        assert(is_contiguous_container_asan_correct(outer[1])); 
     }
 #if __cplusplus >= 201103L
     {
         std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), l1.cbegin());
         assert(l1.size() == 3);
         assert(distance(l1.cbegin(), l1.cend()) == 3);
         assert(i == l1.begin());
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin()));
         assert(l1.size() == 2);
         assert(distance(l1.cbegin(), l1.cend()) == 2);
         assert(i == l1.begin());
         assert((l1 == std::vector<int, min_allocator<int>>(a1+1, a1+3)));
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 2));
         assert(l1.size() == 1);
         assert(distance(l1.cbegin(), l1.cend()) == 1);
         assert(i == l1.begin());
         assert((l1 == std::vector<int, min_allocator<int>>(a1+2, a1+3)));
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<int, min_allocator<int>> l1(a1, a1+3);
+        assert(is_contiguous_container_asan_correct(l1)); 
         std::vector<int, min_allocator<int>>::iterator i = l1.erase(l1.cbegin(), next(l1.cbegin(), 3));
         assert(l1.size() == 0);
         assert(distance(l1.cbegin(), l1.cend()) == 0);
         assert(i == l1.begin());
+        assert(is_contiguous_container_asan_correct(l1)); 
     }
     {
         std::vector<std::vector<int, min_allocator<int>>, min_allocator<std::vector<int, min_allocator<int>>>> outer(2, std::vector<int, min_allocator<int>>(1));
+        assert(is_contiguous_container_asan_correct(outer)); 
+        assert(is_contiguous_container_asan_correct(outer[0])); 
+        assert(is_contiguous_container_asan_correct(outer[1])); 
         outer.erase(outer.begin(), outer.begin());
         assert(outer.size() == 2);
         assert(outer[0].size() == 1);
         assert(outer[1].size() == 1);
+        assert(is_contiguous_container_asan_correct(outer)); 
+        assert(is_contiguous_container_asan_correct(outer[0])); 
+        assert(is_contiguous_container_asan_correct(outer[1])); 
     }
 #endif
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
index 386a4f6..30b8017 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_initializer_list.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -23,6 +24,7 @@
     std::vector<int> d(10, 1);
     std::vector<int>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
     assert(d.size() == 14);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(i == d.begin() + 2);
     assert(d[0] == 1);
     assert(d[1] == 1);
@@ -44,6 +46,7 @@
     std::vector<int, min_allocator<int>> d(10, 1);
     std::vector<int, min_allocator<int>>::iterator i = d.insert(d.cbegin() + 2, {3, 4, 5, 6});
     assert(d.size() == 14);
+    assert(is_contiguous_container_asan_correct(d)); 
     assert(i == d.begin() + 2);
     assert(d[0] == 1);
     assert(d[1] == 1);
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
index 97255b0..cf24a87 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
@@ -21,6 +21,7 @@
 #include "../../../stack_allocator.h"
 #include "test_iterators.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -31,6 +32,7 @@
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
                                         input_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -47,6 +49,7 @@
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
                                         forward_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -63,6 +66,7 @@
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
                                         input_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -79,6 +83,7 @@
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
                                         forward_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -107,6 +112,7 @@
         std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, input_iterator<const int*>(a),
                                         input_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -123,6 +129,7 @@
         std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, forward_iterator<const int*>(a),
                                         forward_iterator<const int*>(a+N));
         assert(v.size() == 100 + N);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
index 7ceb933..cf3715c 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_rvalue.pass.cpp
@@ -20,6 +20,7 @@
 #include "../../../stack_allocator.h"
 #include "../../../MoveOnly.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -28,6 +29,7 @@
         std::vector<MoveOnly> v(100);
         std::vector<MoveOnly>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3));
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -40,6 +42,7 @@
         std::vector<MoveOnly, stack_allocator<MoveOnly, 300> > v(100);
         std::vector<MoveOnly, stack_allocator<MoveOnly, 300> >::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3));
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -61,6 +64,7 @@
         std::vector<MoveOnly, min_allocator<MoveOnly>> v(100);
         std::vector<MoveOnly, min_allocator<MoveOnly>>::iterator i = v.insert(v.cbegin() + 10, MoveOnly(3));
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
index 322c9ff..42effc7 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_size_value.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -26,6 +27,7 @@
         std::vector<int> v(100);
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
         assert(v.size() == 105);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -39,6 +41,7 @@
         std::vector<int, stack_allocator<int, 300> > v(100);
         std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 5, 1);
         assert(v.size() == 105);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -61,6 +64,7 @@
         std::vector<int, min_allocator<int>> v(100);
         std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
         assert(v.size() == 105);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -74,6 +78,7 @@
         std::vector<int, min_allocator<int>> v(100);
         std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 5, 1);
         assert(v.size() == 105);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
diff --git a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
index 28c7718..feb74c0 100644
--- a/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/insert_iter_value.pass.cpp
@@ -19,6 +19,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -26,6 +27,7 @@
         std::vector<int> v(100);
         std::vector<int>::iterator i = v.insert(v.cbegin() + 10, 1);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -38,6 +40,7 @@
         std::vector<int, stack_allocator<int, 300> > v(100);
         std::vector<int, stack_allocator<int, 300> >::iterator i = v.insert(v.cbegin() + 10, 1);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
@@ -60,6 +63,7 @@
         std::vector<int, min_allocator<int>> v(100);
         std::vector<int, min_allocator<int>>::iterator i = v.insert(v.cbegin() + 10, 1);
         assert(v.size() == 101);
+        assert(is_contiguous_container_asan_correct(v)); 
         assert(i == v.begin() + 10);
         int j;
         for (j = 0; j < 10; ++j)
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
index 5446b74..eeeba62 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back.pass.cpp
@@ -15,6 +15,7 @@
 #include <cassert>
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -22,22 +23,27 @@
         std::vector<int> c;
         c.push_back(0);
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(1);
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(2);
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(3);
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(4);
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
     }
@@ -45,22 +51,27 @@
         std::vector<int, stack_allocator<int, 15> > c;
         c.push_back(0);
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(1);
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(2);
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(3);
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(4);
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
     }
@@ -69,22 +80,27 @@
         std::vector<int, min_allocator<int>> c;
         c.push_back(0);
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(1);
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(2);
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(3);
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
         c.push_back(4);
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == j);
     }
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
index f232743..6615a25 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp
@@ -14,6 +14,8 @@
 #include <vector>
 #include <cassert>
 
+#include "asan_testing.h"
+
 // Flag that makes the copy constructor for CMyClass throw an exception
 static bool gCopyConstructorShouldThow = false;
 
@@ -70,6 +72,8 @@
 
     vec.push_back(instance);
     std::vector<CMyClass> vec2(vec);
+    assert(is_contiguous_container_asan_correct(vec)); 
+    assert(is_contiguous_container_asan_correct(vec2)); 
 
     gCopyConstructorShouldThow = true;
     try {
@@ -77,5 +81,6 @@
     }
     catch (...) {
         assert(vec==vec2);
+        assert(is_contiguous_container_asan_correct(vec)); 
     }
 }
diff --git a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
index bb1af29..be48893 100644
--- a/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
+++ b/test/containers/sequences/vector/vector.modifiers/push_back_rvalue.pass.cpp
@@ -16,6 +16,7 @@
 #include "../../../MoveOnly.h"
 #include "../../../stack_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -24,22 +25,27 @@
         std::vector<MoveOnly> c;
         c.push_back(MoveOnly(0));
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(1));
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(2));
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(3));
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(4));
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
     }
@@ -47,22 +53,27 @@
         std::vector<MoveOnly, stack_allocator<MoveOnly, 15> > c;
         c.push_back(MoveOnly(0));
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(1));
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(2));
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(3));
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(4));
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
     }
@@ -71,22 +82,27 @@
         std::vector<MoveOnly, min_allocator<MoveOnly>> c;
         c.push_back(MoveOnly(0));
         assert(c.size() == 1);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(1));
         assert(c.size() == 2);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(2));
         assert(c.size() == 3);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(3));
         assert(c.size() == 4);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
         c.push_back(MoveOnly(4));
         assert(c.size() == 5);
+        assert(is_contiguous_container_asan_correct(c)); 
         for (int j = 0; j < c.size(); ++j)
             assert(c[j] == MoveOnly(j));
     }
diff --git a/test/containers/sequences/vector/vector.special/swap.pass.cpp b/test/containers/sequences/vector/vector.special/swap.pass.cpp
index a7d0c40..27001ae 100644
--- a/test/containers/sequences/vector/vector.special/swap.pass.cpp
+++ b/test/containers/sequences/vector/vector.special/swap.pass.cpp
@@ -16,6 +16,7 @@
 #include <cassert>
 #include "test_allocator.h"
 #include "min_allocator.h"
+#include "asan_testing.h"
 
 int main()
 {
@@ -24,40 +25,56 @@
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
         std::vector<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1 == std::vector<int>(a2, a2+sizeof(a2)/sizeof(a2[0])));
         assert(c2 == std::vector<int>(a1, a1+sizeof(a1)/sizeof(a1[0])));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int> c1(a1, a1);
         std::vector<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1 == std::vector<int>(a2, a2+sizeof(a2)/sizeof(a2[0])));
         assert(c2.empty());
         assert(distance(c2.begin(), c2.end()) == 0);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
         std::vector<int> c2(a2, a2);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1.empty());
         assert(distance(c1.begin(), c1.end()) == 0);
         assert(c2 == std::vector<int>(a1, a1+sizeof(a1)/sizeof(a1[0])));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int> c1(a1, a1);
         std::vector<int> c2(a2, a2);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1.empty());
         assert(distance(c1.begin(), c1.end()) == 0);
         assert(c2.empty());
         assert(distance(c2.begin(), c2.end()) == 0);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #ifndef _LIBCPP_DEBUG_LEVEL
 // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1
@@ -80,11 +97,15 @@
         typedef other_allocator<int> A;
         std::vector<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A(1));
         std::vector<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A(2));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert((c1 == std::vector<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
         assert(c1.get_allocator() == A(2));
         assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
         assert(c2.get_allocator() == A(1));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #if __cplusplus >= 201103L
     {
@@ -92,40 +113,56 @@
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
         std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
         assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int, min_allocator<int>> c1(a1, a1);
         std::vector<int, min_allocator<int>> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert((c1 == std::vector<int, min_allocator<int>>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
         assert(c2.empty());
         assert(distance(c2.begin(), c2.end()) == 0);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int, min_allocator<int>> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
         std::vector<int, min_allocator<int>> c2(a2, a2);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1.empty());
         assert(distance(c1.begin(), c1.end()) == 0);
         assert((c2 == std::vector<int, min_allocator<int>>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
     {
         int a1[] = {1, 3, 7, 9, 10};
         int a2[] = {0, 2, 4, 5, 6, 8, 11};
         std::vector<int, min_allocator<int>> c1(a1, a1);
         std::vector<int, min_allocator<int>> c2(a2, a2);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert(c1.empty());
         assert(distance(c1.begin(), c1.end()) == 0);
         assert(c2.empty());
         assert(distance(c2.begin(), c2.end()) == 0);
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #ifndef _LIBCPP_DEBUG_LEVEL
 // This test known to result in undefined behavior detected by _LIBCPP_DEBUG_LEVEL >= 1
@@ -135,11 +172,15 @@
         typedef min_allocator<int> A;
         std::vector<int, A> c1(a1, a1+sizeof(a1)/sizeof(a1[0]), A());
         std::vector<int, A> c2(a2, a2+sizeof(a2)/sizeof(a2[0]), A());
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
         swap(c1, c2);
         assert((c1 == std::vector<int, A>(a2, a2+sizeof(a2)/sizeof(a2[0]))));
         assert(c1.get_allocator() == A());
         assert((c2 == std::vector<int, A>(a1, a1+sizeof(a1)/sizeof(a1[0]))));
         assert(c2.get_allocator() == A());
+        assert(is_contiguous_container_asan_correct(c1)); 
+        assert(is_contiguous_container_asan_correct(c2)); 
     }
 #endif
 #endif
diff --git a/test/support/asan_testing.h b/test/support/asan_testing.h
new file mode 100644
index 0000000..c8797bd
--- /dev/null
+++ b/test/support/asan_testing.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASAN_TESTING_H
+#define ASAN_TESTING_H
+
+#include <__config>
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" int __sanitizer_verify_contiguous_container
+     ( const void *beg, const void *mid, const void *end );
+     
+template <typename T, typename Alloc>
+bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c )
+{
+    if ( std::is_same<Alloc, std::allocator<T>>::value && c.data() != NULL)
+        return __sanitizer_verify_contiguous_container (
+            c.data(), c.data() + c.size(), c.data() + c.capacity()) != 0;
+    return true;
+}
+
+#else
+template <typename T, typename Alloc>
+bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c )
+{
+    return true;
+}
+#endif
+ 
+
+#endif  // ASAN_TESTING_H
\ No newline at end of file