diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-04-20 09:56:52 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-04-20 09:56:52 +0200 |
commit | e00e62761dbd91200af4e448ff13b598d918049f (patch) | |
tree | b6a5a85592d6403d62b68e65139c16a6ef74fdf5 /gcc/cp | |
parent | 774c08306d605bff4ffa217121fc2da45ee240bd (diff) | |
download | gcc-e00e62761dbd91200af4e448ff13b598d918049f.zip gcc-e00e62761dbd91200af4e448ff13b598d918049f.tar.gz gcc-e00e62761dbd91200af4e448ff13b598d918049f.tar.bz2 |
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 15 | ||||
-rw-r--r-- | gcc/cp/pt.c | 25 |
3 files changed, 35 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e4c3deb..099407b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8c5c84e..5af4928 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1370e21..e2a12b9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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); |