diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 18 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 58 |
3 files changed, 55 insertions, 27 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 0650758..1c0688b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-08-01 Jan Beulich <jbeulich@suse.com> + + * c-fold.c (c_fully_fold_internal): Also emit shift count + warnings for vector types. + * c-typeck.c (build_binary_op): Likewise. + 2016-07-29 Marek Polacek <polacek@redhat.com> PR c/71742 diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 6c82f24..8bc3a9c1 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -320,8 +320,6 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR) && TREE_CODE (orig_op1) != INTEGER_CST && TREE_CODE (op1) == INTEGER_CST - && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE && c_inhibit_evaluation_warnings == 0) { @@ -330,13 +328,23 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, (code == LSHIFT_EXPR ? G_("left shift count is negative") : G_("right shift count is negative"))); - else if (compare_tree_int (op1, - TYPE_PRECISION (TREE_TYPE (orig_op0))) - >= 0) + else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE + || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) + && compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (orig_op0))) + >= 0) warning_at (loc, OPT_Wshift_count_overflow, (code == LSHIFT_EXPR ? G_("left shift count >= width of type") : G_("right shift count >= width of type"))); + else if (TREE_CODE (TREE_TYPE (orig_op0)) == VECTOR_TYPE + && compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig_op0)))) + >= 0) + warning_at (loc, OPT_Wshift_count_overflow, + code == LSHIFT_EXPR + ? G_("left shift count >= width of vector element") + : G_("right shift count >= width of vector element")); } if (code == LSHIFT_EXPR /* If either OP0 has been folded to INTEGER_CST... */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 07e39ef..33c06d40 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10986,21 +10986,16 @@ build_binary_op (location_t location, enum tree_code code, Also set SHORT_SHIFT if shifting rightward. */ case RSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) - { - result_type = type0; - converted = 1; - } - else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE + && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) { result_type = type0; converted = 1; } - else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE) + else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE + || code0 == VECTOR_TYPE) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11013,6 +11008,18 @@ build_binary_op (location_t location, enum tree_code code, warning_at (location, OPT_Wshift_count_negative, "right shift count is negative"); } + else if (code0 == VECTOR_TYPE) + { + if (compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (type0))) + >= 0) + { + int_const = false; + if (c_inhibit_evaluation_warnings == 0) + warning_at (location, OPT_Wshift_count_overflow, + "right shift count >= width of vector element"); + } + } else { if (!integer_zerop (op1)) @@ -11036,21 +11043,16 @@ build_binary_op (location_t location, enum tree_code code, break; case LSHIFT_EXPR: - if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE) - { - result_type = type0; - converted = 1; - } - else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE - && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE + && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE + && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE + && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1)) { result_type = type0; converted = 1; } - else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE) + else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE + || code0 == VECTOR_TYPE) && code1 == INTEGER_TYPE) { doing_shift = true; @@ -11074,6 +11076,18 @@ build_binary_op (location_t location, enum tree_code code, warning_at (location, OPT_Wshift_count_negative, "left shift count is negative"); } + else if (code0 == VECTOR_TYPE) + { + if (compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (type0))) + >= 0) + { + int_const = false; + if (c_inhibit_evaluation_warnings == 0) + warning_at (location, OPT_Wshift_count_overflow, + "left shift count >= width of vector element"); + } + } else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) { int_const = false; |