@@ -733,6 +733,13 @@ cp_lexer_previous_token (cp_lexer *lexer)
{
cp_token_position tp = cp_lexer_previous_token_position (lexer);
+ /* Skip past purged tokens. */
+ while (tp->purged_p)
+ {
+ gcc_assert (tp != lexer->buffer->address ());
+ tp--;
+ }
+
return cp_lexer_token_at (lexer, tp);
}
@@ -14733,6 +14740,18 @@ cp_parser_template_id (cp_parser *parser,
/* Reset the contents of the START_OF_ID token. */
token->type = CPP_TEMPLATE_ID;
+
+ /* Update the location to be of the form:
+ template-name < template-argument-list [opt] >
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ with caret == start at the start of the template-name,
+ ranging until the closing '>'. */
+ location_t finish_loc
+ = get_finish (cp_lexer_previous_token (parser->lexer)->location);
+ location_t combined_loc
+ = make_location (token->location, token->location, finish_loc);
+ token->location = combined_loc;
+
/* Retrieve any deferred checks. Do not pop this access checks yet
so the memory will not be reclaimed during token replacing below. */
token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
@@ -8,10 +8,10 @@ template<int> struct A // { dg-error "has been parsed" }
template<int N> struct B
{
- B* p = new B<N>;
+ B* p = new B<N>; // { dg-error "recursive instantiation of non-static data" }
};
-B<1> x; // { dg-error "recursive instantiation of non-static data" }
+B<1> x;
struct C
{
@@ -697,6 +697,15 @@ public:
example_template (TYPENAME v);
};
+void test_template_id (void)
+{
+ example_template <int>; /* { dg-warning "declaration does not declare anything" } */
+/* { dg-begin-multiline-output "" }
+ example_template <int>;
+ ^~~~~~~~~~~~~~~~~~~~~~
+ { dg-end-multiline-output "" } */
+}
+
void test_new (void)
{
__emit_expression_range (0, ::new base); /* { dg-warning "range" } */