aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-02-01 01:01:34 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-02-01 01:01:34 +0000
commit9367851362e79e5854b56c8ad153d4b3c9d9a264 (patch)
treecfa0b1e39e621b716ae38190c9b764f2198c23ed
parent782c0a3ea9b082471e96d881b8c832405785ba2c (diff)
downloadgcc-9367851362e79e5854b56c8ad153d4b3c9d9a264.zip
gcc-9367851362e79e5854b56c8ad153d4b3c9d9a264.tar.gz
gcc-9367851362e79e5854b56c8ad153d4b3c9d9a264.tar.bz2
decl.c (build_enumerator): Do not issue duplicate error messages about invalid enumeration constants.
* decl.c (build_enumerator): Do not issue duplicate error messages about invalid enumeration constants. * parser.c (cp_parser_non_integral_constant_expression): Always set parser->non_integral_constant_expression_p. (cp_parser_primary_expression): Add cast_p parameter. Issue errors about invalid uses of floating-point literals in cast-expressions. (cp_parser_postfix_expression): Add cast_p parameter. (cp_parser_open_square_expression): Pass it. (cp_parser_parenthesized_expression_list): Add cast_p parameter. (cp_parser_unary_expression): Likewise. (cp_parser_new_placement): Pass it. (cp_parser_direct_new_declarator): Likewise. (cp_parser_new_initializer): Likewise. (cp_parser_cast_expression): Add cast_p parameter. (cp_parser_binary_expression): Likewise. (cp_parser_question_colon_clause): Likewise. (cp_parser_assignment_expression): Likewise. (cp_parser_expression): Likewise. (cp_parser_constant_expression): If an integral constant expression is invalid, return error_mark_node. (cp_parser_expression_statement): Pass cast_p. (cp_parser_condition): Likewise. (cp_parser_iteration_statement): Likewise. (cp_parser_jump_statement): Likewise. (cp_parser_mem_initializer): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_parameter_declaration): Likewise. (cp_parser_initializer): Likewise. (cp_parser_throw_expression): Likewise. (cp_parser_attribute_list): Likewise. (cp_parser_simple_cast_expression): Likewise. (cp_parser_functional_cast): Likewise. (cp_parser_late_parsing_default_args): Likewise. (cp_parser_sizeof_operand): Save/restore non_integral_constant_expression_p. * include/std/std_limits.h (numeric_limits<float>::has_denorm): Add required cast. (numeric_limits<double>::has_denorm): Likewise. (numeric_limits<long double>::has_denorm): Likewise. * g++.dg/other/warning1.C: Adjust error messags. * g++.dg/parse/constant5.C: New test. From-SVN: r94512
-rw-r--r--gcc/cp/ChangeLog39
-rw-r--r--gcc/cp/decl.c5
-rw-r--r--gcc/cp/parser.c210
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/warning1.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/constant5.C14
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/include/std/std_limits.h6
8 files changed, 223 insertions, 67 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1baaf0b..92cebfa 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,42 @@
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (build_enumerator): Do not issue duplicate error messages
+ about invalid enumeration constants.
+ * parser.c (cp_parser_non_integral_constant_expression): Always
+ set parser->non_integral_constant_expression_p.
+ (cp_parser_primary_expression): Add cast_p parameter. Issue
+ errors about invalid uses of floating-point literals in
+ cast-expressions.
+ (cp_parser_postfix_expression): Add cast_p parameter.
+ (cp_parser_open_square_expression): Pass it.
+ (cp_parser_parenthesized_expression_list): Add cast_p parameter.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_new_placement): Pass it.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_cast_expression): Add cast_p parameter.
+ (cp_parser_binary_expression): Likewise.
+ (cp_parser_question_colon_clause): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_constant_expression): If an integral constant
+ expression is invalid, return error_mark_node.
+ (cp_parser_expression_statement): Pass cast_p.
+ (cp_parser_condition): Likewise.
+ (cp_parser_iteration_statement): Likewise.
+ (cp_parser_jump_statement): Likewise.
+ (cp_parser_mem_initializer): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_parameter_declaration): Likewise.
+ (cp_parser_initializer): Likewise.
+ (cp_parser_throw_expression): Likewise.
+ (cp_parser_attribute_list): Likewise.
+ (cp_parser_simple_cast_expression): Likewise.
+ (cp_parser_functional_cast): Likewise.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (cp_parser_sizeof_operand): Save/restore
+ non_integral_constant_expression_p.
+
2005-01-31 Mike Stump <mrs@apple.com>
* parser.c (cp_lexer_new_main): Get the first token, first, before
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 964feaa..9be5adf 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9682,6 +9682,11 @@ build_enumerator (tree name, tree value, tree enumtype)
tree context;
tree type;
+ /* If the VALUE was erroneous, pretend it wasn't there; that will
+ result in the enum being assigned the next value in sequence. */
+ if (value == error_mark_node)
+ value = NULL_TREE;
+
/* Remove no-op casts from the value. */
if (value)
STRIP_TYPE_NOPS (value);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ab2a103..e5ea069 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1357,7 +1357,7 @@ static bool cp_parser_translation_unit
/* Expressions [gram.expr] */
static tree cp_parser_primary_expression
- (cp_parser *, cp_id_kind *, tree *);
+ (cp_parser *, bool, cp_id_kind *, tree *);
static tree cp_parser_id_expression
(cp_parser *, bool, bool, bool *, bool);
static tree cp_parser_unqualified_id
@@ -1369,17 +1369,17 @@ static tree cp_parser_nested_name_specifier
static tree cp_parser_class_or_namespace_name
(cp_parser *, bool, bool, bool, bool, bool);
static tree cp_parser_postfix_expression
- (cp_parser *, bool);
+ (cp_parser *, bool, bool);
static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *);
static tree cp_parser_parenthesized_expression_list
- (cp_parser *, bool, bool *);
+ (cp_parser *, bool, bool, bool *);
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression
- (cp_parser *, bool);
+ (cp_parser *, bool, bool);
static enum tree_code cp_parser_unary_operator
(cp_token *);
static tree cp_parser_new_expression
@@ -1397,17 +1397,17 @@ static tree cp_parser_new_initializer
static tree cp_parser_delete_expression
(cp_parser *);
static tree cp_parser_cast_expression
- (cp_parser *, bool);
+ (cp_parser *, bool, bool);
static tree cp_parser_binary_expression
- (cp_parser *);
+ (cp_parser *, bool);
static tree cp_parser_question_colon_clause
(cp_parser *, tree);
static tree cp_parser_assignment_expression
- (cp_parser *);
+ (cp_parser *, bool);
static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *);
static tree cp_parser_expression
- (cp_parser *);
+ (cp_parser *, bool);
static tree cp_parser_constant_expression
(cp_parser *, bool, bool *);
static tree cp_parser_builtin_offsetof
@@ -1945,12 +1945,14 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
/* 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. */
+ return false. In either case, set
+ PARSER->NON_INTEGRAL_CONSTANT_EXPRESSION_P. */
static bool
cp_parser_non_integral_constant_expression (cp_parser *parser,
const char *thing)
{
+ parser->non_integral_constant_expression_p = true;
if (parser->integral_constant_expression_p)
{
if (!parser->allow_non_integral_constant_expression_p)
@@ -1958,7 +1960,6 @@ cp_parser_non_integral_constant_expression (cp_parser *parser,
error ("%s cannot appear in a constant-expression", thing);
return true;
}
- parser->non_integral_constant_expression_p = true;
}
return false;
}
@@ -2639,6 +2640,8 @@ cp_parser_translation_unit (cp_parser* parser)
literal:
__null
+ CAST_P is true if this primary expression is the target of a cast.
+
Returns a representation of the expression.
*IDK indicates what kind of id-expression (if any) was present.
@@ -2650,6 +2653,7 @@ cp_parser_translation_unit (cp_parser* parser)
static tree
cp_parser_primary_expression (cp_parser *parser,
+ bool cast_p,
cp_id_kind *idk,
tree *qualifying_class)
{
@@ -2674,6 +2678,42 @@ cp_parser_primary_expression (cp_parser *parser,
case CPP_WCHAR:
case CPP_NUMBER:
token = cp_lexer_consume_token (parser->lexer);
+ /* Floating-point literals are only allowed in an integral
+ constant expression if they are cast to an integral or
+ enumeration type. */
+ if (TREE_CODE (token->value) == REAL_CST
+ && parser->integral_constant_expression_p)
+ {
+ /* CAST_P will be set even in invalid code like "int(2.7 +
+ ...)". Therefore, we have to check that the next token
+ is sure to end the cast. */
+ if (cast_p)
+ {
+ cp_token *next_token;
+
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (/* The comma at the end of an
+ enumerator-definition. */
+ next_token->type != CPP_COMMA
+ /* The curly brace at the end of an enum-specifier. */
+ && next_token->type != CPP_CLOSE_BRACE
+ /* The end of a statement. */
+ && next_token->type != CPP_SEMICOLON
+ /* The end of the cast-expression. */
+ && next_token->type != CPP_CLOSE_PAREN
+ /* The end of an array bound. */
+ && next_token->type != CPP_CLOSE_SQUARE)
+ cast_p = false;
+ }
+
+ /* If we are within a cast, then the constraint that the
+ cast is to an integral or enumeration type will be
+ checked at that point. If we are not within a cast, then
+ this code is invalid. */
+ if (!cast_p)
+ cp_parser_non_integral_constant_expression
+ (parser, "floating-point literal");
+ }
return token->value;
case CPP_STRING:
@@ -2724,7 +2764,7 @@ cp_parser_primary_expression (cp_parser *parser,
else
{
/* Parse the parenthesized expression. */
- expr = cp_parser_expression (parser);
+ expr = cp_parser_expression (parser, cast_p);
/* Let the front end know that this expression was
enclosed in parentheses. This matters in case, for
example, the expression is of the form `A::B', since
@@ -2803,7 +2843,8 @@ cp_parser_primary_expression (cp_parser *parser,
/* Look for the opening `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
/* Now, parse the assignment-expression. */
- expression = cp_parser_assignment_expression (parser);
+ expression = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false);
/* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "`,'");
/* Parse the type-id. */
@@ -3666,12 +3707,13 @@ cp_parser_class_or_namespace_name (cp_parser *parser,
but they are essentially the same concept.)
If ADDRESS_P is true, the postfix expression is the operand of the
- `&' operator.
+ `&' operator. CAST_P is true if this expression is the target of a
+ cast.
Returns a representation of the expression. */
static tree
-cp_parser_postfix_expression (cp_parser *parser, bool address_p)
+cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
{
cp_token *token;
enum rid keyword;
@@ -3718,7 +3760,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* And the expression which is being cast. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/true);
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Only type conversions to integral or enumeration types
@@ -3791,7 +3833,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
tree expression;
/* Look for an expression. */
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/false);
/* Compute its typeid. */
postfix_expression = build_typeid (expression);
/* Look for the `)' token. */
@@ -3923,6 +3965,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* It must be a primary-expression. */
postfix_expression = cp_parser_primary_expression (parser,
+ cast_p,
&idk,
&qualifying_class);
}
@@ -3981,7 +4024,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
{
bool koenig_p;
tree args = (cp_parser_parenthesized_expression_list
- (parser, false, /*non_constant_p=*/NULL));
+ (parser, false,
+ /*cast_p=*/false,
+ /*non_constant_p=*/NULL));
if (args == error_mark_node)
{
@@ -4174,7 +4219,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
if (for_offsetof)
index = cp_parser_constant_expression (parser, false, NULL);
else
- index = cp_parser_expression (parser);
+ index = cp_parser_expression (parser, /*cast_p=*/false);
/* Look for the closing `]'. */
cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
@@ -4354,6 +4399,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
identifier
identifier, expression-list
+ CAST_P is true if this expression is the target of a cast.
+
Returns a TREE_LIST. The TREE_VALUE of each node is a
representation of an assignment-expression. Note that a TREE_LIST
is returned even if there is only a single expression in the list.
@@ -4367,6 +4414,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
static tree
cp_parser_parenthesized_expression_list (cp_parser* parser,
bool is_attribute_list,
+ bool cast_p,
bool *non_constant_p)
{
tree expression_list = NULL_TREE;
@@ -4411,7 +4459,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = true;
}
else
- expr = cp_parser_assignment_expression (parser);
+ expr = cp_parser_assignment_expression (parser, cast_p);
if (fold_expr_p)
expr = fold_non_dependent_expr (expr);
@@ -4569,12 +4617,13 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
&& identifier
ADDRESS_P is true iff the unary-expression is appearing as the
- operand of the `&' operator.
+ operand of the `&' operator. CAST_P is true if this expression is
+ the target of a cast.
Returns a representation of the expression. */
static tree
-cp_parser_unary_expression (cp_parser *parser, bool address_p)
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
{
cp_token *token;
enum tree_code unary_operator;
@@ -4702,7 +4751,9 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
token = cp_lexer_consume_token (parser->lexer);
/* Parse the cast-expression. */
cast_expression
- = cp_parser_cast_expression (parser, unary_operator == ADDR_EXPR);
+ = cp_parser_cast_expression (parser,
+ unary_operator == ADDR_EXPR,
+ /*cast_p=*/false);
/* Now, build an appropriate representation. */
switch (unary_operator)
{
@@ -4741,7 +4792,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
return expression;
}
- return cp_parser_postfix_expression (parser, address_p);
+ return cp_parser_postfix_expression (parser, address_p, cast_p);
}
/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
@@ -4862,7 +4913,8 @@ cp_parser_new_placement (cp_parser* parser)
/* Parse the expression-list. */
expression_list = (cp_parser_parenthesized_expression_list
- (parser, false, /*non_constant_p=*/NULL));
+ (parser, false, /*cast_p=*/false,
+ /*non_constant_p=*/NULL));
return expression_list;
}
@@ -5009,7 +5061,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
/* The first expression is not required to be constant. */
if (!declarator)
{
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/false);
/* The standard requires that the expression have integral
type. DR 74 adds enumeration types. We believe that the
real intent is that these expressions be handled like the
@@ -5065,7 +5117,8 @@ cp_parser_new_initializer (cp_parser* parser)
tree expression_list;
expression_list = (cp_parser_parenthesized_expression_list
- (parser, false, /*non_constant_p=*/NULL));
+ (parser, false, /*cast_p=*/false,
+ /*non_constant_p=*/NULL));
if (!expression_list)
expression_list = void_zero_node;
@@ -5124,10 +5177,14 @@ cp_parser_delete_expression (cp_parser* parser)
unary-expression
( type-id ) cast-expression
+ ADDRESS_P is true iff the unary-expression is appearing as the
+ operand of the `&' operator. CAST_P is true if this expression is
+ the target of a cast.
+
Returns a representation of the expression. */
static tree
-cp_parser_cast_expression (cp_parser *parser, bool address_p)
+cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
{
/* If it's a `(', then we might be looking at a cast. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -5197,7 +5254,9 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
ctor of T, but looks like a cast to function returning T
without a dependent expression. */
if (!cp_parser_error_occurred (parser))
- expr = cp_parser_simple_cast_expression (parser);
+ expr = cp_parser_cast_expression (parser,
+ /*address_p=*/false,
+ /*cast_p=*/true);
if (cp_parser_parse_definitely (parser))
{
@@ -5227,7 +5286,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
/* If we get here, then it's not a cast, so it must be a
unary-expression. */
- return cp_parser_unary_expression (parser, address_p);
+ return cp_parser_unary_expression (parser, address_p, cast_p);
}
/* Parse a binary expression of the general form:
@@ -5297,6 +5356,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
simple-cast-expression
binary-expression <token> binary-expression
+ CAST_P is true if this expression is the target of a cast.
+
The binops_by_token map is used to get the tree codes for each <token> type.
binary-expressions are associated according to a precedence table. */
@@ -5306,7 +5367,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
: binops_by_token[token->type].prec)
static tree
-cp_parser_binary_expression (cp_parser* parser)
+cp_parser_binary_expression (cp_parser* parser, bool cast_p)
{
cp_parser_expression_stack stack;
cp_parser_expression_stack_entry *sp = &stack[0];
@@ -5317,7 +5378,7 @@ cp_parser_binary_expression (cp_parser* parser)
bool overloaded_p;
/* Parse the first expression. */
- lhs = cp_parser_simple_cast_expression (parser);
+ lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p);
for (;;)
{
@@ -5431,12 +5492,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
expr = NULL_TREE;
else
/* Parse the expression. */
- expr = cp_parser_expression (parser);
+ expr = cp_parser_expression (parser, /*cast_p=*/false);
/* The next token should be a `:'. */
cp_parser_require (parser, CPP_COLON, "`:'");
/* Parse the assignment-expression. */
- assignment_expr = cp_parser_assignment_expression (parser);
+ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false);
/* Build the conditional-expression. */
return build_x_conditional_expr (logical_or_expr,
@@ -5451,10 +5512,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
logical-or-expression assignment-operator assignment_expression
throw-expression
+ CAST_P is true if this expression is the target of a cast.
+
Returns a representation for the expression. */
static tree
-cp_parser_assignment_expression (cp_parser* parser)
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
{
tree expr;
@@ -5467,7 +5530,7 @@ cp_parser_assignment_expression (cp_parser* parser)
else
{
/* Parse the binary expressions (logical-or-expression). */
- expr = cp_parser_binary_expression (parser);
+ expr = cp_parser_binary_expression (parser, cast_p);
/* If the next token is a `?' then we're actually looking at a
conditional-expression. */
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
@@ -5485,7 +5548,7 @@ cp_parser_assignment_expression (cp_parser* parser)
tree rhs;
/* Parse the right-hand side of the assignment. */
- rhs = cp_parser_assignment_expression (parser);
+ rhs = cp_parser_assignment_expression (parser, cast_p);
/* An assignment may not appear in a
constant-expression. */
if (cp_parser_non_integral_constant_expression (parser,
@@ -5600,10 +5663,12 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
assignment-expression
expression , assignment-expression
+ CAST_P is true if this expression is the target of a cast.
+
Returns a representation of the expression. */
static tree
-cp_parser_expression (cp_parser* parser)
+cp_parser_expression (cp_parser* parser, bool cast_p)
{
tree expression = NULL_TREE;
@@ -5613,7 +5678,7 @@ cp_parser_expression (cp_parser* parser)
/* Parse the next assignment-expression. */
assignment_expression
- = cp_parser_assignment_expression (parser);
+ = cp_parser_assignment_expression (parser, cast_p);
/* If this is the first assignment-expression, we can just
save it away. */
if (!expression)
@@ -5691,14 +5756,18 @@ cp_parser_constant_expression (cp_parser* parser,
For example, cp_parser_initializer_clauses uses this function to
determine whether a particular assignment-expression is in fact
constant. */
- expression = cp_parser_assignment_expression (parser);
+ expression = cp_parser_assignment_expression (parser, /*cast_p=*/false);
/* Restore the old settings. */
- parser->integral_constant_expression_p = saved_integral_constant_expression_p;
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
parser->allow_non_integral_constant_expression_p
= saved_allow_non_integral_constant_expression_p;
if (allow_non_constant_p)
*non_constant_p = parser->non_integral_constant_expression_p;
- parser->non_integral_constant_expression_p = saved_non_integral_constant_expression_p;
+ else if (parser->non_integral_constant_expression_p)
+ expression = error_mark_node;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
return expression;
}
@@ -6009,18 +6078,16 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
/* If the next token is a ';', then there is no expression
statement. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- statement = cp_parser_expression (parser);
+ statement = cp_parser_expression (parser, /*cast_p=*/false);
/* Consume the final `;'. */
cp_parser_consume_semicolon_at_end_of_statement (parser);
if (in_statement_expr
&& cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
- {
- /* This is the final expression statement of a statement
- expression. */
- statement = finish_stmt_expr_expr (statement, in_statement_expr);
- }
+ /* This is the final expression statement of a statement
+ expression. */
+ statement = finish_stmt_expr_expr (statement, in_statement_expr);
else if (statement)
statement = finish_expr_stmt (statement);
else
@@ -6247,7 +6314,8 @@ cp_parser_condition (cp_parser* parser)
attributes, /*prefix_attributes=*/NULL_TREE,
&pushed_scope);
/* Parse the assignment-expression. */
- initializer = cp_parser_assignment_expression (parser);
+ initializer = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false);
/* Process the initializer. */
cp_finish_decl (decl,
@@ -6267,7 +6335,7 @@ cp_parser_condition (cp_parser* parser)
cp_parser_abort_tentative_parse (parser);
/* Otherwise, we are looking at an expression. */
- return cp_parser_expression (parser);
+ return cp_parser_expression (parser, /*cast_p=*/false);
}
/* Parse an iteration-statement.
@@ -6340,7 +6408,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
/* Parse the expression. */
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/false);
/* We're done with the do-statement. */
finish_do_stmt (expression, statement);
/* Look for the `)'. */
@@ -6372,7 +6440,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* If there's an expression, process it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/false);
finish_for_expr (expression, statement);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
@@ -6489,7 +6557,7 @@ cp_parser_jump_statement (cp_parser* parser)
/* If the next token is a `;', then there is no
expression. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- expr = cp_parser_expression (parser);
+ expr = cp_parser_expression (parser, /*cast_p=*/false);
else
expr = NULL_TREE;
/* Build the return-statement. */
@@ -6509,7 +6577,7 @@ cp_parser_jump_statement (cp_parser* parser)
/* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */
- finish_goto_stmt (cp_parser_expression (parser));
+ finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false));
}
else
finish_goto_stmt (cp_parser_identifier (parser));
@@ -7624,6 +7692,7 @@ cp_parser_mem_initializer (cp_parser* parser)
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/false,
/*non_constant_p=*/NULL);
if (!expression_list)
expression_list = void_type_node;
@@ -8828,6 +8897,7 @@ cp_parser_template_argument (cp_parser* parser)
{
cp_parser_parse_tentatively (parser);
argument = cp_parser_primary_expression (parser,
+ /*cast_p=*/false,
&idk,
&qualifying_class);
if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
@@ -8852,6 +8922,7 @@ cp_parser_template_argument (cp_parser* parser)
{
cp_parser_parse_tentatively (parser);
argument = cp_parser_primary_expression (parser,
+ /*cast_p=*/false,
&idk,
&qualifying_class);
if (cp_parser_error_occurred (parser)
@@ -11875,7 +11946,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
= parser->local_variables_forbidden_p;
parser->local_variables_forbidden_p = true;
/* Parse the assignment-expression. */
- default_argument = cp_parser_assignment_expression (parser);
+ default_argument
+ = cp_parser_assignment_expression (parser, /*cast_p=*/false);
/* Restore saved state. */
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
@@ -11973,6 +12045,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
}
else if (token->type == CPP_OPEN_PAREN)
init = cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/false,
non_constant_p);
else
{
@@ -13748,7 +13821,8 @@ cp_parser_throw_expression (cp_parser* parser)
|| token->type == CPP_COLON)
expression = NULL_TREE;
else
- expression = cp_parser_assignment_expression (parser);
+ expression = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false);
return build_throw (expression);
}
@@ -13838,7 +13912,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
/* Parse the expression. */
- expression = cp_parser_expression (parser);
+ expression = cp_parser_expression (parser, /*cast_p=*/false);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
@@ -13994,7 +14068,8 @@ cp_parser_attribute_list (cp_parser* parser)
tree arguments;
arguments = (cp_parser_parenthesized_expression_list
- (parser, true, /*non_constant_p=*/NULL));
+ (parser, true, /*cast_p=*/false,
+ /*non_constant_p=*/NULL));
/* Save the identifier and arguments away. */
TREE_VALUE (attribute) = arguments;
}
@@ -14971,7 +15046,8 @@ cp_parser_single_declaration (cp_parser* parser,
static tree
cp_parser_simple_cast_expression (cp_parser *parser)
{
- return cp_parser_cast_expression (parser, /*address_p=*/false);
+ return cp_parser_cast_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false);
}
/* Parse a functional cast to TYPE. Returns an expression
@@ -14985,6 +15061,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/true,
/*non_constant_p=*/NULL);
cast = build_functional_cast (type, expression_list);
@@ -15268,7 +15345,8 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_push_lexer_for_tokens (parser, tokens);
/* Parse the assignment-expression. */
- TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser);
+ TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser,
+ /*cast_p=*/false);
/* If the token stream has not been completely used up, then
there was extra junk after the end of the default
@@ -15300,6 +15378,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
tree expr = NULL_TREE;
const char *saved_message;
bool saved_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
/* Initialize FORMAT the first time we get here. */
if (!format)
@@ -15318,7 +15397,10 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
/* The restrictions on constant-expressions do not apply inside
sizeof expressions. */
- saved_integral_constant_expression_p = parser->integral_constant_expression_p;
+ saved_integral_constant_expression_p
+ = parser->integral_constant_expression_p;
+ saved_non_integral_constant_expression_p
+ = parser->non_integral_constant_expression_p;
parser->integral_constant_expression_p = false;
/* Do not actually evaluate the expression. */
@@ -15363,7 +15445,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
/* If the type-id production did not work out, then we must be
looking at the unary-expression production. */
if (!expr)
- expr = cp_parser_unary_expression (parser, /*address_p=*/false);
+ expr = cp_parser_unary_expression (parser, /*address_p=*/false,
+ /*cast_p=*/false);
/* Go back to evaluating expressions. */
--skip_evaluation;
@@ -15371,7 +15454,10 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
free ((char *) parser->type_definition_forbidden_message);
/* And restore the old one. */
parser->type_definition_forbidden_message = saved_message;
- parser->integral_constant_expression_p = saved_integral_constant_expression_p;
+ parser->integral_constant_expression_p
+ = saved_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p
+ = saved_non_integral_constant_expression_p;
return expr;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 258e232..4c7011e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/other/warning1.C: Adjust error messags.
+ * g++.dg/parse/constant5.C: New test.
+
2005-01-31 Steven Bosscher <stevenb@suse.de>
PR c/19333
diff --git a/gcc/testsuite/g++.dg/other/warning1.C b/gcc/testsuite/g++.dg/other/warning1.C
index 109fc46..a5cce6c 100644
--- a/gcc/testsuite/g++.dg/other/warning1.C
+++ b/gcc/testsuite/g++.dg/other/warning1.C
@@ -7,8 +7,8 @@ extern "C" int printf(const char *, ...);
struct S
{
- static const float inf = 1.0f / 0.0f; // { dg-warning "1.0|initialization" }
- static const float nan = 0.0f / 0.0f; // { dg-warning "0.0|initialization" }
+ static const float inf = 1.0f / 0.0f; // { dg-warning "1.0|float|initialization" }
+ static const float nan = 0.0f / 0.0f; // { dg-warning "0.0|float|initialization" }
};
int main()
diff --git a/gcc/testsuite/g++.dg/parse/constant5.C b/gcc/testsuite/g++.dg/parse/constant5.C
new file mode 100644
index 0000000..db11afb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/constant5.C
@@ -0,0 +1,14 @@
+enum E {
+ a = 24.2, // { dg-error "constant" }
+ b = (int)3.7,
+ c = int(4.2),
+ d = (int)(4.2 + 3.7), // { dg-error "constant" }
+ e = int(4.2 - 3.7), // { dg-error "constant" }
+ f = (int)17.25
+};
+
+struct S {
+ static const int i = (int)4.2;
+ int j[(int)4.2];
+ static const int k = static_cast<short>(3.7);
+};
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c3c526d..f875fa4 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2005-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * include/std/std_limits.h (numeric_limits<float>::has_denorm):
+ Add required cast.
+ (numeric_limits<double>::has_denorm): Likewise.
+ (numeric_limits<long double>::has_denorm): Likewise.
+
2005-01-31 Paolo Carlini <pcarlini@suse.de>
Gabriel Dos Reis <gdr@integrable-solutions.net>
diff --git a/libstdc++-v3/include/std/std_limits.h b/libstdc++-v3/include/std/std_limits.h
index 9bc99e1..6927de1 100644
--- a/libstdc++-v3/include/std/std_limits.h
+++ b/libstdc++-v3/include/std/std_limits.h
@@ -1007,7 +1007,7 @@ namespace std
static const bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
- = __FLT_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = bool(__FLT_DENORM_MIN__) ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcxx_float_has_denorm_loss;
static float infinity() throw()
@@ -1064,7 +1064,7 @@ namespace std
static const bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__;
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
- = __DBL_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = bool(__DBL_DENORM_MIN__) ? denorm_present : denorm_absent;
static const bool has_denorm_loss = __glibcxx_double_has_denorm_loss;
static double infinity() throw()
@@ -1121,7 +1121,7 @@ namespace std
static const bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
static const bool has_signaling_NaN = has_quiet_NaN;
static const float_denorm_style has_denorm
- = __LDBL_DENORM_MIN__ ? denorm_present : denorm_absent;
+ = bool(__LDBL_DENORM_MIN__) ? denorm_present : denorm_absent;
static const bool has_denorm_loss
= __glibcxx_long_double_has_denorm_loss;