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
This commit is contained in:
parent
e4ea422a00
commit
2d1ac15a6a
|
@ -1,3 +1,14 @@
|
|||
2016-05-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <ebotcazou@adacore.com>
|
||||
|
||||
* tree-ssa-coalesce.c (gimple_can_coalesce_p): Fix reference in head
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
2016-05-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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 <hubicka@ucw.cz>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
// PR c++/70906
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-Wall" }
|
||||
|
||||
template <typename> struct B;
|
||||
template <typename U> struct F { typedef U *t; };
|
||||
template <class> struct D {};
|
||||
template <class VP> struct L {
|
||||
typedef VP np;
|
||||
typedef typename F<D<VP>>::t cnp;
|
||||
};
|
||||
struct P { typedef L<void *> nt; };
|
||||
template <class N> struct I { typedef typename N::template A<int> t; };
|
||||
template <class O1> struct Q { typedef typename I<O1>::t t; };
|
||||
template <class T, class Hook, Hook T::*> struct G;
|
||||
template <typename P, typename M, M P::*PM>
|
||||
struct mh {
|
||||
template <class> struct A { typedef G<P, M, PM> pvt; };
|
||||
};
|
||||
template <typename T> struct B<T *> { static T pt(T); };
|
||||
struct R : public D<void *> { typedef P ht; };
|
||||
class lmh : public R {};
|
||||
template <class T, class Hook, Hook T::*P> 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<cnp>::pt(static_cast<const Ht &>(p1.*P));
|
||||
return cnp ();
|
||||
}
|
||||
};
|
||||
template <class T, class S> struct K {
|
||||
template <S> struct J;
|
||||
template <class U> static int foo(J<U::tnp> *, int);
|
||||
static const int c = sizeof(foo<T>(0, 0));
|
||||
};
|
||||
template <class V> struct W1 {
|
||||
typedef typename V::vt vt;
|
||||
static const bool value = K<V, typename V::np (*)(vt &)>::c == K<V, typename V::cnp (*)(const vt &)>::c;
|
||||
};
|
||||
template <class V> struct O {
|
||||
static const bool svt = W1<V>::value;
|
||||
};
|
||||
template <bool> struct M {};
|
||||
template <class V> class C {
|
||||
static const bool svt = O<V>::svt;
|
||||
M<svt> m;
|
||||
};
|
||||
template <class V> struct H {
|
||||
C<V> bar();
|
||||
};
|
||||
template <class O1> struct ml {
|
||||
typedef typename Q<O1>::t po;
|
||||
typedef H<typename po::pvt> t;
|
||||
};
|
||||
template <class O1> class list : public ml<O1>::t {};
|
||||
struct N {
|
||||
struct IV { lmh hk; };
|
||||
typedef list<mh<IV, lmh, &IV::hk>> ISL;
|
||||
friend void fn1(int &, N const &);
|
||||
};
|
||||
void fn1(int &, N const &) {
|
||||
N::ISL xl;
|
||||
for (xl.bar();;)
|
||||
;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// PR c++/70933
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wsequence-point" }
|
||||
|
||||
struct A
|
||||
{
|
||||
A (const char *);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct B
|
||||
{
|
||||
typedef T U;
|
||||
U &baz (const A &);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
B<T> b;
|
||||
T &p = b.baz ("p1") = T(4);
|
||||
}
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
bar<unsigned> ();
|
||||
}
|
|
@ -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.
|
||||
|
|
12
gcc/tree.c
12
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue