@@ -15260,7 +15260,11 @@ cp_parser_using_declaration (cp_parser* parser,
/* Parse an alias-declaration.
alias-declaration:
- using identifier attribute-specifier-seq [opt] = type-id */
+ using identifier attribute-specifier-seq [opt] = type-id
+
+ Note that if this function is used in the context of a tentative
+ parse, it commits the currently active tentative parse after it
+ sees the '=' token. */
static tree
cp_parser_alias_declaration (cp_parser* parser)
@@ -15293,6 +15297,8 @@ cp_parser_alias_declaration (cp_parser* parser)
if (cp_parser_error_occurred (parser))
return error_mark_node;
+ cp_parser_commit_to_tentative_parse (parser);
+
/* Now we are going to parse the type-id of the declaration. */
/*
@@ -15322,6 +15328,9 @@ cp_parser_alias_declaration (cp_parser* parser)
if (parser->num_template_parameter_lists)
parser->type_definition_forbidden_message = saved_message;
+ if (type == error_mark_node)
+ return error_mark_node;
+
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
if (cp_parser_error_occurred (parser))
@@ -19058,9 +19067,19 @@ cp_parser_member_declaration (cp_parser* parser)
else
{
tree decl;
+ bool alias_decl_expected;
cp_parser_parse_tentatively (parser);
decl = cp_parser_alias_declaration (parser);
- if (cp_parser_parse_definitely (parser))
+ /* Note that if we actually see the '=' token after the
+ identifier, cp_parser_alias_declaration commits the
+ tentative parse. In that case, we really expects an
+ alias-declaration. Otherwise, we expect a using
+ declaration. */
+ alias_decl_expected =
+ !cp_parser_uncommitted_to_tentative_parse_p (parser);
+ cp_parser_parse_definitely (parser);
+
+ if (alias_decl_expected)
finish_member_declaration (decl);
else
cp_parser_using_declaration (parser,
@@ -23,6 +23,6 @@ template<class T>
using A3 =
enum B3 {b = 0;}; //{ dg-error "types may not be defined in alias template" }
-A3<int> a3;
+A3<int> a3; // { dg-error "'A3' does not name a type" }
int main() { }
new file mode 100644
@@ -0,0 +1,7 @@
+// Origin: PR c++/54401
+// { dg-do compile { target c++11 } }
+
+template<typename>
+struct X {
+ using type = T; // { dg-error "expected type-specifier|does not name a type" }
+};