From: Jason Merrill Date: Tue, 17 Nov 2015 21:44:08 +0000 (-0500) Subject: Don't fold -(constant) or -0. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8c2bebddd224cddee49a9e436aac395a1f7716f5;p=gcc.git Don't fold -(constant) or -0. * parser.c (cp_parser_unary_expression): Fold -constant here. * typeck.c (cp_build_unary_op): Not here. From-SVN: r230506 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e4103004286..536fee0b1ba 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-11-17 Jason Merrill + * parser.c (cp_parser_unary_expression): Fold -constant here. + * typeck.c (cp_build_unary_op): Not here. + PR bootstrap/68361 * cvt.c (cp_convert_and_check): Use warning_sentinel to suppress -Wparentheses. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 286c8db54c9..c5f95301e34 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7662,6 +7662,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, /* Consume the operator token. */ token = cp_lexer_consume_token (parser->lexer); + enum cpp_ttype op_ttype = cp_lexer_peek_token (parser->lexer)->type; + /* Parse the cast-expression. */ cast_expression = cp_parser_cast_expression (parser, @@ -7693,8 +7695,25 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, non_constant_p = unary_operator == PREINCREMENT_EXPR ? NIC_PREINCREMENT : NIC_PREDECREMENT; /* Fall through. */ - case UNARY_PLUS_EXPR: case NEGATE_EXPR: + /* Immediately fold negation of a constant, unless the constant is 0 + (since -0 == 0) or it would overflow. */ + if (unary_operator == NEGATE_EXPR && op_ttype == CPP_NUMBER + && CONSTANT_CLASS_P (cast_expression) + && !integer_zerop (cast_expression) + && !TREE_OVERFLOW (cast_expression)) + { + tree folded = fold_build1 (unary_operator, + TREE_TYPE (cast_expression), + cast_expression); + if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded)) + { + expression = folded; + break; + } + } + /* Fall through. */ + case UNARY_PLUS_EXPR: case TRUTH_NOT_EXPR: expression = finish_unary_op_expr (loc, unary_operator, cast_expression, complain); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 6541e97cca5..b7395cf072a 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5768,10 +5768,6 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert, /* Make sure the result is not an lvalue: a unary plus or minus expression is always a rvalue. */ arg = rvalue (arg); - - if (code == NEGATE_EXPR && CONSTANT_CLASS_P (arg)) - /* Immediately fold negation of a constant. */ - return fold_build1 (code, TREE_TYPE (arg), arg); } } break;