Make permutation products aliasing by default.
diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h
index 4748b11..eb8e797 100644
--- a/Eigen/src/Core/PermutationMatrix.h
+++ b/Eigen/src/Core/PermutationMatrix.h
@@ -468,17 +468,17 @@
 /** \returns the matrix with the permutation applied to the columns.
  */
 template <typename MatrixDerived, typename PermutationDerived>
-EIGEN_DEVICE_FUNC const Product<MatrixDerived, PermutationDerived, AliasFreeProduct> operator*(
+EIGEN_DEVICE_FUNC const Product<MatrixDerived, PermutationDerived, DefaultProduct> operator*(
     const MatrixBase<MatrixDerived>& matrix, const PermutationBase<PermutationDerived>& permutation) {
-  return Product<MatrixDerived, PermutationDerived, AliasFreeProduct>(matrix.derived(), permutation.derived());
+  return Product<MatrixDerived, PermutationDerived, DefaultProduct>(matrix.derived(), permutation.derived());
 }
 
 /** \returns the matrix with the permutation applied to the rows.
  */
 template <typename PermutationDerived, typename MatrixDerived>
-EIGEN_DEVICE_FUNC const Product<PermutationDerived, MatrixDerived, AliasFreeProduct> operator*(
+EIGEN_DEVICE_FUNC const Product<PermutationDerived, MatrixDerived, DefaultProduct> operator*(
     const PermutationBase<PermutationDerived>& permutation, const MatrixBase<MatrixDerived>& matrix) {
-  return Product<PermutationDerived, MatrixDerived, AliasFreeProduct>(permutation.derived(), matrix.derived());
+  return Product<PermutationDerived, MatrixDerived, DefaultProduct>(permutation.derived(), matrix.derived());
 }
 
 template <typename PermutationType>
@@ -520,16 +520,16 @@
   /** \returns the matrix with the inverse permutation applied to the columns.
    */
   template <typename OtherDerived>
-  friend const Product<OtherDerived, InverseType, AliasFreeProduct> operator*(const MatrixBase<OtherDerived>& matrix,
-                                                                              const InverseType& trPerm) {
-    return Product<OtherDerived, InverseType, AliasFreeProduct>(matrix.derived(), trPerm.derived());
+  friend const Product<OtherDerived, InverseType, DefaultProduct> operator*(const MatrixBase<OtherDerived>& matrix,
+                                                                            const InverseType& trPerm) {
+    return Product<OtherDerived, InverseType, DefaultProduct>(matrix.derived(), trPerm.derived());
   }
 
   /** \returns the matrix with the inverse permutation applied to the rows.
    */
   template <typename OtherDerived>
-  const Product<InverseType, OtherDerived, AliasFreeProduct> operator*(const MatrixBase<OtherDerived>& matrix) const {
-    return Product<InverseType, OtherDerived, AliasFreeProduct>(derived(), matrix.derived());
+  const Product<InverseType, OtherDerived, DefaultProduct> operator*(const MatrixBase<OtherDerived>& matrix) const {
+    return Product<InverseType, OtherDerived, DefaultProduct>(derived(), matrix.derived());
   }
 };
 
diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp
index 2c83783..ee794b2 100644
--- a/test/permutationmatrices.cpp
+++ b/test/permutationmatrices.cpp
@@ -39,7 +39,8 @@
   RightTranspositionsType rt(rv);
   MatrixType m_permuted = MatrixType::Random(rows, cols);
 
-  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_original * rp, 1);  // 1 temp for sub expression "lp * m_original"
+  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = lp * m_original * rp,
+                          1);  // 1 temp for sub expression "lp * m_original"
 
   for (int i = 0; i < rows; i++)
     for (int j = 0; j < cols; j++) VERIFY_IS_APPROX(m_permuted(lv(i), j), m_original(i, rv(j)));
@@ -50,7 +51,7 @@
   VERIFY_IS_APPROX(m_permuted, lm * m_original * rm);
 
   m_permuted = m_original;
-  VERIFY_EVALUATION_COUNT(m_permuted = lp * m_permuted * rp, 1);
+  VERIFY_EVALUATION_COUNT(m_permuted.noalias() = lp * m_permuted * rp, 1);
   VERIFY_IS_APPROX(m_permuted, lm * m_original * rm);
 
   LeftPermutationType lpi;
@@ -169,6 +170,26 @@
   VERIFY_IS_APPROX(v1, (P.inverse() * rhs).eval());
 }
 
+void test_aliasing() {
+  // Bug #2869.
+  auto P = Eigen::PermutationMatrix<4>{Eigen::Vector4i{0, 2, 3, 1}};
+  {
+    Eigen::Vector<float, 5> z = {0.0f, 1.1f, 2.2f, 3.3f, 4.4f};
+    Eigen::Vector<float, 5> expected = z;
+    z.tail<4>() = P * z.head<4>();
+    expected.tail<4>() = (P * expected.head<4>()).eval();
+    VERIFY_IS_APPROX(z, expected);
+  }
+
+  {
+    // Obfuscate the aliasing in the RHS expression.
+    Eigen::Vector4f a = {1.1f, 2.2f, 3.3f, 4.4f};
+    Eigen::Vector4f expected = P * (a + Eigen::Vector4f::Zero()).cwiseSqrt();
+    a = P * (a + Eigen::Vector4f::Zero()).cwiseSqrt();
+    VERIFY_IS_APPROX(a, expected);
+  }
+}
+
 EIGEN_DECLARE_TEST(permutationmatrices) {
   for (int i = 0; i < g_repeat; i++) {
     CALL_SUBTEST_1(permutationmatrices(Matrix<float, 1, 1>()));
@@ -182,4 +203,5 @@
         MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
   }
   CALL_SUBTEST_5(bug890<double>());
+  CALL_SUBTEST_4(test_aliasing());
 }