aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-11-17 16:44:08 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-11-17 16:44:08 -0500
commit8c2bebddd224cddee49a9e436aac395a1f7716f5 (patch)
tree4cfc6535864089407a9ca62300a2da16e43fa7d4 /gcc
parent33c6daf4781dd373ac4760ac020d670e075d3af4 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/parser.c21
-rw-r--r--gcc/cp/typeck.c4
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;