mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
158beb4ab3
commit
6f5bcd2400
|
|
@ -1,3 +1,15 @@
|
||||||
|
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)
|
||||||
|
|
||||||
*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)
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
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>
|
2016-06-06 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/71259
|
PR tree-optimization/71259
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue