Commit e00e6276 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/85462 (internal compiler error: in inc_refcount_use, at cp/pt.c:8955)

	PR c++/85462
	* cp-tree.h (tinst_level): Remove in_system_header_p member,
	change refcount member from unsigned char to unsigned short,
	add refcount_infinity static data member, adjust comments.
	* pt.c (tinst_level::refcount_infinity): Define.
	(inc_refcount_use): Remove assert, don't increment if refcount
	is already refcount_infinity, adjust comment.
	(dec_refcount_use): Remove assert, don't decrement if refcount
	is refcount_infinity, adjust comment.
	(push_tinst_level_loc): Formatting fix.

	* g++.dg/cpp0x/pr85462.C: New test.

From-SVN: r259516
parent 774c0830
2018-04-20 Jakub Jelinek <jakub@redhat.com>
PR c++/85462
* cp-tree.h (tinst_level): Remove in_system_header_p member,
change refcount member from unsigned char to unsigned short,
add refcount_infinity static data member, adjust comments.
* pt.c (tinst_level::refcount_infinity): Define.
(inc_refcount_use): Remove assert, don't increment if refcount
is already refcount_infinity, adjust comment.
(dec_refcount_use): Remove assert, don't decrement if refcount
is refcount_infinity, adjust comment.
(push_tinst_level_loc): Formatting fix.
2018-04-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84611
......
......@@ -5927,14 +5927,19 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
/* The location where the template is instantiated. */
location_t locus;
/* errorcount+sorrycount when we pushed this level. */
/* errorcount + sorrycount when we pushed this level. */
unsigned short errors;
/* True if the location is in a system header. */
bool in_system_header_p;
/* Count references to this object. If refcount reaches
refcount_infinity value, we don't increment or decrement the
refcount anymore, as the refcount isn't accurate anymore.
The object can be still garbage collected if unreferenced from
anywhere, which might keep referenced objects referenced longer than
otherwise necessary. Hitting the infinity is rare though. */
unsigned short refcount;
/* Count references to this object. */
unsigned char refcount;
/* Infinity value for the above refcount. */
static const unsigned short refcount_infinity = (unsigned short) ~0;
};
bool decl_spec_seq_has_spec_p (const cp_decl_specifier_seq *, cp_decl_spec);
......
......@@ -8945,15 +8945,14 @@ tinst_level::to_list ()
return ret;
}
/* Increment OBJ's refcount. */
const unsigned short tinst_level::refcount_infinity;
/* Increment OBJ's refcount unless it is already infinite. */
static tinst_level *
inc_refcount_use (tinst_level *obj)
{
if (obj)
{
++obj->refcount;
gcc_assert (obj->refcount != 0);
}
if (obj && obj->refcount != tinst_level::refcount_infinity)
++obj->refcount;
return obj;
}
......@@ -8966,15 +8965,16 @@ tinst_level::free (tinst_level *obj)
tinst_level_freelist ().free (obj);
}
/* Decrement OBJ's refcount. If it reaches zero, release OBJ's DECL
and OBJ, and start over with the tinst_level object that used to be
referenced by OBJ's NEXT. */
/* Decrement OBJ's refcount if not infinite. If it reaches zero, release
OBJ's DECL and OBJ, and start over with the tinst_level object that
used to be referenced by OBJ's NEXT. */
static void
dec_refcount_use (tinst_level *obj)
{
while (obj && !--obj->refcount)
while (obj
&& obj->refcount != tinst_level::refcount_infinity
&& !--obj->refcount)
{
gcc_assert (obj->refcount+1 != 0);
tinst_level *next = obj->next;
tinst_level::free (obj);
obj = next;
......@@ -10145,8 +10145,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
new_level->tldcl = tldcl;
new_level->targs = targs;
new_level->locus = loc;
new_level->errors = errorcount+sorrycount;
new_level->in_system_header_p = in_system_header_at (input_location);
new_level->errors = errorcount + sorrycount;
new_level->next = NULL;
new_level->refcount = 0;
set_refcount_ptr (new_level->next, current_tinst_level);
......
2018-04-20 Jakub Jelinek <jakub@redhat.com>
PR c++/85462
* g++.dg/cpp0x/pr85462.C: New test.
2018-04-19 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/pr85404.c: Require CET target.
......
// PR c++/85462
// { dg-do compile { target c++11 } }
template <class T> struct D { using d = T *; };
template <class, class, class> struct E;
template <class T, class U> struct E<T, U, U> { using d = typename D<T>::d; };
template <class T> struct G { using d = typename E<T, int, int>::d; };
template <class T, class U> typename G<T>::d foo (U);
#define A(n) class A##n {};
#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9)
#define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9)
#define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4)
D(1)
class H;
template <typename>
struct I
{
bool bar ();
#undef A
#define A(n) void f##n (A##n *);
D(1)
void baz ();
};
A1000 v;
template <typename T>
bool I<T>::bar ()
{
#undef A
#define A(n) A##n k##n = *foo<A##n> (v); f##n (&k##n);
D(1)
foo<H> (v);
baz ();
return false;
}
struct J : I<int>
{
void qux () { bar (); }
};
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