aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-11-08 01:42:23 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-11-08 01:42:23 +0000
commit4f2c9d7ec6409e570be8df243c57e4e3298b26e6 (patch)
treefa22e6801338e929ebb4695d50bd7f7c25b302c2
parent07cf4226a74edbf9f7872f0c001fc82791c80ba0 (diff)
downloadgcc-4f2c9d7ec6409e570be8df243c57e4e3298b26e6.zip
gcc-4f2c9d7ec6409e570be8df243c57e4e3298b26e6.tar.gz
gcc-4f2c9d7ec6409e570be8df243c57e4e3298b26e6.tar.bz2
re PR c++/8338 (Infinite loop on illegal code)
PR c++/8338 * pt.c (for_each_template_parm): Add htab parameter. (process_partial_specialization): Adjust call. (push_template_decl_real): Likewise. (pair_fn_data): Add visited. (for_each_template_parm_r): Avoid walking duplicates more than once. (uses_template_parms): Adjust call to for_each_template_parm. PR c++/8338 * g++.dg/template/crash2.C: New test. From-SVN: r58911
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/pt.c70
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/crash2.C31
4 files changed, 97 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3f37368..08f6b25 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,16 @@
2002-11-07 Mark Mitchell <mark@codesourcery.com>
+ PR c++/8338
+ * pt.c (for_each_template_parm): Add htab parameter.
+ (process_partial_specialization): Adjust call.
+ (push_template_decl_real): Likewise.
+ (pair_fn_data): Add visited.
+ (for_each_template_parm_r): Avoid walking duplicates more than
+ once.
+ (uses_template_parms): Adjust call to for_each_template_parm.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
* class.c (add_implicitly_declared_members): Put implicitly
declared functions at the end of TYPE_METHODs when -fabi-version
is at least 2.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 09e225a..62eef7a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -115,7 +115,7 @@ static tree convert_nontype_argument PARAMS ((tree, tree));
static tree convert_template_argument PARAMS ((tree, tree, tree,
tsubst_flags_t, int, tree));
static tree get_bindings_overload PARAMS ((tree, tree, tree));
-static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
+static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*, htab_t));
static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
static int inline_needs_template_parms PARAMS ((tree));
static void push_inline_template_parms_recursive PARAMS ((tree, int));
@@ -2237,7 +2237,8 @@ process_partial_specialization (decl)
tpd.current_arg = i;
for_each_template_parm (TREE_VEC_ELT (inner_args, i),
&mark_template_parm,
- &tpd);
+ &tpd,
+ NULL);
}
for (i = 0; i < ntparms; ++i)
if (tpd.parms[i] == 0)
@@ -2318,7 +2319,8 @@ process_partial_specialization (decl)
memset ((PTR) tpd2.parms, 0, sizeof (int) * nargs);
for_each_template_parm (type,
&mark_template_parm,
- &tpd2);
+ &tpd2,
+ NULL);
if (tpd2.arg_uses_template_parms [i])
{
@@ -2751,7 +2753,8 @@ push_template_decl_real (decl, is_friend)
if (for_each_template_parm (TREE_TYPE (TREE_TYPE (tmpl)),
template_parm_this_level_p,
- &depth))
+ &depth,
+ NULL))
DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
}
}
@@ -4337,6 +4340,7 @@ struct pair_fn_data
{
tree_fn_t fn;
void *data;
+ htab_t visited;
};
/* Called from for_each_template_parm via walk_tree. */
@@ -4351,9 +4355,20 @@ for_each_template_parm_r (tp, walk_subtrees, d)
struct pair_fn_data *pfd = (struct pair_fn_data *) d;
tree_fn_t fn = pfd->fn;
void *data = pfd->data;
-
+ void **slot;
+
+ /* If we have already visited this tree, there's no need to walk
+ subtrees. Otherwise, add it to the visited table. */
+ slot = htab_find_slot (pfd->visited, *tp, INSERT);
+ if (*slot)
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ *slot = *tp;
+
if (TYPE_P (t)
- && for_each_template_parm (TYPE_CONTEXT (t), fn, data))
+ && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
return error_mark_node;
switch (TREE_CODE (t))
@@ -4368,20 +4383,21 @@ for_each_template_parm_r (tp, walk_subtrees, d)
if (!TYPE_TEMPLATE_INFO (t))
*walk_subtrees = 0;
else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
- fn, data))
+ fn, data, pfd->visited))
return error_mark_node;
break;
case METHOD_TYPE:
/* Since we're not going to walk subtrees, we have to do this
explicitly here. */
- if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
+ if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
+ pfd->visited))
return error_mark_node;
/* Fall through. */
case FUNCTION_TYPE:
/* Check the return type. */
- if (for_each_template_parm (TREE_TYPE (t), fn, data))
+ if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
return error_mark_node;
/* Check the parameter types. Since default arguments are not
@@ -4394,7 +4410,8 @@ for_each_template_parm_r (tp, walk_subtrees, d)
tree parm;
for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
- if (for_each_template_parm (TREE_VALUE (parm), fn, data))
+ if (for_each_template_parm (TREE_VALUE (parm), fn, data,
+ pfd->visited))
return error_mark_node;
/* Since we've already handled the TYPE_ARG_TYPES, we don't
@@ -4406,20 +4423,22 @@ for_each_template_parm_r (tp, walk_subtrees, d)
case FUNCTION_DECL:
case VAR_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
- && for_each_template_parm (DECL_TI_ARGS (t), fn, data))
+ && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
+ pfd->visited))
return error_mark_node;
/* Fall through. */
case CONST_DECL:
case PARM_DECL:
if (DECL_CONTEXT (t)
- && for_each_template_parm (DECL_CONTEXT (t), fn, data))
+ && for_each_template_parm (DECL_CONTEXT (t), fn, data,
+ pfd->visited))
return error_mark_node;
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
- if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
+ if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited))
return error_mark_node;
/* Fall through. */
@@ -4435,7 +4454,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
case TEMPLATE_DECL:
/* A template template parameter is encountered */
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
- && for_each_template_parm (TREE_TYPE (t), fn, data))
+ && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
return error_mark_node;
/* Already substituted template template parameter */
@@ -4443,14 +4462,17 @@ for_each_template_parm_r (tp, walk_subtrees, d)
break;
case TYPENAME_TYPE:
- if (!fn || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn, data))
+ if (!fn
+ || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
+ data, pfd->visited))
return error_mark_node;
break;
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
&& for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
- (TREE_TYPE (t)), fn, data))
+ (TREE_TYPE (t)), fn, data,
+ pfd->visited))
return error_mark_node;
break;
@@ -4482,7 +4504,8 @@ for_each_template_parm_r (tp, walk_subtrees, d)
the BINFO hierarchy, which is circular, and therefore
confuses walk_tree. */
*walk_subtrees = 0;
- if (for_each_template_parm (BASELINK_FUNCTIONS (*tp), fn, data))
+ if (for_each_template_parm (BASELINK_FUNCTIONS (*tp), fn, data,
+ pfd->visited))
return error_mark_node;
break;
@@ -4504,10 +4527,11 @@ for_each_template_parm_r (tp, walk_subtrees, d)
considered to be the function which always returns 1. */
static int
-for_each_template_parm (t, fn, data)
+for_each_template_parm (t, fn, data, visited)
tree t;
tree_fn_t fn;
void* data;
+ htab_t visited;
{
struct pair_fn_data pfd;
@@ -4518,7 +4542,13 @@ for_each_template_parm (t, fn, data)
/* Walk the tree. (Conceptually, we would like to walk without
duplicates, but for_each_template_parm_r recursively calls
for_each_template_parm, so we would need to reorganize a fair
- bit to use walk_tree_without_duplicates.) */
+ bit to use walk_tree_without_duplicates, so we keep our own
+ visited list.) */
+ if (visited)
+ pfd.visited = visited;
+ else
+ pfd.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer,
+ NULL);
return walk_tree (&t,
for_each_template_parm_r,
&pfd,
@@ -4529,7 +4559,7 @@ int
uses_template_parms (t)
tree t;
{
- return for_each_template_parm (t, 0, 0);
+ return for_each_template_parm (t, 0, 0, NULL);
}
static int tinst_depth;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7ad265e..c817452 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2002-11-07 Mark Mitchell <mark@codesourcery.com>
+ PR c++/8338
+ * g++.dg/template/crash2.C: New test.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
* testsuite/g++.dg/abi/dtor1.C: New test.
* testsuite/g++.dg/abi/dtor2.C: Likewise.
diff --git a/gcc/testsuite/g++.dg/template/crash2.C b/gcc/testsuite/g++.dg/template/crash2.C
new file mode 100644
index 0000000..e6cc965
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash2.C
@@ -0,0 +1,31 @@
+// { dg-options "" }
+
+template <class EnumType>
+class A
+{
+public:
+ static const EnumType size = max; // { dg-error "" }
+ int table[size];
+};
+template <class EnumType>
+const EnumType A<EnumType>::size;
+
+
+namespace N
+{
+enum E { max = 5 };
+
+struct B
+{
+ A<E> a; // { dg-error "" }
+};
+
+}
+
+int
+main()
+{
+ N::B b;
+
+ return 0;
+}