diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 521c87f6210..936d171b9e4 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4401,7 +4401,35 @@ modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
   if (mutable_p)
     return false;
 
-  return (TREE_READONLY (obj) || CP_TYPE_CONST_P (TREE_TYPE (obj)));
+  if (TREE_READONLY (obj))
+    return true;
+
+  if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
+    {
+      /* Although a COMPONENT_REF may have a const type, we should
+	 only consider it modifying a const object when the field
+	 or object components is const.  This can happen when using
+	 constructs such as const_cast<const T &>(m), making something
+	 const even though it wasn't declared const.  */
+      if (TREE_CODE (obj) == COMPONENT_REF)
+	{
+	  tree op1 = TREE_OPERAND (obj, 1);
+	  if (CP_TYPE_CONST_P (TREE_TYPE (op1)))
+	    return true;
+	  else
+	    {
+	      tree op0 = TREE_OPERAND (obj, 0);
+	      /* The LHS of . or -> might itself be a COMPONENT_REF.  */
+	      if (TREE_CODE (op0) == COMPONENT_REF)
+		op0 = TREE_OPERAND (op0, 1);
+	      return CP_TYPE_CONST_P (TREE_TYPE (op0));
+	    }
+	}
+      else
+	return true;
+    }
+
+  return false;
 }
 
 /* Evaluate an INIT_EXPR or MODIFY_EXPR.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const17.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const17.C
new file mode 100644
index 00000000000..3f215d28175
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const17.C
@@ -0,0 +1,23 @@
+// PR c++/94074 - wrong modifying const object error for COMPONENT_REF.
+// { dg-do compile { target c++14 } }
+
+typedef decltype (sizeof (0)) size_t;
+
+template <typename E, size_t N>
+struct array
+{
+  constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
+  E elems[N];
+};
+
+template <typename T>
+struct S {
+  using U = array<T, 4>;
+  U m;
+  constexpr S(int) : m{}
+  {
+    const_cast<int &>(const_cast<const U &>(m)[0]) = 42;
+  }
+};
+
+constexpr S<int> p = { 10 };
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C
new file mode 100644
index 00000000000..11a680468c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C
@@ -0,0 +1,23 @@
+// PR c++/94074 - wrong modifying const object error for COMPONENT_REF.
+// { dg-do compile { target c++14 } }
+
+typedef decltype (sizeof (0)) size_t;
+
+template <typename E, size_t N>
+struct array
+{
+  constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
+  E elems[N];
+};
+
+template <typename T>
+struct S {
+  using U = array<T, 4>;
+  const U m;
+  constexpr S(int) : m{}
+  {
+    const_cast<int &>(const_cast<const U &>(m)[0]) = 42; // { dg-error "modifying a const object" }
+  }
+};
+
+constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C
new file mode 100644
index 00000000000..c31222ffcdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C
@@ -0,0 +1,23 @@
+// PR c++/94074 - wrong modifying const object error for COMPONENT_REF.
+// { dg-do compile { target c++14 } }
+
+typedef decltype (sizeof (0)) size_t;
+
+template <typename E, size_t N>
+struct array
+{
+  constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
+  const E elems[N];
+};
+
+template <typename T>
+struct S {
+  using U = array<T, 4>;
+  U m;
+  constexpr S(int) : m{}
+  {
+    const_cast<int &>(const_cast<const U &>(m)[0]) = 42; // { dg-error "modifying a const object" }
+  }
+};
+
+constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const20.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const20.C
new file mode 100644
index 00000000000..2d5034945bd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const20.C
@@ -0,0 +1,28 @@
+// PR c++/94074 - wrong modifying const object error for COMPONENT_REF.
+// { dg-do compile { target c++14 } }
+
+typedef decltype (sizeof (0)) size_t;
+
+template <typename E, size_t N>
+struct array
+{
+  constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
+  E elems[N];
+};
+
+template <typename E, size_t N>
+struct array2 {
+  array<E, N> a;
+};
+
+template <typename T>
+struct S {
+  using U = array2<T, 4>;
+  U m;
+  constexpr S(int) : m{}
+  {
+    const_cast<int &>(const_cast<const U &>(m).a[0]) = 42;
+  }
+};
+
+constexpr S<int> p = { 10 };
