sgallagh / rpms / gcc

Forked from rpms/gcc 4 years ago
Clone
Blob Blame History Raw
2019-03-12  Jakub Jelinek  <jakub@redhat.com>

	PR c++/89652
	* constexpr.c (cxx_eval_loop_expr): Only remove SAVE_EXPRs that are
	still in new_ctx.values hash_map.

	* g++.dg/cpp1y/constexpr-89652.C: New test.

--- gcc/cp/constexpr.c.jj	2019-03-08 08:43:23.529496048 +0100
+++ gcc/cp/constexpr.c	2019-03-11 15:11:32.081334270 +0100
@@ -4236,7 +4236,8 @@ cxx_eval_loop_expr (const constexpr_ctx
       /* Forget saved values of SAVE_EXPRs.  */
       for (hash_set<tree>::iterator iter = save_exprs.begin();
 	   iter != save_exprs.end(); ++iter)
-	new_ctx.values->remove (*iter);
+	if (new_ctx.values->get (*iter))
+	  new_ctx.values->remove (*iter);
 
       if (++count >= constexpr_loop_limit)
 	{
@@ -4258,7 +4259,8 @@ cxx_eval_loop_expr (const constexpr_ctx
   /* Forget saved values of SAVE_EXPRs.  */
   for (hash_set<tree>::iterator iter = save_exprs.begin();
        iter != save_exprs.end(); ++iter)
-    new_ctx.values->remove (*iter);
+    if (new_ctx.values->get (*iter))
+      new_ctx.values->remove (*iter);
 
   return NULL_TREE;
 }
--- gcc/testsuite/g++.dg/cpp1y/constexpr-89652.C.jj	2019-03-11 15:14:21.877561575 +0100
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-89652.C	2019-03-11 15:16:11.962763933 +0100
@@ -0,0 +1,36 @@
+// PR c++/89652
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+template <typename T> constexpr auto foo (T &e) { return e.foo (); }
+template <typename T> constexpr auto bar (T &e) { return foo (e); }
+template <typename T, int N> struct A { typedef T a[N]; };
+template <typename T, unsigned long N> struct B {
+  typedef T *b;
+  typename A<T, N>::a d;
+  constexpr b foo () { return d; }
+};
+template <typename> struct C { long m; };
+struct D { long n; };
+template <typename, unsigned long> struct E {
+  B<C<int>, 1>::b p;
+  constexpr D operator* () { return {p->m}; }
+  constexpr E operator++ (int) { auto a{*this}; ++p; return a; }
+};
+template <typename T, unsigned long N>
+constexpr bool operator!= (E<T, N> a, E<T, N>) { return a.p; }
+template <unsigned long N, typename T, unsigned long M>
+constexpr auto baz (B<T, M> s, B<D, N>)
+{
+  B<D, M> t{};
+  auto q{foo (t)};
+  using u = E<T, M>;
+  auto v = u{bar (s)};
+  auto w = u{};
+  while (v != w)
+    *q++ = *v++;
+  return t;
+}
+constexpr auto a = B<C<int>, 5>{};
+auto b = B<D, 0>{};
+auto c = baz (a, b);