Commit 625cbf93 by Mark Mitchell Committed by Mark Mitchell

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
parent 983e6484
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> 2004-03-12 Matt Austern <austern@apple.com>
* decl2.c (maybe_make_one_only): Look at * decl2.c (maybe_make_one_only): Look at
......
...@@ -1719,8 +1719,8 @@ static void cp_parser_check_for_definition_in_return_type ...@@ -1719,8 +1719,8 @@ static void cp_parser_check_for_definition_in_return_type
(tree, int); (tree, int);
static void cp_parser_check_for_invalid_template_id static void cp_parser_check_for_invalid_template_id
(cp_parser *, tree); (cp_parser *, tree);
static tree cp_parser_non_integral_constant_expression static bool cp_parser_non_integral_constant_expression
(const char *); (cp_parser *, const char *);
static void cp_parser_diagnose_invalid_type_name static void cp_parser_diagnose_invalid_type_name
(cp_parser *, tree, tree); (cp_parser *, tree, tree);
static bool cp_parser_parse_and_diagnose_invalid_type_name static bool cp_parser_parse_and_diagnose_invalid_type_name
...@@ -1922,14 +1922,24 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, ...@@ -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 /* If parsing an integral constant-expression, issue an error message
constant-expression. Returns ERROR_MARK_NODE. */ about the fact that THING appeared and return true. Otherwise,
return false, marking the current expression as non-constant. */
static tree static bool
cp_parser_non_integral_constant_expression (const char *thing) cp_parser_non_integral_constant_expression (cp_parser *parser,
const char *thing)
{ {
error ("%s cannot appear in a constant-expression", thing); if (parser->integral_constant_expression_p)
return error_mark_node; {
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 /* Emit a diagnostic for an invalid type name. Consider also if it is
...@@ -2542,12 +2552,9 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -2542,12 +2552,9 @@ cp_parser_primary_expression (cp_parser *parser,
return error_mark_node; return error_mark_node;
} }
/* Pointers cannot appear in constant-expressions. */ /* Pointers cannot appear in constant-expressions. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "`this'"))
if (!parser->allow_non_integral_constant_expression_p) return error_mark_node;
return cp_parser_non_integral_constant_expression ("`this'");
parser->non_integral_constant_expression_p = true;
}
return finish_this_expr (); return finish_this_expr ();
/* The `operator' keyword can be the beginning of an /* The `operator' keyword can be the beginning of an
...@@ -2589,12 +2596,9 @@ cp_parser_primary_expression (cp_parser *parser, ...@@ -2589,12 +2596,9 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"); cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Using `va_arg' in a constant-expression is not /* Using `va_arg' in a constant-expression is not
allowed. */ allowed. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "`va_arg'"))
if (!parser->allow_non_integral_constant_expression_p) return error_mark_node;
return cp_parser_non_integral_constant_expression ("`va_arg'");
parser->non_integral_constant_expression_p = true;
}
return build_x_va_arg (expression, type); return build_x_va_arg (expression, type);
} }
...@@ -3518,14 +3522,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3518,14 +3522,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type) && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
/* A cast to pointer or reference type is allowed in the /* A cast to pointer or reference type is allowed in the
implementation of "offsetof". */ implementation of "offsetof". */
&& !(parser->in_offsetof_p && POINTER_TYPE_P (type))) && !(parser->in_offsetof_p && POINTER_TYPE_P (type))
{ && (cp_parser_non_integral_constant_expression
if (!parser->allow_non_integral_constant_expression_p) (parser,
return (cp_parser_non_integral_constant_expression "a cast to a type other than an integral or "
("a cast to a type other than an integral or " "enumeration type")))
"enumeration type")); return error_mark_node;
parser->non_integral_constant_expression_p = true;
}
switch (keyword) switch (keyword)
{ {
...@@ -3771,13 +3773,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3771,13 +3773,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
idk = CP_ID_KIND_NONE; idk = CP_ID_KIND_NONE;
/* Array references are not permitted in /* Array references are not permitted in
constant-expressions. */ constant-expressions. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression
{ (parser, "an array reference"))
if (!parser->allow_non_integral_constant_expression_p) postfix_expression = error_mark_node;
postfix_expression
= cp_parser_non_integral_constant_expression ("an array reference");
parser->non_integral_constant_expression_p = true;
}
} }
break; break;
...@@ -3796,15 +3794,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3796,15 +3794,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* Function calls are not permitted in /* Function calls are not permitted in
constant-expressions. */ 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 = error_mark_node;
{ break;
postfix_expression
= cp_parser_non_integral_constant_expression ("a function call");
break;
}
parser->non_integral_constant_expression_p = true;
} }
koenig_p = false; koenig_p = false;
...@@ -3999,18 +3993,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3999,18 +3993,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
operator. */ operator. */
parser->context->object_type = NULL_TREE; parser->context->object_type = NULL_TREE;
/* These operators may not appear in constant-expressions. */ /* These operators may not appear in constant-expressions. */
if (parser->integral_constant_expression_p if (/* The "->" operator is allowed in the implementation
/* The "->" operator is allowed in the implementation
of "offsetof". The "." operator may appear in the of "offsetof". The "." operator may appear in the
name of the member. */ name of the member. */
&& !parser->in_offsetof_p) !parser->in_offsetof_p
{ && (cp_parser_non_integral_constant_expression
if (!parser->allow_non_integral_constant_expression_p) (parser,
postfix_expression token_type == CPP_DEREF ? "'->'" : "`.'")))
= (cp_parser_non_integral_constant_expression postfix_expression = error_mark_node;
(token_type == CPP_DEREF ? "'->'" : "`.'"));
parser->non_integral_constant_expression_p = true;
}
} }
break; break;
...@@ -4023,13 +4013,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -4023,13 +4013,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
= finish_increment_expr (postfix_expression, = finish_increment_expr (postfix_expression,
POSTINCREMENT_EXPR); POSTINCREMENT_EXPR);
/* Increments may not appear in constant-expressions. */ /* Increments may not appear in constant-expressions. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "an increment"))
if (!parser->allow_non_integral_constant_expression_p) postfix_expression = error_mark_node;
postfix_expression
= cp_parser_non_integral_constant_expression ("an increment");
parser->non_integral_constant_expression_p = true;
}
idk = CP_ID_KIND_NONE; idk = CP_ID_KIND_NONE;
break; break;
...@@ -4042,13 +4028,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -4042,13 +4028,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
= finish_increment_expr (postfix_expression, = finish_increment_expr (postfix_expression,
POSTDECREMENT_EXPR); POSTDECREMENT_EXPR);
/* Decrements may not appear in constant-expressions. */ /* Decrements may not appear in constant-expressions. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "a decrement"))
if (!parser->allow_non_integral_constant_expression_p) postfix_expression = error_mark_node;
postfix_expression
= cp_parser_non_integral_constant_expression ("a decrement");
parser->non_integral_constant_expression_p = true;
}
idk = CP_ID_KIND_NONE; idk = CP_ID_KIND_NONE;
break; break;
...@@ -4447,12 +4429,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) ...@@ -4447,12 +4429,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
abort (); abort ();
} }
if (non_constant_p && parser->integral_constant_expression_p) if (non_constant_p
{ && cp_parser_non_integral_constant_expression (parser,
if (!parser->allow_non_integral_constant_expression_p) non_constant_p))
return cp_parser_non_integral_constant_expression (non_constant_p); expression = error_mark_node;
parser->non_integral_constant_expression_p = true;
}
return expression; return expression;
} }
...@@ -4553,6 +4533,11 @@ cp_parser_new_expression (cp_parser* parser) ...@@ -4553,6 +4533,11 @@ cp_parser_new_expression (cp_parser* parser)
else else
initializer = NULL_TREE; 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. */ /* Create a representation of the new-expression. */
return build_new (placement, type, initializer, global_scope_p); return build_new (placement, type, initializer, global_scope_p);
} }
...@@ -4781,6 +4766,11 @@ cp_parser_delete_expression (cp_parser* parser) ...@@ -4781,6 +4766,11 @@ cp_parser_delete_expression (cp_parser* parser)
/* Parse the cast-expression. */ /* Parse the cast-expression. */
expression = cp_parser_simple_cast_expression (parser); 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); 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) ...@@ -4878,14 +4868,13 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
can be used in constant-expressions. */ can be used in constant-expressions. */
if (parser->integral_constant_expression_p if (parser->integral_constant_expression_p
&& !dependent_type_p (type) && !dependent_type_p (type)
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
{ && (cp_parser_non_integral_constant_expression
if (!parser->allow_non_integral_constant_expression_p) (parser,
return (cp_parser_non_integral_constant_expression "a cast to a type other than an integral or "
("a casts to a type other than an integral or " "enumeration type")))
"enumeration type")); return error_mark_node;
parser->non_integral_constant_expression_p = true;
}
/* Perform the cast. */ /* Perform the cast. */
expr = build_c_cast (type, expr); expr = build_c_cast (type, expr);
return expr; return expr;
...@@ -5238,12 +5227,9 @@ cp_parser_assignment_expression (cp_parser* parser) ...@@ -5238,12 +5227,9 @@ cp_parser_assignment_expression (cp_parser* parser)
rhs = cp_parser_assignment_expression (parser); rhs = cp_parser_assignment_expression (parser);
/* An assignment may not appear in a /* An assignment may not appear in a
constant-expression. */ constant-expression. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "an assignment"))
if (!parser->allow_non_integral_constant_expression_p) return error_mark_node;
return cp_parser_non_integral_constant_expression ("an assignment");
parser->non_integral_constant_expression_p = true;
}
/* Build the assignment expression. */ /* Build the assignment expression. */
expr = build_x_modify_expr (expr, expr = build_x_modify_expr (expr,
assignment_operator, assignment_operator,
...@@ -5381,13 +5367,9 @@ cp_parser_expression (cp_parser* parser) ...@@ -5381,13 +5367,9 @@ cp_parser_expression (cp_parser* parser)
/* Consume the `,'. */ /* Consume the `,'. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
/* A comma operator cannot appear in a constant-expression. */ /* A comma operator cannot appear in a constant-expression. */
if (parser->integral_constant_expression_p) if (cp_parser_non_integral_constant_expression (parser,
{ "a comma operator"))
if (!parser->allow_non_integral_constant_expression_p) expression = error_mark_node;
expression
= cp_parser_non_integral_constant_expression ("a comma operator");
parser->non_integral_constant_expression_p = true;
}
} }
return expression; return expression;
......
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> 2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20040313-1.c: New test. * gcc.c-torture/execute/20040313-1.c: New test.
......
// PR c++/14550
struct A {
A();
};
template <int> void foo()
{
A *p = new A;
}
void bar()
{
foo<0>();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment