Commit 991eeb49 by Jason Merrill Committed by Jason Merrill

pt.c (check_explicit_specialization): Don't complain about non-template variable.

	* pt.c (check_explicit_specialization): Don't complain about
	non-template variable.
	(template_for_substitution): Allow variable templates.
	(check_template_variable): Fix logic for member var template.
	* decl.c (start_decl): Don't complain about extra template header
	here.

From-SVN: r214487
parent f348033d
2014-08-25 Jason Merrill <jason@redhat.com> 2014-08-25 Jason Merrill <jason@redhat.com>
* pt.c (check_explicit_specialization): Don't complain about
non-template variable.
(template_for_substitution): Allow variable templates.
(check_template_variable): Fix logic for member var template.
* decl.c (start_decl): Don't complain about extra template header
here.
* decl.c (start_decl): Look through member variable template. * decl.c (start_decl): Look through member variable template.
* pt.c (tsubst_decl) [VAR_DECL]: Handle member variable templates. * pt.c (tsubst_decl) [VAR_DECL]: Handle member variable templates.
* decl2.c (grokfield): Set DECL_CONTEXT earlier on * decl2.c (grokfield): Set DECL_CONTEXT earlier on
......
...@@ -4672,14 +4672,6 @@ start_decl (const cp_declarator *declarator, ...@@ -4672,14 +4672,6 @@ start_decl (const cp_declarator *declarator,
} }
field = DECL_TEMPLATE_RESULT (field); field = DECL_TEMPLATE_RESULT (field);
} }
else if (this_tmpl)
{
error_at (DECL_SOURCE_LOCATION (decl),
"member template declaration of %qD", decl);
inform (DECL_SOURCE_LOCATION (field), "does not match "
"non-member-template declaration here");
return error_mark_node;
}
if (DECL_CONTEXT (field) != context) if (DECL_CONTEXT (field) != context)
{ {
......
...@@ -2308,7 +2308,8 @@ check_template_variable (tree decl) ...@@ -2308,7 +2308,8 @@ check_template_variable (tree decl)
{ {
tree ctx = CP_DECL_CONTEXT (decl); tree ctx = CP_DECL_CONTEXT (decl);
int wanted = num_template_headers_for_class (ctx); int wanted = num_template_headers_for_class (ctx);
if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
{ {
if (cxx_dialect < cxx14) if (cxx_dialect < cxx14)
pedwarn (DECL_SOURCE_LOCATION (decl), 0, pedwarn (DECL_SOURCE_LOCATION (decl), 0,
...@@ -2323,7 +2324,8 @@ check_template_variable (tree decl) ...@@ -2323,7 +2324,8 @@ check_template_variable (tree decl)
bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0, bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0,
"too many template headers for %D (should be %d)", "too many template headers for %D (should be %d)",
decl, wanted); decl, wanted);
if (warned && CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) if (warned && CLASS_TYPE_P (ctx)
&& CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
inform (DECL_SOURCE_LOCATION (decl), inform (DECL_SOURCE_LOCATION (decl),
"members of an explicitly specialized class are defined " "members of an explicitly specialized class are defined "
"without a template header"); "without a template header");
...@@ -2451,11 +2453,9 @@ check_explicit_specialization (tree declarator, ...@@ -2451,11 +2453,9 @@ check_explicit_specialization (tree declarator,
/* Fall through. */ /* Fall through. */
case tsk_expl_spec: case tsk_expl_spec:
if (VAR_P (decl) && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) if (VAR_P (decl) && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
{ /* In cases like template<> constexpr bool v = true;
// In cases like template<> constexpr bool v = true; We'll give an error in check_template_variable. */
error ("%qD is not a template variable", dname); break;
break;
}
SET_DECL_TEMPLATE_SPECIALIZATION (decl); SET_DECL_TEMPLATE_SPECIALIZATION (decl);
if (ctype) if (ctype)
...@@ -19711,8 +19711,6 @@ template_for_substitution (tree decl) ...@@ -19711,8 +19711,6 @@ template_for_substitution (tree decl)
cannot restructure the loop to just keep going until we find cannot restructure the loop to just keep going until we find
a template with a definition, since that might go too far if a template with a definition, since that might go too far if
a specialization was declared, but not defined. */ a specialization was declared, but not defined. */
gcc_assert (!VAR_P (decl)
|| DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl)));
/* Fetch the more general template. */ /* Fetch the more general template. */
tmpl = DECL_TI_TEMPLATE (tmpl); tmpl = DECL_TI_TEMPLATE (tmpl);
......
// { dg-do compile { target c++14 } }
template <class T>
struct Y
{
template <class U> static U x;
};
template <class T>
template <class U>
U Y<T>::x = U();
int main()
{
int y = Y<int>::x<int>;
}
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