aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2018-04-20 09:56:52 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2018-04-20 09:56:52 +0200
commite00e62761dbd91200af4e448ff13b598d918049f (patch)
treeb6a5a85592d6403d62b68e65139c16a6ef74fdf5 /gcc/cp
parent774c08306d605bff4ffa217121fc2da45ee240bd (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/pt.c25
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);