re PR c++/57 ([DR 325] GCC can't parse a non-parenthesized comma in a template-id within a default argument)
PR c++/57 * parser.c (cp_parser_parameter_declaration): Handle < ambiguity in default arguments. Co-Authored-By: Liu Guanwei <liu_gw@163.com> From-SVN: r134762
This commit is contained in:
parent
d6b68fccba
commit
bda3795274
@ -1,3 +1,10 @@
|
||||
2008-04-28 Jason Merrill <jason@redhat.com>
|
||||
Liu Guanwei <liu_gw@163.com>
|
||||
|
||||
PR c++/57
|
||||
* parser.c (cp_parser_parameter_declaration): Handle < ambiguity
|
||||
in default arguments.
|
||||
|
||||
2008-04-25 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* typeck.c (check_return_expr): Update.
|
||||
|
@ -13723,6 +13723,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
&& TYPE_BEING_DEFINED (current_class_type))
|
||||
{
|
||||
unsigned depth = 0;
|
||||
int maybe_template_id = 0;
|
||||
cp_token *first_token;
|
||||
cp_token *token;
|
||||
|
||||
@ -13741,6 +13742,33 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
/* In valid code, a default argument must be
|
||||
immediately followed by a `,' `)', or `...'. */
|
||||
case CPP_COMMA:
|
||||
if (depth == 0 && maybe_template_id)
|
||||
{
|
||||
/* If we've seen a '<', we might be in a
|
||||
template-argument-list. Until Core issue 325 is
|
||||
resolved, we don't know how this situation ought
|
||||
to be handled, so try to DTRT. We check whether
|
||||
what comes after the comma is a valid parameter
|
||||
declaration list. If it is, then the comma ends
|
||||
the default argument; otherwise the default
|
||||
argument continues. */
|
||||
bool error = false;
|
||||
|
||||
/* Set ITALP so cp_parser_parameter_declaration_list
|
||||
doesn't decide to commit to this parse. */
|
||||
bool saved_italp = parser->in_template_argument_list_p;
|
||||
parser->in_template_argument_list_p = true;
|
||||
|
||||
cp_parser_parse_tentatively (parser);
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
cp_parser_parameter_declaration_list (parser, &error);
|
||||
if (!cp_parser_error_occurred (parser) && !error)
|
||||
done = true;
|
||||
cp_parser_abort_tentative_parse (parser);
|
||||
|
||||
parser->in_template_argument_list_p = saved_italp;
|
||||
break;
|
||||
}
|
||||
case CPP_CLOSE_PAREN:
|
||||
case CPP_ELLIPSIS:
|
||||
/* If we run into a non-nested `;', `}', or `]',
|
||||
@ -13764,6 +13792,13 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
++depth;
|
||||
break;
|
||||
|
||||
case CPP_LESS:
|
||||
if (depth == 0)
|
||||
/* This might be the comparison operator, or it might
|
||||
start a template argument list. */
|
||||
++maybe_template_id;
|
||||
break;
|
||||
|
||||
case CPP_RSHIFT:
|
||||
if (cxx_dialect == cxx98)
|
||||
break;
|
||||
@ -13772,11 +13807,16 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
cases. */
|
||||
|
||||
case CPP_GREATER:
|
||||
/* If we see a non-nested `>', and `>' is not an
|
||||
operator, then it marks the end of the default
|
||||
argument. */
|
||||
if (!depth && !greater_than_is_operator_p)
|
||||
done = true;
|
||||
if (depth == 0)
|
||||
{
|
||||
/* This might be an operator, or it might close a
|
||||
template argument list. But if a previous '<'
|
||||
started a template argument list, this will have
|
||||
closed it, so we can't be in one anymore. */
|
||||
maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
|
||||
if (maybe_template_id < 0)
|
||||
maybe_template_id = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
/* If we run out of tokens, issue an error message. */
|
||||
|
@ -3,15 +3,15 @@
|
||||
// Default arguments containing more than one non-nested explicit
|
||||
// template argument leads to parse error
|
||||
|
||||
// This might be ill formed. See DR 325 (which would like to make it
|
||||
// so)
|
||||
// This might be ill formed. See DR 325 (one proposed resolution is to make
|
||||
// it so)
|
||||
|
||||
template <class T> class foo1;
|
||||
template <class T, class U> class foo2; // { dg-error "" }
|
||||
template <class T, class U> class foo2;
|
||||
|
||||
struct bar {
|
||||
template <class T, class U>
|
||||
bar(int i = foo1<T>::baz, // { dg-bogus "" } -
|
||||
int j = int(foo2<T, U>::baz), // ok
|
||||
int k = foo2<T, U>::baz) {} // { dg-error "" }
|
||||
int k = foo2<T, U>::baz) {} // ok?
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user