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. * decl2.c (grokfield): Set DECL_CONTEXT earlier on variables. From-SVN: r214420
This commit is contained in:
parent
2167dc924b
commit
3749134042
|
@ -1,3 +1,10 @@
|
|||
2014-08-25 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* decl.c (start_decl): Look through member variable template.
|
||||
* pt.c (tsubst_decl) [VAR_DECL]: Handle member variable templates.
|
||||
* decl2.c (grokfield): Set DECL_CONTEXT earlier on
|
||||
variables.
|
||||
|
||||
2014-08-25 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/34938
|
||||
|
|
|
@ -4650,13 +4650,37 @@ start_decl (const cp_declarator *declarator,
|
|||
|
||||
if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
|
||||
{
|
||||
bool this_tmpl = (processing_template_decl
|
||||
> template_class_depth (context));
|
||||
if (VAR_P (decl))
|
||||
{
|
||||
tree field = lookup_field (context, DECL_NAME (decl), 0, false);
|
||||
if (field == NULL_TREE || !VAR_P (field))
|
||||
error ("%q#D is not a static member of %q#T", decl, context);
|
||||
if (field == NULL_TREE
|
||||
|| !(VAR_P (field) || variable_template_p (field)))
|
||||
error ("%q+#D is not a static data member of %q#T", decl, context);
|
||||
else
|
||||
{
|
||||
if (variable_template_p (field))
|
||||
{
|
||||
if (!this_tmpl)
|
||||
{
|
||||
error_at (DECL_SOURCE_LOCATION (decl),
|
||||
"non-member-template declaration of %qD", decl);
|
||||
inform (DECL_SOURCE_LOCATION (field), "does not match "
|
||||
"member template declaration here");
|
||||
return error_mark_node;
|
||||
}
|
||||
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 (!same_type_p (DECL_CONTEXT (field), context))
|
||||
|
@ -4683,8 +4707,7 @@ start_decl (const cp_declarator *declarator,
|
|||
else
|
||||
{
|
||||
tree field = check_classfn (context, decl,
|
||||
(processing_template_decl
|
||||
> template_class_depth (context))
|
||||
this_tmpl
|
||||
? current_template_parms
|
||||
: NULL_TREE);
|
||||
if (field && field != error_mark_node
|
||||
|
|
|
@ -994,6 +994,10 @@ grokfield (const cp_declarator *declarator,
|
|||
&& DECL_CONTEXT (value) != current_class_type)
|
||||
return value;
|
||||
|
||||
/* Need to set this before push_template_decl. */
|
||||
if (TREE_CODE (value) == VAR_DECL)
|
||||
DECL_CONTEXT (value) = current_class_type;
|
||||
|
||||
if (processing_template_decl && VAR_OR_FUNCTION_DECL_P (value))
|
||||
{
|
||||
value = push_template_decl (value);
|
||||
|
|
13
gcc/cp/pt.c
13
gcc/cp/pt.c
|
@ -11127,13 +11127,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
same_type_p, because DECL_CONTEXT is always
|
||||
canonical... */
|
||||
if (ctx == DECL_CONTEXT (t)
|
||||
&& (TREE_CODE (t) != TYPE_DECL
|
||||
/* ... unless T is a member template; in which
|
||||
case our caller can be willing to create a
|
||||
specialization of that template represented
|
||||
by T. */
|
||||
|| !(DECL_TI_TEMPLATE (t)
|
||||
&& DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (t)))))
|
||||
/* ... unless T is a member template; in which
|
||||
case our caller can be willing to create a
|
||||
specialization of that template represented
|
||||
by T. */
|
||||
&& !(DECL_TI_TEMPLATE (t)
|
||||
&& DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
|
||||
spec = t;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
struct A {};
|
||||
|
||||
void (*A::p)(auto) = 0; // { dg-error "static member|template" }
|
||||
void (*A::p)(auto) = 0; // { dg-error "static data member|template" }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// { dg-do compile { target c++14 } }
|
||||
// { dg-final { scan-assembler "_ZN1X1xIiEE" } }
|
||||
|
||||
struct X
|
||||
{
|
||||
template <class T> static T x;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T X::x = T();
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = X::x<int>;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// { dg-do compile { target c++14 } }
|
||||
|
||||
struct X
|
||||
{
|
||||
template <class T> static int x;
|
||||
};
|
||||
|
||||
int X::x = 42; // { dg-error "template" }
|
||||
|
||||
struct Y
|
||||
{
|
||||
static int y;
|
||||
};
|
||||
|
||||
template <class T> int Y::y = 42; // { dg-error "template" }
|
Loading…
Reference in New Issue