70 lines
2.3 KiB
Diff
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);
|