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
--- /dev/null
+// { 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" }