diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-18 15:44:36 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-18 15:44:36 +0000 |
commit | 2806ee49f2b72c642ed1da9cbd1c53e4e0c08eb5 (patch) | |
tree | 7a30e58e91902a07435d0df3f33afcd8eeeddc4e /gcc | |
parent | 3983e6c754ffb5702c81e8758cd66111dab3c2a6 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/explicit7.C | 13 |
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 (); } |