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> 2018-04-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84611 PR c++/84611
......
...@@ -5927,14 +5927,19 @@ struct GTY((chain_next ("%h.next"))) tinst_level { ...@@ -5927,14 +5927,19 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
/* The location where the template is instantiated. */ /* The location where the template is instantiated. */
location_t locus; location_t locus;
/* errorcount+sorrycount when we pushed this level. */ /* errorcount + sorrycount when we pushed this level. */
unsigned short errors; unsigned short errors;
/* True if the location is in a system header. */ /* Count references to this object. If refcount reaches
bool in_system_header_p; 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. */ /* Infinity value for the above refcount. */
unsigned char 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); bool decl_spec_seq_has_spec_p (const cp_decl_specifier_seq *, cp_decl_spec);
......
...@@ -8945,15 +8945,14 @@ tinst_level::to_list () ...@@ -8945,15 +8945,14 @@ tinst_level::to_list ()
return ret; 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 * static tinst_level *
inc_refcount_use (tinst_level *obj) inc_refcount_use (tinst_level *obj)
{ {
if (obj) if (obj && obj->refcount != tinst_level::refcount_infinity)
{ ++obj->refcount;
++obj->refcount;
gcc_assert (obj->refcount != 0);
}
return obj; return obj;
} }
...@@ -8966,15 +8965,16 @@ tinst_level::free (tinst_level *obj) ...@@ -8966,15 +8965,16 @@ tinst_level::free (tinst_level *obj)
tinst_level_freelist ().free (obj); tinst_level_freelist ().free (obj);
} }
/* Decrement OBJ's refcount. If it reaches zero, release OBJ's DECL /* Decrement OBJ's refcount if not infinite. If it reaches zero, release
and OBJ, and start over with the tinst_level object that used to be OBJ's DECL and OBJ, and start over with the tinst_level object that
referenced by OBJ's NEXT. */ used to be referenced by OBJ's NEXT. */
static void static void
dec_refcount_use (tinst_level *obj) 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 *next = obj->next;
tinst_level::free (obj); tinst_level::free (obj);
obj = next; obj = next;
...@@ -10145,8 +10145,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc) ...@@ -10145,8 +10145,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
new_level->tldcl = tldcl; new_level->tldcl = tldcl;
new_level->targs = targs; new_level->targs = targs;
new_level->locus = loc; new_level->locus = loc;
new_level->errors = errorcount+sorrycount; new_level->errors = errorcount + sorrycount;
new_level->in_system_header_p = in_system_header_at (input_location);
new_level->next = NULL; new_level->next = NULL;
new_level->refcount = 0; new_level->refcount = 0;
set_refcount_ptr (new_level->next, current_tinst_level); 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> 2018-04-19 H.J. Lu <hongjiu.lu@intel.com>
* gcc.target/i386/pr85404.c: Require CET target. * 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