From 2d1ac15a6abfe3cf5cd6ee92a3d8960bd9fb1af8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 4 May 2016 22:44:40 +0200 Subject: [PATCH] re PR c++/70906 (ice in add_expr, at tree.c:7925) PR c++/70906 PR c++/70933 * tree-core.h (enum operand_equal_flag): Add OEP_HASH_CHECK. * tree.c (inchash::add_expr): If !IS_EXPR_CODE_CLASS (tclass), assert flags & OEP_HASH_CHECK, instead of asserting it never happens. Handle TARGET_EXPR. * fold-const.c (operand_equal_p): For hash verification, or in OEP_HASH_CHECK into flags. * g++.dg/opt/pr70906.C: New test. * g++.dg/opt/pr70933.C: New test. From-SVN: r235902 --- gcc/ChangeLog | 11 +++++ gcc/fold-const.c | 4 +- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/opt/pr70906.C | 69 ++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/opt/pr70933.C | 29 +++++++++++++ gcc/tree-core.h | 4 +- gcc/tree.c | 12 +++++- 7 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr70906.C create mode 100644 gcc/testsuite/g++.dg/opt/pr70933.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 898de7ee914..d1745531864 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-05-04 Jakub Jelinek + + PR c++/70906 + PR c++/70933 + * tree-core.h (enum operand_equal_flag): Add OEP_HASH_CHECK. + * tree.c (inchash::add_expr): If !IS_EXPR_CODE_CLASS (tclass), + assert flags & OEP_HASH_CHECK, instead of asserting it + never happens. Handle TARGET_EXPR. + * fold-const.c (operand_equal_p): For hash verification, + or in OEP_HASH_CHECK into flags. + 2016-05-04 Eric Botcazou * tree-ssa-coalesce.c (gimple_can_coalesce_p): Fix reference in head diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 416ec5d7a84..9ef43bf2259 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2758,8 +2758,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) if (arg0 != arg1) { inchash::hash hstate0 (0), hstate1 (0); - inchash::add_expr (arg0, hstate0, flags); - inchash::add_expr (arg1, hstate1, flags); + inchash::add_expr (arg0, hstate0, flags | OEP_HASH_CHECK); + inchash::add_expr (arg1, hstate1, flags | OEP_HASH_CHECK); hashval_t h0 = hstate0.end (); hashval_t h1 = hstate1.end (); gcc_assert (h0 == h1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ee63d45bd9c..ea73617155f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-05-04 Jakub Jelinek + PR c++/70906 + PR c++/70933 + * g++.dg/opt/pr70906.C: New test. + * g++.dg/opt/pr70933.C: New test. + * gcc.target/i386/avx512vl-vmovq-1.c: New test. 2016-05-04 Jan Hubicka diff --git a/gcc/testsuite/g++.dg/opt/pr70906.C b/gcc/testsuite/g++.dg/opt/pr70906.C new file mode 100644 index 00000000000..19c91cd6aec --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr70906.C @@ -0,0 +1,69 @@ +// PR c++/70906 +// { dg-do compile { target c++11 } } +// { dg-options "-Wall" } + +template struct B; +template struct F { typedef U *t; }; +template struct D {}; +template struct L { + typedef VP np; + typedef typename F>::t cnp; +}; +struct P { typedef L nt; }; +template struct I { typedef typename N::template A t; }; +template struct Q { typedef typename I::t t; }; +template struct G; +template +struct mh { + template struct A { typedef G pvt; }; +}; +template struct B { static T pt(T); }; +struct R : public D { typedef P ht; }; +class lmh : public R {}; +template struct G { + typedef Hook Ht; + typedef typename Ht::ht::nt nt; + typedef T vt; + typedef typename nt::np np; + typedef typename nt::cnp cnp; + static np tnp(T &); + static cnp tnp(const T &p1) { + B::pt(static_cast(p1.*P)); + return cnp (); + } +}; +template struct K { + template struct J; + template static int foo(J *, int); + static const int c = sizeof(foo(0, 0)); +}; +template struct W1 { + typedef typename V::vt vt; + static const bool value = K::c == K::c; +}; +template struct O { + static const bool svt = W1::value; +}; +template struct M {}; +template class C { + static const bool svt = O::svt; + M m; +}; +template struct H { + C bar(); +}; +template struct ml { + typedef typename Q::t po; + typedef H t; +}; +template class list : public ml::t {}; +struct N { + struct IV { lmh hk; }; + typedef list> ISL; + friend void fn1(int &, N const &); +}; +void fn1(int &, N const &) { + N::ISL xl; + for (xl.bar();;) + ; +} diff --git a/gcc/testsuite/g++.dg/opt/pr70933.C b/gcc/testsuite/g++.dg/opt/pr70933.C new file mode 100644 index 00000000000..f664d45777c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr70933.C @@ -0,0 +1,29 @@ +// PR c++/70933 +// { dg-do compile } +// { dg-options "-Wsequence-point" } + +struct A +{ + A (const char *); +}; + +template +struct B +{ + typedef T U; + U &baz (const A &); +}; + +template +void +bar () +{ + B b; + T &p = b.baz ("p1") = T(4); +} + +void +foo () +{ + bar (); +} diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 6d573d7b6d2..ea832fa5344 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -767,7 +767,9 @@ enum operand_equal_flag { OEP_MATCH_SIDE_EFFECTS = 4, OEP_ADDRESS_OF = 8, /* Internal within operand_equal_p: */ - OEP_NO_HASH_CHECK = 16 + OEP_NO_HASH_CHECK = 16, + /* Internal within inchash::add_expr: */ + OEP_HASH_CHECK = 32 }; /* Enum and arrays used for tree allocation stats. diff --git a/gcc/tree.c b/gcc/tree.c index ebec112d4b1..c5653372f18 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7915,9 +7915,12 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags) && integer_zerop (TREE_OPERAND (t, 1))) inchash::add_expr (TREE_OPERAND (TREE_OPERAND (t, 0), 0), hstate, flags); + /* Don't ICE on FE specific trees, or their arguments etc. + during operand_equal_p hash verification. */ + else if (!IS_EXPR_CODE_CLASS (tclass)) + gcc_assert (flags & OEP_HASH_CHECK); else { - gcc_assert (IS_EXPR_CODE_CLASS (tclass)); unsigned int sflags = flags; hstate.add_object (code); @@ -7966,6 +7969,13 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags) hstate.add_int (CALL_EXPR_IFN (t)); break; + case TARGET_EXPR: + /* For TARGET_EXPR, just hash on the TARGET_EXPR_SLOT. + Usually different TARGET_EXPRs just should use + different temporaries in their slots. */ + inchash::add_expr (TARGET_EXPR_SLOT (t), hstate, flags); + return; + default: break; } -- 2.30.2