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:
parent
1e5f79b619
commit
36f48ebd01
@ -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
|
||||
|
26
gcc/cp/pt.c
26
gcc/cp/pt.c
@ -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;
|
||||
|
15
gcc/testsuite/g++.dg/template/template-keyword1.C
Normal file
15
gcc/testsuite/g++.dg/template/template-keyword1.C
Normal 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" }
|
Loading…
x
Reference in New Issue
Block a user