re PR c++/22263 (explicit instantiation fails to emit symbols defined later)

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.

From-SVN: r102133
This commit is contained in:
Mark Mitchell 2005-07-18 15:44:36 +00:00 committed by Mark Mitchell
parent 28356f52a9
commit eba839f971
6 changed files with 54 additions and 16 deletions

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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;
}

View File

@ -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.

View File

@ -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 (); }