diff options
author | Jason Merrill <jason@redhat.com> | 2015-01-06 15:44:59 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-01-06 15:44:59 -0500 |
commit | efcdb22fe3288fbfa4cd8ba9554b3a561c4d6e08 (patch) | |
tree | 9e6a76a93de820d6c2c6f7e3980a979f81f7ca93 | |
parent | c6a38536f205e0723600d54bce3aaf05ec107161 (diff) | |
download | gcc-efcdb22fe3288fbfa4cd8ba9554b3a561c4d6e08.zip gcc-efcdb22fe3288fbfa4cd8ba9554b3a561c4d6e08.tar.gz gcc-efcdb22fe3288fbfa4cd8ba9554b3a561c4d6e08.tar.bz2 |
parser.c (cp_parser_nested_name_specifier_opt): Diagnose invalid template-ids.
* parser.c (cp_parser_nested_name_specifier_opt): Diagnose invalid
template-ids.
From-SVN: r219269
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ20.C | 12 |
3 files changed, 55 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e5e54ea..f9322bf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-01-06 Jason Merrill <jason@redhat.com> + * parser.c (cp_parser_nested_name_specifier_opt): Diagnose invalid + template-ids. + PR c++/64455 * pt.c (type_dependent_expression_p): Handle variable templates. * constexpr.c (potential_constant_expression_1): Use it. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 22dff06..5c23a36 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5435,6 +5435,46 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, cp_lexer_consume_token (parser->lexer); } + if (cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID) + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE)) + { + /* If we have a non-type template-id followed by ::, it can't + possibly be valid. */ + token = cp_lexer_peek_token (parser->lexer); + tree tid = token->u.tree_check_value->value; + if (TREE_CODE (tid) == TEMPLATE_ID_EXPR + && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE) + { + tree tmpl = NULL_TREE; + if (is_overloaded_fn (tid)) + { + tree fns = get_fns (tid); + if (!OVL_CHAIN (fns)) + tmpl = OVL_CURRENT (fns); + error_at (token->location, "function template-id %qD " + "in nested-name-specifier", tid); + } + else + { + /* Variable template. */ + tmpl = TREE_OPERAND (tid, 0); + gcc_assert (variable_template_p (tmpl)); + error_at (token->location, "variable template-id %qD " + "in nested-name-specifier", tid); + } + if (tmpl) + inform (DECL_SOURCE_LOCATION (tmpl), + "%qD declared here", tmpl); + + parser->scope = error_mark_node; + error_p = true; + /* As below. */ + success = true; + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + } + } + if (cp_parser_uncommitted_to_tentative_parse_p (parser)) break; /* If the next token is an identifier, and the one after diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ20.C b/gcc/testsuite/g++.dg/cpp1y/var-templ20.C new file mode 100644 index 0000000..38bd370 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ20.C @@ -0,0 +1,12 @@ +// { dg-do compile { target c++14 } } + +template <bool> struct Sink {}; +template <class T> void fn(); +template <class T> T var = T(); + +template <class T> void f() +{ + Sink<fn<T>::value>(); // { dg-error "function" } + Sink<var<T>::value>(); // { dg-error "variable" } +} +// { dg-prune-output "template argument" } |