fixed many conversion warnings on clang
diff --git a/example/example6.cpp b/example/example6.cpp
index 26552b7..e0bfb9e 100644
--- a/example/example6.cpp
+++ b/example/example6.cpp
@@ -133,22 +133,22 @@
        .def("__reversed__", [](const Sequence &s) -> Sequence { return s.reversed(); })
        /// Slicing protocol (optional)
        .def("__getitem__", [](const Sequence &s, py::slice slice) -> Sequence* {
-            py::ssize_t start, stop, step, slicelength;
+            size_t start, stop, step, slicelength;
             if (!slice.compute(s.size(), &start, &stop, &step, &slicelength))
                 throw py::error_already_set();
             Sequence *seq = new Sequence(slicelength);
-            for (int i=0; i<slicelength; ++i) {
+            for (size_t i=0; i<slicelength; ++i) {
                 (*seq)[i] = s[start]; start += step;
             }
             return seq;
         })
        .def("__setitem__", [](Sequence &s, py::slice slice, const Sequence &value) {
-            py::ssize_t start, stop, step, slicelength;
+            size_t start, stop, step, slicelength;
             if (!slice.compute(s.size(), &start, &stop, &step, &slicelength))
                 throw py::error_already_set();
-            if ((size_t) slicelength != value.size())
+            if (slicelength != value.size())
                 throw std::runtime_error("Left and right hand size of slice assignment have different sizes!");
-            for (int i=0; i<slicelength; ++i) {
+            for (size_t i=0; i<slicelength; ++i) {
                 s[start] = value[i]; start += step;
             }
         })
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index def3044..35726bf 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -471,13 +471,13 @@
         ssize_t length;
         int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src.ptr(), &buffer, &length);
         if (err == -1) { PyErr_Clear(); return false; }  // TypeError
-        value = std::string(buffer, length);
+        value = std::string(buffer, (size_t) length);
         success = true;
         return true;
     }
 
     static handle cast(const std::string &src, return_value_policy /* policy */, handle /* parent */) {
-        return PyUnicode_FromStringAndSize(src.c_str(), src.length());
+        return PyUnicode_FromStringAndSize(src.c_str(), (ssize_t) src.length());
     }
 
     PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
@@ -520,17 +520,17 @@
         if (temp) {
             int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length);
             if (err == -1) { buffer = nullptr; }  // TypeError
-            length = length / sizeof(wchar_t) - 1; ++buffer; // Skip BOM
+            length = length / (ssize_t) sizeof(wchar_t) - 1; ++buffer; // Skip BOM
         }
 #endif
         if (!buffer) { PyErr_Clear(); return false; }
-        value = std::wstring(buffer, length);
+        value = std::wstring(buffer, (size_t) length);
         success = true;
         return true;
     }
 
     static handle cast(const std::wstring &src, return_value_policy /* policy */, handle /* parent */) {
-        return PyUnicode_FromWideChar(src.c_str(), src.length());
+        return PyUnicode_FromWideChar(src.c_str(), (ssize_t) src.length());
     }
 
     PYBIND11_TYPE_CASTER(std::wstring, _(PYBIND11_STRING_NAME));
@@ -570,7 +570,7 @@
 
     static handle cast(const wchar_t *src, return_value_policy /* policy */, handle /* parent */) {
         if (src == nullptr) return handle(Py_None).inc_ref();
-        return PyUnicode_FromWideChar(src, wcslen(src));
+        return PyUnicode_FromWideChar(src, (ssize_t) wcslen(src));
     }
 
     static handle cast(wchar_t src, return_value_policy /* policy */, handle /* parent */) {
diff --git a/include/pybind11/common.h b/include/pybind11/common.h
index 272c207..5cab5e7 100644
--- a/include/pybind11/common.h
+++ b/include/pybind11/common.h
@@ -197,22 +197,23 @@
     size_t itemsize;             // Size of individual items in bytes
     size_t size;                 // Total number of entries
     std::string format;          // For homogeneous buffers, this should be set to format_descriptor<T>::value
-    int ndim;                    // Number of dimensions
+    size_t ndim;                 // Number of dimensions
     std::vector<size_t> shape;   // Shape of the tensor (1 entry per dimension)
     std::vector<size_t> strides; // Number of entries between adjacent entries (for each per dimension)
 
     buffer_info() : ptr(nullptr), view(nullptr) {}
-    buffer_info(void *ptr, size_t itemsize, const std::string &format, int ndim,
+    buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim,
                 const std::vector<size_t> &shape, const std::vector<size_t> &strides)
         : ptr(ptr), itemsize(itemsize), size(1), format(format),
           ndim(ndim), shape(shape), strides(strides) {
-        for (int i=0; i<ndim; ++i) size *= shape[i];
+        for (size_t i = 0; i < ndim; ++i)
+            size *= shape[i];
     }
 
     buffer_info(Py_buffer *view)
-        : ptr(view->buf), itemsize(view->itemsize), size(1), format(view->format),
-          ndim(view->ndim), shape(view->ndim), strides(view->ndim), view(view) {
-        for (int i = 0; i < view->ndim; ++i) {
+        : ptr(view->buf), itemsize((size_t) view->itemsize), size(1), format(view->format),
+          ndim((size_t) view->ndim), shape((size_t) view->ndim), strides((size_t) view->ndim), view(view) {
+        for (size_t i = 0; i < (size_t) view->ndim; ++i) {
             shape[i] = (size_t) view->shape[i];
             strides[i] = (size_t) view->strides[i];
             size *= shape[i];
diff --git a/include/pybind11/eigen.h b/include/pybind11/eigen.h
index 96daf48..006a7b9 100644
--- a/include/pybind11/eigen.h
+++ b/include/pybind11/eigen.h
@@ -10,9 +10,19 @@
 #pragma once
 
 #include "numpy.h"
+
+#if defined(__GNUG__) || defined(__clang__)
+#  pragma GCC diagnostic push
+#  pragma GCC diagnostic ignored "-Wconversion"
+#endif
+
 #include <Eigen/Core>
 #include <Eigen/SparseCore>
 
+#if defined(__GNUG__) || defined(__clang__)
+#  pragma GCC diagnostic pop
+#endif
+
 #if defined(_MSC_VER)
 #pragma warning(push)
 #pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
@@ -63,7 +73,7 @@
             auto strides = Strides(info.strides[0] / sizeof(Scalar), 0);
 
             value = Eigen::Map<Type, 0, Strides>(
-                (Scalar *) info.ptr, info.shape[0], 1, strides);
+                (Scalar *) info.ptr, typename Strides::Index(info.shape[0]), 1, strides);
         } else if (info.ndim == 2) {
             typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;
 
@@ -76,7 +86,9 @@
                 info.strides[rowMajor ? 1 : 0] / sizeof(Scalar));
 
             value = Eigen::Map<Type, 0, Strides>(
-                (Scalar *) info.ptr, info.shape[0], info.shape[1], strides);
+                (Scalar *) info.ptr,
+                typename Strides::Index(info.shape[0]),
+                typename Strides::Index(info.shape[1]), strides);
         } else {
             return false;
         }
@@ -117,8 +129,8 @@
                 { (size_t) src.rows(),
                   (size_t) src.cols() },
                 /* Strides (in bytes) for each index */
-                { sizeof(Scalar) * (rowMajor ? src.cols() : 1),
-                  sizeof(Scalar) * (rowMajor ? 1 : src.rows()) }
+                { sizeof(Scalar) * (rowMajor ? (size_t) src.cols() : 1),
+                  sizeof(Scalar) * (rowMajor ? 1 : (size_t) src.rows()) }
             )).release();
         }
     }
diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h
index f97c790..0180d95 100644
--- a/include/pybind11/numpy.h
+++ b/include/pybind11/numpy.h
@@ -109,7 +109,7 @@
         if (descr == nullptr)
             pybind11_fail("NumPy: unsupported buffer format '" + info.format + "'!");
         object tmp(api.PyArray_NewFromDescr_(
-            api.PyArray_Type_, descr, info.ndim, (Py_intptr_t *) &info.shape[0],
+            api.PyArray_Type_, descr, (int) info.ndim, (Py_intptr_t *) &info.shape[0],
             (Py_intptr_t *) &info.strides[0], info.ptr, 0, nullptr), false);
         if (info.ptr && tmp)
             tmp = object(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */), false);
@@ -261,7 +261,7 @@
 
         while (buffer_shape_iter != buffer.shape.rend()) {
             if (*shape_iter == *buffer_shape_iter)
-                *strides_iter = static_cast<int>(*buffer_strides_iter);
+                *strides_iter = static_cast<size_t>(*buffer_strides_iter);
             else
                 *strides_iter = 0;
 
@@ -286,12 +286,12 @@
 };
 
 template <size_t N>
-bool broadcast(const std::array<buffer_info, N>& buffers, int& ndim, std::vector<size_t>& shape) {
-    ndim = std::accumulate(buffers.begin(), buffers.end(), 0, [](int res, const buffer_info& buf) {
+bool broadcast(const std::array<buffer_info, N>& buffers, size_t& ndim, std::vector<size_t>& shape) {
+    ndim = std::accumulate(buffers.begin(), buffers.end(), size_t(0), [](size_t res, const buffer_info& buf) {
         return std::max(res, buf.ndim);
     });
 
-    shape = std::vector<size_t>(static_cast<size_t>(ndim), 1);
+    shape = std::vector<size_t>(ndim, 1);
     bool trivial_broadcast = true;
     for (size_t i = 0; i < N; ++i) {
         auto res_iter = shape.rbegin();
@@ -329,7 +329,7 @@
         std::array<buffer_info, N> buffers {{ args.request()... }};
 
         /* Determine dimensions parameters of output array */
-        int ndim = 0;
+        size_t ndim = 0;
         std::vector<size_t> shape(0);
         bool trivial_broadcast = broadcast(buffers, ndim, shape);
 
@@ -337,7 +337,7 @@
         std::vector<size_t> strides(ndim);
         if (ndim > 0) {
             strides[ndim-1] = sizeof(Return);
-            for (int i = ndim - 1; i > 0; --i) {
+            for (size_t i = ndim - 1; i > 0; --i) {
                 strides[i - 1] = strides[i] * shape[i];
                 size *= shape[i];
             }
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index 7ac9e5c..00a7fe0 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -336,8 +336,8 @@
                                 *it = overloads;
 
         /* Need to know how many arguments + keyword arguments there are to pick the right overload */
-        size_t nargs = PyTuple_GET_SIZE(args),
-               nkwargs = kwargs ? PyDict_Size(kwargs) : 0;
+        size_t nargs = (size_t) PyTuple_GET_SIZE(args),
+               nkwargs = kwargs ? (size_t) PyDict_Size(kwargs) : 0;
 
         handle parent = nargs > 0 ? PyTuple_GET_ITEM(args, 0) : nullptr,
                result = PYBIND11_TRY_NEXT_OVERLOAD;
@@ -547,7 +547,7 @@
                                               : std::string(rec->name));
         /* Basic type attributes */
         type->ht_type.tp_name = strdup(full_name.c_str());
-        type->ht_type.tp_basicsize = rec->instance_size;
+        type->ht_type.tp_basicsize = (ssize_t) rec->instance_size;
         type->ht_type.tp_base = (PyTypeObject *) rec->base_handle.ptr();
         rec->base_handle.inc_ref();
 
@@ -702,14 +702,14 @@
         view->ndim = 1;
         view->internal = info;
         view->buf = info->ptr;
-        view->itemsize = info->itemsize;
+        view->itemsize = (ssize_t) info->itemsize;
         view->len = view->itemsize;
         for (auto s : info->shape)
             view->len *= s;
         if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
             view->format = const_cast<char *>(info->format.c_str());
         if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
-            view->ndim = info->ndim;
+            view->ndim = (int) info->ndim;
             view->strides = (ssize_t *) &info->strides[0];
             view->shape = (ssize_t *) &info->shape[0];
         }
diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h
index 2ba03c0..ad9029b 100644
--- a/include/pybind11/pytypes.h
+++ b/include/pybind11/pytypes.h
@@ -336,7 +336,7 @@
     PYBIND11_OBJECT_DEFAULT(str, object, detail::PyUnicode_Check_Permissive)
 
     str(const std::string &s)
-        : object(PyUnicode_FromStringAndSize(s.c_str(), s.length()), false) {
+        : object(PyUnicode_FromStringAndSize(s.c_str(), (ssize_t) s.length()), false) {
         if (!m_ptr) pybind11_fail("Could not allocate string object!");
     }
 
@@ -352,7 +352,7 @@
         int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length);
         if (err == -1)
             pybind11_fail("Unable to extract string contents! (invalid type)");
-        return std::string(buffer, length);
+        return std::string(buffer, (size_t) length);
     }
 };
 
@@ -370,7 +370,7 @@
     PYBIND11_OBJECT_DEFAULT(bytes, object, PYBIND11_BYTES_CHECK)
 
     bytes(const std::string &s)
-        : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(s.data(), s.size()), false) {
+        : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(s.data(), (ssize_t) s.size()), false) {
         if (!m_ptr) pybind11_fail("Could not allocate bytes object!");
     }
 
@@ -380,7 +380,7 @@
         int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length);
         if (err == -1)
             pybind11_fail("Unable to extract bytes contents!");
-        return std::string(buffer, length);
+        return std::string(buffer, (size_t) length);
     }
 };
 
@@ -463,9 +463,12 @@
         m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr());
         if (!m_ptr) pybind11_fail("Could not allocate slice object!");
     }
-    bool compute(ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {
-        return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, length,
-                                    start, stop, step, slicelength) == 0;
+    bool compute(size_t length, size_t *start, size_t *stop, size_t *step,
+                 size_t *slicelength) const {
+        return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr,
+                                    (ssize_t) length, (ssize_t *) start,
+                                    (ssize_t *) stop, (ssize_t *) step,
+                                    (ssize_t *) slicelength) == 0;
     }
 };
 
diff --git a/include/pybind11/stl_bind.h b/include/pybind11/stl_bind.h
index 3783982..7de71c8 100644
--- a/include/pybind11/stl_bind.h
+++ b/include/pybind11/stl_bind.h
@@ -135,6 +135,7 @@
 pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::module &m, std::string const &name, Args&&... args) {
     using Vector = std::vector<T, Allocator>;
     using SizeType = typename Vector::size_type;
+    using DiffType = typename Vector::difference_type;
     using Class_ = pybind11::class_<Vector, holder_type>;
 
     Class_ cl(m, name.c_str(), std::forward<Args>(args)...);
@@ -176,7 +177,7 @@
 
     cl.def("insert",
         [](Vector &v, SizeType i, const T &x) {
-            v.insert(v.begin() + i, x);
+            v.insert(v.begin() + (DiffType) i, x);
         },
         arg("i") , arg("x"),
         "Insert an item at a given position."
@@ -198,7 +199,7 @@
             if (i >= v.size())
                 throw pybind11::index_error();
             T t = v[i];
-            v.erase(v.begin() + i);
+            v.erase(v.begin() + (DiffType) i);
             return t;
         },
         arg("i"),
@@ -232,7 +233,7 @@
         [](Vector &v, SizeType i) {
             if (i >= v.size())
                 throw pybind11::index_error();
-            v.erase(v.begin() + i);
+            v.erase(v.begin() + typename Vector::difference_type(i));
         },
         "Delete list elements using a slice object"
     );
@@ -249,7 +250,7 @@
     /// Slicing protocol
     cl.def("__getitem__",
         [](const Vector &v, slice slice) -> Vector * {
-            ssize_t start, stop, step, slicelength;
+            size_t start, stop, step, slicelength;
 
             if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
                 throw pybind11::error_already_set();
@@ -257,7 +258,7 @@
             Vector *seq = new Vector();
             seq->reserve((size_t) slicelength);
 
-            for (int i=0; i<slicelength; ++i) {
+            for (size_t i=0; i<slicelength; ++i) {
                 seq->push_back(v[start]);
                 start += step;
             }
@@ -269,14 +270,14 @@
 
     cl.def("__setitem__",
         [](Vector &v, slice slice,  const Vector &value) {
-            ssize_t start, stop, step, slicelength;
+            size_t start, stop, step, slicelength;
             if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
                 throw pybind11::error_already_set();
 
-            if ((size_t) slicelength != value.size())
+            if (slicelength != value.size())
                 throw std::runtime_error("Left and right hand size of slice assignment have different sizes!");
 
-            for (int i=0; i<slicelength; ++i) {
+            for (size_t i=0; i<slicelength; ++i) {
                 v[start] = value[i];
                 start += step;
             }
@@ -286,16 +287,16 @@
 
     cl.def("__delitem__",
         [](Vector &v, slice slice) {
-            ssize_t start, stop, step, slicelength;
+            size_t start, stop, step, slicelength;
 
             if (!slice.compute(v.size(), &start, &stop, &step, &slicelength))
                 throw pybind11::error_already_set();
 
             if (step == 1 && false) {
-                v.erase(v.begin() + start, v.begin() + start + slicelength);
+                v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
             } else {
-                for (ssize_t i = 0; i < slicelength; ++i) {
-                    v.erase(v.begin() + start);
+                for (size_t i = 0; i < slicelength; ++i) {
+                    v.erase(v.begin() + DiffType(start));
                     start += step - 1;
                 }
             }