summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-18 15:44:36 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-18 15:44:36 +0000
commit2806ee49f2b72c642ed1da9cbd1c53e4e0c08eb5 (patch)
tree7a30e58e91902a07435d0df3f33afcd8eeeddc4e /gcc
parent3983e6c754ffb5702c81e8758cd66111dab3c2a6 (diff)
downloadgcc-2806ee49f2b72c642ed1da9cbd1c53e4e0c08eb5.tar.gz
PR c++/22263
* cp-tree.h (instantiate_decl): Change prototype. * decl2.c (mark_used): Adjust accordingly. * pt.c (do_decl_instantiation): Likewise. (instantiate_class_member): Likewise. (instantiate_decl): Rename undefined_ok as expl_inst_class_mem_p. Clear DECL_INTERFACE_KNOWN for an explicitly instantiated template that has no definition available. (instantiate_pending_templates): Adjust call to instantiate_decl. PR c++/22263 * g++.dg/template/explicit7.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102133 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/pt.c35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/explicit7.C13
6 files changed, 54 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4c048cf4bd8..b30aabc1f9a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2005-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22263
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust accordingly.
+ * pt.c (do_decl_instantiation): Likewise.
+ (instantiate_class_member): Likewise.
+ (instantiate_decl): Rename undefined_ok as expl_inst_class_mem_p.
+ Clear DECL_INTERFACE_KNOWN for an explicitly instantiated template
+ that has no definition available.
+ (instantiate_pending_templates): Adjust call to instantiate_decl.
+
2005-07-17 Mark Mitchell <mark@codesourcery.com>
PR c++/22139
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2d5e5f1f41d..d9d053d6dfb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3997,7 +3997,7 @@ extern int more_specialized_fn (tree, tree, int);
extern void mark_class_instantiated (tree, int);
extern void do_decl_instantiation (tree, tree);
extern void do_type_instantiation (tree, tree, tsubst_flags_t);
-extern tree instantiate_decl (tree, int, int);
+extern tree instantiate_decl (tree, int, bool);
extern int push_tinst_level (tree);
extern void pop_tinst_level (void);
extern int more_specialized_class (tree, tree, tree);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 22166e8b398..5afcd896cc1 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3278,7 +3278,8 @@ mark_used (tree decl)
times. Maintaining a stack of active functions is expensive,
and the inliner knows to instantiate any functions it might
need. */
- instantiate_decl (decl, /*defer_ok=*/true, /*undefined_ok=*/0);
+ instantiate_decl (decl, /*defer_ok=*/true,
+ /*expl_inst_class_mem_p=*/false);
}
#include "gt-cp-decl2.h"
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bbf3bf9bb34..619cdc11752 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11010,7 +11010,8 @@ do_decl_instantiation (tree decl, tree storage)
mark_decl_instantiated (result, extern_p);
if (! extern_p)
- instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
+ instantiate_decl (result, /*defer_ok=*/1,
+ /*expl_inst_class_mem_p=*/false);
}
void
@@ -11047,7 +11048,8 @@ instantiate_class_member (tree decl, int extern_p)
{
mark_decl_instantiated (decl, extern_p);
if (! extern_p)
- instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1);
+ instantiate_decl (decl, /*defer_ok=*/1,
+ /*expl_inst_class_mem_p=*/true);
}
/* Perform an explicit instantiation of template class T. STORAGE, if
@@ -11343,14 +11345,12 @@ template_for_substitution (tree decl)
DEFER_OK is nonzero, then we don't have to actually do the
instantiation now; we just have to do it sometime. Normally it is
an error if this is an explicit instantiation but D is undefined.
- If UNDEFINED_OK is nonzero, then instead we treat it as an implicit
- instantiation. UNDEFINED_OK is nonzero only if we are being used
- to instantiate the members of an explicitly instantiated class
- template. */
-
+ EXPL_INST_CLASS_MEM_P is true iff D is a member of an
+ explicitly instantiated class template. */
tree
-instantiate_decl (tree d, int defer_ok, int undefined_ok)
+instantiate_decl (tree d, int defer_ok,
+ bool expl_inst_class_mem_p)
{
tree tmpl = DECL_TI_TEMPLATE (d);
tree gen_args;
@@ -11439,9 +11439,14 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
input_location = DECL_SOURCE_LOCATION (d);
- if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
+ /* If D is a member of an explicitly instantiated class template,
+ and no definition is available, treat it like an implicit
+ instantiation. */
+ if (!pattern_defined && expl_inst_class_mem_p
+ && DECL_EXPLICIT_INSTANTIATION (d))
{
DECL_NOT_REALLY_EXTERN (d) = 0;
+ DECL_INTERFACE_KNOWN (d) = 0;
SET_DECL_IMPLICIT_INSTANTIATION (d);
}
@@ -11678,8 +11683,9 @@ instantiate_pending_templates (int retries)
fn;
fn = TREE_CHAIN (fn))
if (! DECL_ARTIFICIAL (fn))
- instantiate_decl (fn, /*defer_ok=*/0,
- /*undefined_ok=*/0);
+ instantiate_decl (fn,
+ /*defer_ok=*/0,
+ /*expl_inst_class_mem_p=*/false);
if (COMPLETE_TYPE_P (instantiation))
reconsider = 1;
}
@@ -11699,9 +11705,10 @@ instantiate_pending_templates (int retries)
if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
{
- instantiation = instantiate_decl (instantiation,
- /*defer_ok=*/0,
- /*undefined_ok=*/0);
+ instantiation
+ = instantiate_decl (instantiation,
+ /*defer_ok=*/0,
+ /*expl_inst_class_mem_p=*/false);
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
reconsider = 1;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 80b9604ecbf..88228523684 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22263
+ * g++.dg/template/explicit7.C: New test.
+
2005-07-17 Jerry DeLisle <jvdelisle@verizon.net>
* gfortran.fortran-torture/execute/nan_inf_fmt.f90: Change case of field
width of 8 to +Inf and -Inf.
diff --git a/gcc/testsuite/g++.dg/template/explicit7.C b/gcc/testsuite/g++.dg/template/explicit7.C
new file mode 100644
index 00000000000..7424677181a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/explicit7.C
@@ -0,0 +1,13 @@
+// PR c++/22263
+// { dg-do link }
+
+template <class T> struct S { T foo (); T bar (); };
+template <class T> T S<T>::foo () { return bar (); }
+template struct S<int>;
+template <class T> T S<T>::bar () { return T (); }
+
+#if !__GXX_WEAK__
+template int S<int>::bar ();
+#endif
+
+int main () { return S<int>().foo (); }