aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-07-19 00:22:43 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-07-19 00:22:43 +0000
commitf604fc3b2ea1d6738af942668d16ddd5cd2663a8 (patch)
tree4c3e45cb6e2a2a0cf8fae4bbd9efde2d779c5dae /gcc
parent437a9eba689bd253b51a8f4ac46b01b063835084 (diff)
downloadgcc-f604fc3b2ea1d6738af942668d16ddd5cd2663a8.zip
gcc-f604fc3b2ea1d6738af942668d16ddd5cd2663a8.tar.gz
gcc-f604fc3b2ea1d6738af942668d16ddd5cd2663a8.tar.bz2
re PR c++/28235 (ICE with static const member as default parameter in template)
PR c++/28235 * pt.c (tsubst_decl): Handling substitutions into a static data member from within the scope of the tempalte itself. PR c++/28235 * g++.dg/template/static27.C: New test. From-SVN: r115576
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c70
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/static27.C13
4 files changed, 71 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cf7a062..2f22450 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2006-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28235
+ * pt.c (tsubst_decl): Handling substitutions into a static data
+ member from within the scope of the tempalte itself.
+
2006-07-18 Lee Millward <lee.millward@gmail.com>
PR c++/28258
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 873ef51..7c09964 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6673,7 +6673,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
tree tmpl = NULL_TREE;
tree ctx;
tree type = NULL_TREE;
- int local_p;
+ bool local_p;
if (TREE_CODE (t) == TYPE_DECL)
{
@@ -6691,40 +6691,64 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
}
}
- /* Assume this is a non-local variable. */
- local_p = 0;
+ /* Check to see if we already have the specialization we
+ need. */
+ spec = NULL_TREE;
+ if (DECL_CLASS_SCOPE_P (t) || DECL_NAMESPACE_SCOPE_P (t))
+ {
+ /* T is a static data member or namespace-scope entity.
+ We have to substitute into namespace-scope variables
+ (even though such entities are never templates) because
+ of cases like:
+
+ template <class T> void f() { extern T t; }
+
+ where the entity referenced is not known until
+ instantiation time. */
+ local_p = false;
+ ctx = DECL_CONTEXT (t);
+ if (DECL_CLASS_SCOPE_P (t))
+ {
+ ctx = tsubst_aggr_type (ctx, args,
+ complain,
+ in_decl, /*entering_scope=*/1);
+ /* If CTX is unchanged, then T is in fact the
+ specialization we want. That situation occurs when
+ referencing a static data member within in its own
+ class. We can use pointer equality, rather than
+ same_type_p, because DECL_CONTEXT is always
+ canonical. */
+ if (ctx == DECL_CONTEXT (t))
+ spec = t;
+ }
- if (TYPE_P (CP_DECL_CONTEXT (t)))
- ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
- complain,
- in_decl, /*entering_scope=*/1);
- else if (DECL_NAMESPACE_SCOPE_P (t))
- ctx = DECL_CONTEXT (t);
+ if (!spec)
+ {
+ tmpl = DECL_TI_TEMPLATE (t);
+ gen_tmpl = most_general_template (tmpl);
+ argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
+ spec = (retrieve_specialization
+ (gen_tmpl, argvec,
+ /*class_specializations_p=*/false));
+ }
+ }
else
{
+ /* A local variable. */
+ local_p = true;
/* Subsequent calls to pushdecl will fill this in. */
ctx = NULL_TREE;
- local_p = 1;
+ spec = retrieve_local_specialization (t);
}
-
- /* Check to see if we already have this specialization. */
- if (!local_p)
- {
- tmpl = DECL_TI_TEMPLATE (t);
- gen_tmpl = most_general_template (tmpl);
- argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
- spec = retrieve_specialization (gen_tmpl, argvec,
- /*class_specializations_p=*/false);
- }
- else
- spec = retrieve_local_specialization (t);
-
+ /* If we already have the specialization we need, there is
+ nothing more to do. */
if (spec)
{
r = spec;
break;
}
+ /* Create a new node for the specialization we need. */
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 505a2ad..604b6cd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/28235
+ * g++.dg/template/static27.C: New test.
+
2006-07-18 Diego Novillo <dnovillo@redhat.com>
PR 28410
diff --git a/gcc/testsuite/g++.dg/template/static27.C b/gcc/testsuite/g++.dg/template/static27.C
new file mode 100644
index 0000000..0b63967
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/static27.C
@@ -0,0 +1,13 @@
+// PR c++/28235
+
+template<typename> struct A
+{
+ static const bool i = true;
+ template<bool = i> struct B {};
+ B<> b;
+};
+
+void f() {
+ A<int> a1, a2;
+ a1.b = a2.b;
+}