gcc/gcc9-pr89652.patch

70 lines
2.3 KiB
Diff

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);