Commit 6f5bcd24 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/70847 (exponential time in cp_fold for chained virtual function calls)

	PR c++/70847
	PR c++/71330
	PR c++/71393
	* cp-gimplify.c (cp_fold_r): Set *walk_subtrees = 0 and return NULL
	right after cp_fold call if cp_fold has returned the same stmt
	already in some earlier cp_fold_r call.
	(cp_fold_function): Add pset automatic variable, pass its address
	to cp_walk_tree.

	* g++.dg/opt/pr70847.C: New test.
	* g++.dg/ubsan/pr70847.C: New test.
	* g++.dg/ubsan/pr71393.C: New test.

Co-Authored-By: Patrick Palka <ppalka@gcc.gnu.org>

From-SVN: r237151
parent 158beb4a
2016-06-06 Jakub Jelinek <jakub@redhat.com>
Patrick Palka <ppalka@gcc.gnu.org>
PR c++/70847
PR c++/71330
PR c++/71393
* cp-gimplify.c (cp_fold_r): Set *walk_subtrees = 0 and return NULL
right after cp_fold call if cp_fold has returned the same stmt
already in some earlier cp_fold_r call.
(cp_fold_function): Add pset automatic variable, pass its address
to cp_walk_tree.
2016-06-04 Paolo Carlini <paolo.carlini@oracle.com> 2016-06-04 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/70202 PR c++/70202
......
...@@ -940,6 +940,17 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) ...@@ -940,6 +940,17 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
*stmt_p = stmt = cp_fold (*stmt_p); *stmt_p = stmt = cp_fold (*stmt_p);
if (((hash_set<tree> *) data)->add (stmt))
{
/* Don't walk subtrees of stmts we've already walked once, otherwise
we can have exponential complexity with e.g. lots of nested
SAVE_EXPRs or TARGET_EXPRs. cp_fold uses a cache and will return
always the same tree, which the first time cp_fold_r has been
called on it had the subtrees walked. */
*walk_subtrees = 0;
return NULL;
}
code = TREE_CODE (stmt); code = TREE_CODE (stmt);
if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
|| code == OMP_TASKLOOP || code == CILK_FOR || code == CILK_SIMD || code == OMP_TASKLOOP || code == CILK_FOR || code == CILK_SIMD
...@@ -997,7 +1008,8 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data) ...@@ -997,7 +1008,8 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
void void
cp_fold_function (tree fndecl) cp_fold_function (tree fndecl)
{ {
cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, NULL, NULL); hash_set<tree> pset;
cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &pset, NULL);
} }
/* Perform any pre-gimplification lowering of C++ front end trees to /* Perform any pre-gimplification lowering of C++ front end trees to
......
2016-06-06 Jakub Jelinek <jakub@redhat.com> 2016-06-06 Jakub Jelinek <jakub@redhat.com>
Patrick Palka <ppalka@gcc.gnu.org>
PR c++/70847
PR c++/71330
PR c++/71393
* g++.dg/opt/pr70847.C: New test.
* g++.dg/ubsan/pr70847.C: New test.
* g++.dg/ubsan/pr71393.C: New test.
2016-06-06 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/71259 PR tree-optimization/71259
* gcc.dg/vect/pr71259.c: New test. * gcc.dg/vect/pr71259.c: New test.
......
// PR c++/70847
// { dg-do compile }
struct D { virtual D& f(); };
void
g()
{
D d;
d.f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f();
}
// PR c++/70847
// { dg-do compile }
struct D { virtual D& f(); };
void
g()
{
D d;
d.f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f().f();
}
// PR c++/71393
// { dg-do compile }
// { dg-options "-fsanitize=undefined" }
struct B { B &operator << (long); };
struct A { A (); long a, b, c, d, e, f; };
A::A ()
{
B q;
q << 0 << a << 0 << b << 0 << (b / a) << 0 << c << 0 << (c / a) << 0
<< d << 0 << (d / a) << 0 << e << 0 << (e / a) << 0 << f << 0
<< (f / a) << 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment