aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2012-11-28 09:27:10 +0000
committerRichard Biener <rguenther@suse.de>2012-11-28 09:27:10 +0000
commitd5c4dfb70a2156a2da3605877a0c2960b1f32cde (patch)
tree708df4dc743c4f6d7778396707a8a1254049b1dd /gcc/c-family
parentca2dd887382c9ea98b92685bf894a815200dced0 (diff)
2012-11-28 Richard Biener <rguenther@suse.de>
PR c/35634 * gimple.h (gimplify_self_mod_expr): Declare. * gimplify.c (gimplify_self_mod_expr): Export. Take a different type for performing the arithmetic in. (gimplify_expr): Adjust. * tree-vect-loop-manip.c (vect_can_advance_ivs_p): Strip sign conversions we can re-apply after adjusting the IV. c-family/ * c-gimplify.c (c_gimplify_expr): Gimplify self-modify expressions here and use a type with proper overflow behavior for types that would need to be promoted for the arithmetic. * gcc.dg/torture/pr35634.c: New testcase. * g++.dg/torture/pr35634.C: Likewise. * gcc.dg/vect/pr18536.c: Mark worker function noinline. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@193882 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-gimplify.c41
2 files changed, 38 insertions, 10 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index ce794a29273..ab68f3abd05 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2012-11-28 Richard Biener <rguenther@suse.de>
+
+ PR c/35634
+ * c-gimplify.c (c_gimplify_expr): Gimplify self-modify expressions
+ here and use a type with proper overflow behavior for types that would
+ need to be promoted for the arithmetic.
+
2012-11-23 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/55435
diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
index 27814e1a1fb..74c94c140f5 100644
--- a/gcc/c-family/c-gimplify.c
+++ b/gcc/c-family/c-gimplify.c
@@ -172,16 +172,37 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
{
enum tree_code code = TREE_CODE (*expr_p);
- /* This is handled mostly by gimplify.c, but we have to deal with
- not warning about int x = x; as it is a GCC extension to turn off
- this warning but only if warn_init_self is zero. */
- if (code == DECL_EXPR
- && TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
- && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
- && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
- && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
- && !warn_init_self)
- TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+ switch (code)
+ {
+ case DECL_EXPR:
+ /* This is handled mostly by gimplify.c, but we have to deal with
+ not warning about int x = x; as it is a GCC extension to turn off
+ this warning but only if warn_init_self is zero. */
+ if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
+ && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
+ && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
+ && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) == DECL_EXPR_DECL (*expr_p))
+ && !warn_init_self)
+ TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+ break;
+
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ {
+ tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
+ if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
+ {
+ if (TYPE_OVERFLOW_UNDEFINED (type))
+ type = unsigned_type_for (type);
+ return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
+ }
+ break;
+ }
+
+ default:;
+ }
return GS_UNHANDLED;
}