PR c++/45976 - error with ::template in declarator.

* pt.c (resolve_typename_type): Fix TEMPLATE_ID_EXPR handling.

From-SVN: r249753
This commit is contained in:
Jason Merrill 2017-06-28 15:41:43 -04:00 committed by Jason Merrill
parent 1e5f79b619
commit 36f48ebd01
3 changed files with 37 additions and 7 deletions

View File

@ -1,5 +1,8 @@
2017-06-28 Jason Merrill <jason@redhat.com>
PR c++/45976 - error with ::template in declarator.
* pt.c (resolve_typename_type): Fix TEMPLATE_ID_EXPR handling.
PR c++/54769 - wrong lookup of dependent template-name.
* parser.c (cp_parser_template_name): Handle dependent object type.
(cp_parser_nested_name_specifier_opt): Make template_keyword_p a

View File

@ -24624,26 +24624,38 @@ resolve_typename_type (tree type, bool only_current_p)
/* For a TYPENAME_TYPE like "typename X::template Y<T>", we want to
find a TEMPLATE_DECL. Otherwise, we want to find a TYPE_DECL. */
tree fullname = TYPENAME_TYPE_FULLNAME (type);
if (!decl)
/*nop*/;
else if (identifier_p (TYPENAME_TYPE_FULLNAME (type))
else if (identifier_p (fullname)
&& TREE_CODE (decl) == TYPE_DECL)
{
result = TREE_TYPE (decl);
if (result == error_mark_node)
result = NULL_TREE;
}
else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == TEMPLATE_ID_EXPR
else if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR
&& DECL_CLASS_TEMPLATE_P (decl))
{
tree tmpl;
tree args;
/* Obtain the template and the arguments. */
tmpl = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 0);
args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1);
tree tmpl = TREE_OPERAND (fullname, 0);
if (TREE_CODE (tmpl) == IDENTIFIER_NODE)
{
/* We get here with a plain identifier because a previous tentative
parse of the nested-name-specifier as part of a ptr-operator saw
::template X<A>. The use of ::template is necessary in a
ptr-operator, but wrong in a declarator-id.
[temp.names]: In a qualified-id of a declarator-id, the keyword
template shall not appear at the top level. */
pedwarn (EXPR_LOC_OR_LOC (fullname, input_location), OPT_Wpedantic,
"keyword %<template%> not allowed in declarator-id");
tmpl = decl;
}
tree args = TREE_OPERAND (fullname, 1);
/* Instantiate the template. */
result = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
/*entering_scope=*/0,
/*entering_scope=*/true,
tf_error | tf_user);
if (result == error_mark_node)
result = NULL_TREE;

View File

@ -0,0 +1,15 @@
// PR c++/45976
template<int a>
struct A {
static const int value;
template<int b>
struct B {
static const int value;
};
};
template<int a>
template<int b>
const int A<a>::template B<b>::value = 0; // { dg-error "keyword .template" }