Commit f7e4e484 by Mark Mitchell

re PR c++/23699 (rejects static int as non constant after "extern template")

	PR c++/23699
	* decl2.c (mark_used): Always instantiate static data members
	initialized by constant expressions.
	* pt.c (instantiate_decl): Instantiate the initializers for static
	data members initialized by constant expressions.

From-SVN: r103807
parent 27250734
...@@ -11371,6 +11371,7 @@ instantiate_decl (tree d, int defer_ok, ...@@ -11371,6 +11371,7 @@ instantiate_decl (tree d, int defer_ok,
bool pattern_defined; bool pattern_defined;
int need_push; int need_push;
location_t saved_loc = input_location; location_t saved_loc = input_location;
bool external_p;
/* This function should only be used to instantiate templates for /* This function should only be used to instantiate templates for
functions and static member variables. */ functions and static member variables. */
...@@ -11488,17 +11489,32 @@ instantiate_decl (tree d, int defer_ok, ...@@ -11488,17 +11489,32 @@ instantiate_decl (tree d, int defer_ok,
pop_access_scope (d); pop_access_scope (d);
} }
/* Do not instantiate templates that we know will be defined /* Check to see whether we know that this template will be
elsewhere. */ instantiated in some other file, as with "extern template"
if (DECL_INTERFACE_KNOWN (d) extension. */
&& DECL_REALLY_EXTERN (d) external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
&& ! (TREE_CODE (d) == FUNCTION_DECL /* In general, we do not instantiate such templates... */
&& DECL_INLINE (d))) if (external_p
/* ... but we instantiate inline functions so that we can inline
them and ... */
&& ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
/* ... we instantiate static data members whose values are
needed in integral constant expressions. */
&& ! (TREE_CODE (d) == VAR_DECL
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
goto out; goto out;
/* Defer all other templates, unless we have been explicitly /* Defer all other templates, unless we have been explicitly
forbidden from doing so. We restore the source position here forbidden from doing so. */
because it's used by add_pending_template. */ if (/* If there is no definition, we cannot instantiate the
else if (! pattern_defined || defer_ok) template. */
! pattern_defined
/* If it's OK to postpone instantiation, do so. */
|| defer_ok
/* If this is a static data member that will be defined
elsewhere, we don't want to instantiate the entire data
member, but we do want to instantiate the initializer so that
we can substitute that elsewhere. */
|| (external_p && TREE_CODE (d) == VAR_DECL))
{ {
/* The definition of the static data member is now required so /* The definition of the static data member is now required so
we must substitute the initializer. */ we must substitute the initializer. */
...@@ -11514,6 +11530,8 @@ instantiate_decl (tree d, int defer_ok, ...@@ -11514,6 +11530,8 @@ instantiate_decl (tree d, int defer_ok,
pop_nested_class (); pop_nested_class ();
} }
/* We restore the source position here because it's used by
add_pending_template. */
input_location = saved_loc; input_location = saved_loc;
if (at_eof && !pattern_defined if (at_eof && !pattern_defined
...@@ -11528,7 +11546,10 @@ instantiate_decl (tree d, int defer_ok, ...@@ -11528,7 +11546,10 @@ instantiate_decl (tree d, int defer_ok,
pedwarn pedwarn
("explicit instantiation of %qD but no definition available", d); ("explicit instantiation of %qD but no definition available", d);
add_pending_template (d); /* ??? Historically, we have instantiated inline functions, even
when marked as "extern template". */
if (!(external_p && TREE_CODE (d) == VAR_DECL))
add_pending_template (d);
goto out; goto out;
} }
/* Tell the repository that D is available in this translation unit /* Tell the repository that D is available in this translation unit
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment