mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 00:01:21 +08:00
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:
parent
28356f52a9
commit
eba839f971
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
35
gcc/cp/pt.c
35
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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
13
gcc/testsuite/g++.dg/template/explicit7.C
Normal file
13
gcc/testsuite/g++.dg/template/explicit7.C
Normal 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 (); }
|
Loading…
x
Reference in New Issue
Block a user