re PR c++/14550 (trouble with pointers in templates)
PR c++/14550 * parser.c (cp_parser_non_integral_constant_expression): Encode more of the idiom that surrounded calls to this function within the function itself (cp_parser_primary_expression): Adjust accordingly. (cp_parser_postfix_expression): Likewise. (cp_parser_unary_expression): Likewise. (cp_parser_cast_expression): Likewise. (cp_parser_assignment_expression): Likewise. (cp_parser_expression): Likewise. (cp_parser_new_expression): Note that new-expressions are not allowed in integral constant expressions. (cp_parser_delete_expression): Likewise. PR c++/14550 * g++.dg/parse/template14.C: New test. From-SVN: r79498
This commit is contained in:
parent
983e64842f
commit
625cbf9318
@ -1,3 +1,19 @@
|
||||
2004-03-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/14550
|
||||
* parser.c (cp_parser_non_integral_constant_expression): Encode
|
||||
more of the idiom that surrounded calls to this function within
|
||||
the function itself
|
||||
(cp_parser_primary_expression): Adjust accordingly.
|
||||
(cp_parser_postfix_expression): Likewise.
|
||||
(cp_parser_unary_expression): Likewise.
|
||||
(cp_parser_cast_expression): Likewise.
|
||||
(cp_parser_assignment_expression): Likewise.
|
||||
(cp_parser_expression): Likewise.
|
||||
(cp_parser_new_expression): Note that new-expressions are not
|
||||
allowed in integral constant expressions.
|
||||
(cp_parser_delete_expression): Likewise.
|
||||
|
||||
2004-03-12 Matt Austern <austern@apple.com>
|
||||
|
||||
* decl2.c (maybe_make_one_only): Look at
|
||||
|
170
gcc/cp/parser.c
170
gcc/cp/parser.c
@ -1719,8 +1719,8 @@ static void cp_parser_check_for_definition_in_return_type
|
||||
(tree, int);
|
||||
static void cp_parser_check_for_invalid_template_id
|
||||
(cp_parser *, tree);
|
||||
static tree cp_parser_non_integral_constant_expression
|
||||
(const char *);
|
||||
static bool cp_parser_non_integral_constant_expression
|
||||
(cp_parser *, const char *);
|
||||
static void cp_parser_diagnose_invalid_type_name
|
||||
(cp_parser *, tree, tree);
|
||||
static bool cp_parser_parse_and_diagnose_invalid_type_name
|
||||
@ -1922,14 +1922,24 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
|
||||
}
|
||||
}
|
||||
|
||||
/* Issue an error message about the fact that THING appeared in a
|
||||
constant-expression. Returns ERROR_MARK_NODE. */
|
||||
/* If parsing an integral constant-expression, issue an error message
|
||||
about the fact that THING appeared and return true. Otherwise,
|
||||
return false, marking the current expression as non-constant. */
|
||||
|
||||
static tree
|
||||
cp_parser_non_integral_constant_expression (const char *thing)
|
||||
static bool
|
||||
cp_parser_non_integral_constant_expression (cp_parser *parser,
|
||||
const char *thing)
|
||||
{
|
||||
error ("%s cannot appear in a constant-expression", thing);
|
||||
return error_mark_node;
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
{
|
||||
error ("%s cannot appear in a constant-expression", thing);
|
||||
return true;
|
||||
}
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Emit a diagnostic for an invalid type name. Consider also if it is
|
||||
@ -2542,12 +2552,9 @@ cp_parser_primary_expression (cp_parser *parser,
|
||||
return error_mark_node;
|
||||
}
|
||||
/* Pointers cannot appear in constant-expressions. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return cp_parser_non_integral_constant_expression ("`this'");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"`this'"))
|
||||
return error_mark_node;
|
||||
return finish_this_expr ();
|
||||
|
||||
/* The `operator' keyword can be the beginning of an
|
||||
@ -2589,12 +2596,9 @@ cp_parser_primary_expression (cp_parser *parser,
|
||||
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
|
||||
/* Using `va_arg' in a constant-expression is not
|
||||
allowed. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return cp_parser_non_integral_constant_expression ("`va_arg'");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"`va_arg'"))
|
||||
return error_mark_node;
|
||||
return build_x_va_arg (expression, type);
|
||||
}
|
||||
|
||||
@ -3518,14 +3522,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
|
||||
/* A cast to pointer or reference type is allowed in the
|
||||
implementation of "offsetof". */
|
||||
&& !(parser->in_offsetof_p && POINTER_TYPE_P (type)))
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return (cp_parser_non_integral_constant_expression
|
||||
("a cast to a type other than an integral or "
|
||||
"enumeration type"));
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
&& !(parser->in_offsetof_p && POINTER_TYPE_P (type))
|
||||
&& (cp_parser_non_integral_constant_expression
|
||||
(parser,
|
||||
"a cast to a type other than an integral or "
|
||||
"enumeration type")))
|
||||
return error_mark_node;
|
||||
|
||||
switch (keyword)
|
||||
{
|
||||
@ -3771,13 +3773,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
idk = CP_ID_KIND_NONE;
|
||||
/* Array references are not permitted in
|
||||
constant-expressions. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
postfix_expression
|
||||
= cp_parser_non_integral_constant_expression ("an array reference");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression
|
||||
(parser, "an array reference"))
|
||||
postfix_expression = error_mark_node;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3796,15 +3794,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
|
||||
/* Function calls are not permitted in
|
||||
constant-expressions. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"a function call"))
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
{
|
||||
postfix_expression
|
||||
= cp_parser_non_integral_constant_expression ("a function call");
|
||||
break;
|
||||
}
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
postfix_expression = error_mark_node;
|
||||
break;
|
||||
}
|
||||
|
||||
koenig_p = false;
|
||||
@ -3999,18 +3993,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
operator. */
|
||||
parser->context->object_type = NULL_TREE;
|
||||
/* These operators may not appear in constant-expressions. */
|
||||
if (parser->integral_constant_expression_p
|
||||
/* The "->" operator is allowed in the implementation
|
||||
if (/* The "->" operator is allowed in the implementation
|
||||
of "offsetof". The "." operator may appear in the
|
||||
name of the member. */
|
||||
&& !parser->in_offsetof_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
postfix_expression
|
||||
= (cp_parser_non_integral_constant_expression
|
||||
(token_type == CPP_DEREF ? "'->'" : "`.'"));
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
!parser->in_offsetof_p
|
||||
&& (cp_parser_non_integral_constant_expression
|
||||
(parser,
|
||||
token_type == CPP_DEREF ? "'->'" : "`.'")))
|
||||
postfix_expression = error_mark_node;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4023,13 +4013,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
= finish_increment_expr (postfix_expression,
|
||||
POSTINCREMENT_EXPR);
|
||||
/* Increments may not appear in constant-expressions. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
postfix_expression
|
||||
= cp_parser_non_integral_constant_expression ("an increment");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"an increment"))
|
||||
postfix_expression = error_mark_node;
|
||||
idk = CP_ID_KIND_NONE;
|
||||
break;
|
||||
|
||||
@ -4042,13 +4028,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
= finish_increment_expr (postfix_expression,
|
||||
POSTDECREMENT_EXPR);
|
||||
/* Decrements may not appear in constant-expressions. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
postfix_expression
|
||||
= cp_parser_non_integral_constant_expression ("a decrement");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"a decrement"))
|
||||
postfix_expression = error_mark_node;
|
||||
idk = CP_ID_KIND_NONE;
|
||||
break;
|
||||
|
||||
@ -4447,12 +4429,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (non_constant_p && parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return cp_parser_non_integral_constant_expression (non_constant_p);
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (non_constant_p
|
||||
&& cp_parser_non_integral_constant_expression (parser,
|
||||
non_constant_p))
|
||||
expression = error_mark_node;
|
||||
|
||||
return expression;
|
||||
}
|
||||
@ -4553,6 +4533,11 @@ cp_parser_new_expression (cp_parser* parser)
|
||||
else
|
||||
initializer = NULL_TREE;
|
||||
|
||||
/* A new-expression may not appear in an integral constant
|
||||
expression. */
|
||||
if (cp_parser_non_integral_constant_expression (parser, "`new'"))
|
||||
return error_mark_node;
|
||||
|
||||
/* Create a representation of the new-expression. */
|
||||
return build_new (placement, type, initializer, global_scope_p);
|
||||
}
|
||||
@ -4781,6 +4766,11 @@ cp_parser_delete_expression (cp_parser* parser)
|
||||
/* Parse the cast-expression. */
|
||||
expression = cp_parser_simple_cast_expression (parser);
|
||||
|
||||
/* A delete-expression may not appear in an integral constant
|
||||
expression. */
|
||||
if (cp_parser_non_integral_constant_expression (parser, "`delete'"))
|
||||
return error_mark_node;
|
||||
|
||||
return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
|
||||
}
|
||||
|
||||
@ -4878,14 +4868,13 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
|
||||
can be used in constant-expressions. */
|
||||
if (parser->integral_constant_expression_p
|
||||
&& !dependent_type_p (type)
|
||||
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return (cp_parser_non_integral_constant_expression
|
||||
("a casts to a type other than an integral or "
|
||||
"enumeration type"));
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
|
||||
&& (cp_parser_non_integral_constant_expression
|
||||
(parser,
|
||||
"a cast to a type other than an integral or "
|
||||
"enumeration type")))
|
||||
return error_mark_node;
|
||||
|
||||
/* Perform the cast. */
|
||||
expr = build_c_cast (type, expr);
|
||||
return expr;
|
||||
@ -5238,12 +5227,9 @@ cp_parser_assignment_expression (cp_parser* parser)
|
||||
rhs = cp_parser_assignment_expression (parser);
|
||||
/* An assignment may not appear in a
|
||||
constant-expression. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
return cp_parser_non_integral_constant_expression ("an assignment");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"an assignment"))
|
||||
return error_mark_node;
|
||||
/* Build the assignment expression. */
|
||||
expr = build_x_modify_expr (expr,
|
||||
assignment_operator,
|
||||
@ -5381,13 +5367,9 @@ cp_parser_expression (cp_parser* parser)
|
||||
/* Consume the `,'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* A comma operator cannot appear in a constant-expression. */
|
||||
if (parser->integral_constant_expression_p)
|
||||
{
|
||||
if (!parser->allow_non_integral_constant_expression_p)
|
||||
expression
|
||||
= cp_parser_non_integral_constant_expression ("a comma operator");
|
||||
parser->non_integral_constant_expression_p = true;
|
||||
}
|
||||
if (cp_parser_non_integral_constant_expression (parser,
|
||||
"a comma operator"))
|
||||
expression = error_mark_node;
|
||||
}
|
||||
|
||||
return expression;
|
||||
|
@ -1,3 +1,8 @@
|
||||
2004-03-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/14550
|
||||
* g++.dg/parse/template14.C: New test.
|
||||
|
||||
2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* gcc.c-torture/execute/20040313-1.c: New test.
|
||||
|
17
gcc/testsuite/g++.dg/parse/template14.C
Normal file
17
gcc/testsuite/g++.dg/parse/template14.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/14550
|
||||
|
||||
struct A {
|
||||
A();
|
||||
};
|
||||
|
||||
template <int> void foo()
|
||||
{
|
||||
A *p = new A;
|
||||
}
|
||||
|
||||
void bar()
|
||||
{
|
||||
foo<0>();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user