diff options
author | Jason Merrill <jason@redhat.com> | 2015-11-17 16:44:08 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-11-17 16:44:08 -0500 |
commit | 8c2bebddd224cddee49a9e436aac395a1f7716f5 (patch) | |
tree | 4cfc6535864089407a9ca62300a2da16e43fa7d4 | |
parent | 33c6daf4781dd373ac4760ac020d670e075d3af4 (diff) | |
download | gcc-8c2bebddd224cddee49a9e436aac395a1f7716f5.zip gcc-8c2bebddd224cddee49a9e436aac395a1f7716f5.tar.gz gcc-8c2bebddd224cddee49a9e436aac395a1f7716f5.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 21 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 |
3 files changed, 23 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e410300..536fee0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-11-17 Jason Merrill <jason@redhat.com> + * 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 286c8db..c5f9530 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 6541e97c..b7395cf 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; |