From 2725970784399fb8efb1c946472340c2de074f45 Mon Sep 17 00:00:00 2001 From: manu Date: Wed, 13 Aug 2008 10:01:52 +0000 Subject: [PATCH] 2008-08-13 Manuel Lopez-Ibanez PR 35635 * c-common.c (conversion_warning): Use a switch. Ignore boolean expressions except for conversions to signed:1 bitfields. Handle COND_EXPR with constant operands. testsuite/ * gcc.dg/pr35635.c: New. * gcc.dg/Wconversion-integer.c: Update. * gcc.dg/Wconversion-integer-no-sign.c: Update. * gcc.dg/Wsign-conversion.c: Update. * g++.dg/warn/pr35635.C: New. * g++.dg/warn/Wconversion-integer.C: Update. * g++.dg/warn/Wsign-conversion.C: Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139049 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++ gcc/c-common.c | 105 +++++++++++++++------ gcc/testsuite/ChangeLog | 11 +++ gcc/testsuite/g++.dg/warn/Wconversion-integer.C | 4 +- gcc/testsuite/g++.dg/warn/Wsign-conversion.C | 8 +- gcc/testsuite/g++.dg/warn/pr35635.C | 89 +++++++++++++++++ gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c | 4 +- gcc/testsuite/gcc.dg/Wconversion-integer.c | 8 +- gcc/testsuite/gcc.dg/Wsign-conversion.c | 8 +- gcc/testsuite/gcc.dg/pr35635.c | 90 ++++++++++++++++++ 10 files changed, 289 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/pr35635.C create mode 100644 gcc/testsuite/gcc.dg/pr35635.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 805d73dd375..4e03620f40d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-08-13 Manuel Lopez-Ibanez + + PR 35635 + * c-common.c (conversion_warning): Use a switch. Ignore boolean + expressions except for conversions to signed:1 bitfields. Handle + COND_EXPR with constant operands. + 2008-08-13 Richard Guenther PR tree-optimization/15255 diff --git a/gcc/c-common.c b/gcc/c-common.c index 59da62f7ecc..93021820cd6 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1559,39 +1559,63 @@ conversion_warning (tree type, tree expr) { bool give_warning = false; - unsigned int formal_prec = TYPE_PRECISION (type); + tree expr_type = TREE_TYPE (expr); if (!warn_conversion && !warn_sign_conversion) return; - if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST) + switch (TREE_CODE (expr)) { + case EQ_EXPR: + case NE_EXPR: + case LE_EXPR: + case GE_EXPR: + case LT_EXPR: + case GT_EXPR: + case TRUTH_ANDIF_EXPR: + case TRUTH_ORIF_EXPR: + case TRUTH_AND_EXPR: + case TRUTH_OR_EXPR: + case TRUTH_XOR_EXPR: + case TRUTH_NOT_EXPR: + /* Conversion from boolean to a signed:1 bit-field (which only + can hold the values 0 and -1) doesn't lose information - but + it does change the value. */ + if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) + warning (OPT_Wconversion, + "conversion to %qT from boolean expression", type); + return; + + case REAL_CST: + case INTEGER_CST: + /* Warn for real constant that is not an exact integer converted to integer type. */ - if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE + if (TREE_CODE (expr_type) == REAL_TYPE && TREE_CODE (type) == INTEGER_TYPE) { - if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (TREE_TYPE (expr)))) + if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type))) give_warning = true; } /* Warn for an integer constant that does not fit into integer type. */ - else if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE + else if (TREE_CODE (expr_type) == INTEGER_TYPE && TREE_CODE (type) == INTEGER_TYPE && !int_fits_type_p (expr, type)) { - if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr))) + if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type) + && tree_int_cst_sgn (expr) < 0) warning (OPT_Wsign_conversion, "negative integer implicitly converted to unsigned type"); - else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (TREE_TYPE (expr))) - warning (OPT_Wsign_conversion, - "conversion of unsigned constant value to negative integer"); + else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (expr_type)) + warning (OPT_Wsign_conversion, "conversion of unsigned constant " + "value to negative integer"); else give_warning = true; } else if (TREE_CODE (type) == REAL_TYPE) { /* Warn for an integer constant that does not fit into real type. */ - if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE) + if (TREE_CODE (expr_type) == INTEGER_TYPE) { REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr); if (!exact_real_truncate (TYPE_MODE (type), &a)) @@ -1599,8 +1623,8 @@ conversion_warning (tree type, tree expr) } /* Warn for a real constant that does not fit into a smaller real type. */ - else if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE - && formal_prec < TYPE_PRECISION (TREE_TYPE (expr))) + else if (TREE_CODE (expr_type) == REAL_TYPE + && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) { REAL_VALUE_TYPE a = TREE_REAL_CST (expr); if (!exact_real_truncate (TYPE_MODE (type), &a)) @@ -1611,11 +1635,31 @@ conversion_warning (tree type, tree expr) if (give_warning) warning (OPT_Wconversion, "conversion to %qT alters %qT constant value", - type, TREE_TYPE (expr)); - } - else /* 'expr' is not a constant. */ - { - tree expr_type = TREE_TYPE (expr); + type, expr_type); + + return; + + case COND_EXPR: + { + /* In case of COND_EXPR, if both operands are constants or + COND_EXPR, then we do not care about the type of COND_EXPR, + only about the conversion of each operand. */ + tree op1 = TREE_OPERAND (expr, 1); + tree op2 = TREE_OPERAND (expr, 2); + + if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST + || TREE_CODE (op1) == COND_EXPR) + && (TREE_CODE (op2) == REAL_CST || TREE_CODE (op2) == INTEGER_CST + || TREE_CODE (op2) == COND_EXPR)) + { + conversion_warning (type, op1); + conversion_warning (type, op2); + return; + } + /* Fall through. */ + } + + default: /* 'expr' is not a constant. */ /* Warn for real types converted to integer types. */ if (TREE_CODE (expr_type) == REAL_TYPE @@ -1631,11 +1675,11 @@ conversion_warning (tree type, tree expr) /* Don't warn for short y; short x = ((int)y & 0xff); */ if (TREE_CODE (expr) == BIT_AND_EXPR - || TREE_CODE (expr) == BIT_IOR_EXPR + || TREE_CODE (expr) == BIT_IOR_EXPR || TREE_CODE (expr) == BIT_XOR_EXPR) { - /* It both args were extended from a shortest type, use - that type if that is safe. */ + /* If both args were extended from a shortest type, + use that type if that is safe. */ expr_type = shorten_binary_op (expr_type, TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1), @@ -1652,25 +1696,26 @@ conversion_warning (tree type, tree expr) && int_fits_type_p (op0, c_common_signed_type (type)) && int_fits_type_p (op0, c_common_unsigned_type (type))) || (TREE_CODE (op1) == INTEGER_CST - && int_fits_type_p (op1, c_common_signed_type (type)) - && int_fits_type_p (op1, c_common_unsigned_type (type)))) + && int_fits_type_p (op1, c_common_signed_type (type)) + && int_fits_type_p (op1, + c_common_unsigned_type (type)))) return; } } /* Warn for integer types converted to smaller integer types. */ - if (formal_prec < TYPE_PRECISION (expr_type)) + if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) give_warning = true; /* When they are the same width but different signedness, then the value may change. */ - else if ((formal_prec == TYPE_PRECISION (expr_type) + else if ((TYPE_PRECISION (type) == TYPE_PRECISION (expr_type) && TYPE_UNSIGNED (expr_type) != TYPE_UNSIGNED (type)) /* Even when converted to a bigger type, if the type is unsigned but expr is signed, then negative values will be changed. */ || (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type))) - warning (OPT_Wsign_conversion, - "conversion to %qT from %qT may change the sign of the result", + warning (OPT_Wsign_conversion, "conversion to %qT from %qT " + "may change the sign of the result", type, expr_type); } @@ -1682,8 +1727,10 @@ conversion_warning (tree type, tree expr) { tree type_low_bound = TYPE_MIN_VALUE (expr_type); tree type_high_bound = TYPE_MAX_VALUE (expr_type); - REAL_VALUE_TYPE real_low_bound = real_value_from_int_cst (0, type_low_bound); - REAL_VALUE_TYPE real_high_bound = real_value_from_int_cst (0, type_high_bound); + REAL_VALUE_TYPE real_low_bound + = real_value_from_int_cst (0, type_low_bound); + REAL_VALUE_TYPE real_high_bound + = real_value_from_int_cst (0, type_high_bound); if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound) || !exact_real_truncate (TYPE_MODE (type), &real_high_bound)) @@ -1693,7 +1740,7 @@ conversion_warning (tree type, tree expr) /* Warn for real types converted to smaller real types. */ else if (TREE_CODE (expr_type) == REAL_TYPE && TREE_CODE (type) == REAL_TYPE - && formal_prec < TYPE_PRECISION (expr_type)) + && TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) give_warning = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca8c8cfe5d1..50096c9bbc7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2008-08-13 Manuel Lopez-Ibanez + + PR 35635 + * gcc.dg/pr35635.c: New. + * gcc.dg/Wconversion-integer.c: Update. + * gcc.dg/Wconversion-integer-no-sign.c: Update. + * gcc.dg/Wsign-conversion.c: Update. + * g++.dg/warn/pr35635.C: New. + * g++.dg/warn/Wconversion-integer.C: Update. + * g++.dg/warn/Wsign-conversion.C: Update. + 2008-08-13 Richard Guenther PR tree-optimization/15255 diff --git a/gcc/testsuite/g++.dg/warn/Wconversion-integer.C b/gcc/testsuite/g++.dg/warn/Wconversion-integer.C index 46900825a8b..42d9cb00044 100644 --- a/gcc/testsuite/g++.dg/warn/Wconversion-integer.C +++ b/gcc/testsuite/g++.dg/warn/Wconversion-integer.C @@ -42,8 +42,8 @@ void h (int x) uc = x ? 1U : -1; /* { dg-warning "conversion" } */ uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */ - uc = x ? 1 : -1; /* { dg-warning "conversion" } */ - uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + uc = x ? 1 : -1; /* Warned by -Wsign-conversion. */ + uc = x ? SCHAR_MIN : 1; /* Warned by -Wsign-conversion. */ ui = x ? 1U : -1; /* Warned by -Wsign-conversion. */ ui = x ? INT_MIN : 1U; /* Warned by -Wsign-conversion. */ ui = ui ? SCHAR_MIN : 1U; /* Warned by -Wsign-conversion. */ diff --git a/gcc/testsuite/g++.dg/warn/Wsign-conversion.C b/gcc/testsuite/g++.dg/warn/Wsign-conversion.C index b097446c3f8..83fe2ed660b 100644 --- a/gcc/testsuite/g++.dg/warn/Wsign-conversion.C +++ b/gcc/testsuite/g++.dg/warn/Wsign-conversion.C @@ -42,15 +42,15 @@ void h (int x) uc = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ uc = x ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ - uc = x ? 1 : -1; - uc = x ? SCHAR_MIN : 1; + uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ - ui = x ? 1 : -1; /* { dg-warning "conversion" } */ - ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */ uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ diff --git a/gcc/testsuite/g++.dg/warn/pr35635.C b/gcc/testsuite/g++.dg/warn/pr35635.C new file mode 100644 index 00000000000..d3b39a2b0c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr35635.C @@ -0,0 +1,89 @@ +/* PR 35635 */ +/* { dg-do compile } */ +/* { dg-options "-Wconversion -Wsign-conversion" } */ + +struct unsigned_bit { + unsigned int x:1; +} unsigned_bit; +struct signed_bit { + int x:1; +} signed_bit; +int bar; +int bar2; + +void func1() +{ + /* The result of boolean operators fits in unsiged int:1, thus do + not warn. */ + unsigned_bit.x = (bar != 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar == 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar <= 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar >= 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar < 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar > 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = !bar; /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar || bar2); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar && bar2); /* { dg-bogus "conversion" } */ + + /* Both branches of ? fit in the destination, thus do not warn. */ + unsigned_bit.x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */ + unsigned_bit.x = bar != 0 ? 1.0 : 0.0; /* { dg-bogus "conversion" } */ + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */ + unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ +} + +void func2() +{ + signed char schar_x; + + /* Both branches of ? fit in the destination, thus do not warn. */ + schar_x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */ + schar_x = bar != 0 ? 2.0 : 10; /* { dg-bogus "conversion" } */ + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */ + schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */ +} + + + +void func3() +{ + unsigned char uchar_x; + + /* Both branches of ? fit in the destination, thus do not warn. */ + uchar_x = bar != 0 ? 1 : 0; + uchar_x = bar != 0 ? 2.0 : 10; + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */ + uchar_x = bar != 0 + ? (unsigned char) 1024 + : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ +} + +void func4() +{ + signed_bit.x = -1; /* { dg-bogus "conversion" } */ + signed_bit.x = bar != 0 ? -1.0 : 0.0; /* { dg-bogus "conversion" } */ + signed_bit.x = bar != 0 ? -1 : 0; /* { dg-bogus "conversion" } */ + + signed_bit.x = 1; /* { dg-warning "conversion" } */ + signed_bit.x = (bar != 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar == 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar <= 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar >= 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar < 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar > 0); /* { dg-warning "conversion" } */ + signed_bit.x = !bar; /* { dg-warning "conversion" } */ + signed_bit.x = (bar || bar2); /* { dg-warning "conversion" } */ + signed_bit.x = (bar && bar2); /* { dg-warning "conversion" } */ + signed_bit.x = bar != 0 ? 1 : 0; /* { dg-warning "conversion" } */ + signed_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */ +} + diff --git a/gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c b/gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c index 0847db28da9..c17d502d8f3 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c +++ b/gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c @@ -42,8 +42,8 @@ void h (int x) uc = x ? 1U : -1; /* { dg-warning "conversion" } */ uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */ - uc = x ? 1 : -1; /* { dg-warning "conversion" } */ - uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + uc = x ? 1 : -1; /* Warned by -Wsign-conversion. */ + uc = x ? SCHAR_MIN : 1; /* Warned by -Wsign-conversion. */ ui = x ? 1U : -1; /* Warned by -Wsign-conversion. */ ui = x ? INT_MIN : 1U; /* Warned by -Wsign-conversion. */ ui = ui ? SCHAR_MIN : 1U; /* Warned by -Wsign-conversion. */ diff --git a/gcc/testsuite/gcc.dg/Wconversion-integer.c b/gcc/testsuite/gcc.dg/Wconversion-integer.c index 9e3b948251c..b2101076f93 100644 --- a/gcc/testsuite/gcc.dg/Wconversion-integer.c +++ b/gcc/testsuite/gcc.dg/Wconversion-integer.c @@ -44,15 +44,15 @@ void h (int x) /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 43 } */ uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */ /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 45 } */ - uc = x ? 1 : -1; /* { dg-warning "conversion" } */ - uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ - ui = x ? 1 : -1; /* { dg-warning "conversion" } */ - ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */ uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ diff --git a/gcc/testsuite/gcc.dg/Wsign-conversion.c b/gcc/testsuite/gcc.dg/Wsign-conversion.c index 45edd3b4361..0300850f904 100644 --- a/gcc/testsuite/gcc.dg/Wsign-conversion.c +++ b/gcc/testsuite/gcc.dg/Wsign-conversion.c @@ -42,15 +42,15 @@ void h (int x) uc = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ uc = x ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ - uc = x ? 1 : -1; - uc = x ? SCHAR_MIN : 1; + uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ - ui = x ? 1 : -1; /* { dg-warning "conversion" } */ - ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */ + ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ + ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */ uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ diff --git a/gcc/testsuite/gcc.dg/pr35635.c b/gcc/testsuite/gcc.dg/pr35635.c new file mode 100644 index 00000000000..45d10a67bd3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr35635.c @@ -0,0 +1,90 @@ +/* PR 35635 */ +/* { dg-do compile } */ +/* { dg-options "-Wconversion -Wsign-conversion" } */ + +struct unsigned_bit { + unsigned int x:1; +} unsigned_bit; +struct signed_bit { + int x:1; +} signed_bit; +int bar; +int bar2; + +void func1() +{ + /* The result of boolean operators fits in unsiged int:1, thus do + not warn. */ + unsigned_bit.x = (bar != 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar == 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar <= 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar >= 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar < 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar > 0); /* { dg-bogus "conversion" } */ + unsigned_bit.x = !bar; /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar || bar2); /* { dg-bogus "conversion" } */ + unsigned_bit.x = (bar && bar2); /* { dg-bogus "conversion" } */ + + /* Both branches of ? fit in the destination, thus do not warn. */ + unsigned_bit.x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */ + unsigned_bit.x = bar != 0 ? 1.0 : 0.0; /* { dg-bogus "conversion" } */ + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */ + unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ +} + +void func2() +{ + signed char schar_x; + + /* Both branches of ? fit in the destination, thus do not warn. */ + schar_x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */ + schar_x = bar != 0 ? 2.0 : 10; /* { dg-bogus "conversion" } */ + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */ + schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */ +} + + + +void func3() +{ + unsigned char uchar_x; + + /* Both branches of ? fit in the destination, thus do not warn. */ + uchar_x = bar != 0 ? 1 : 0; + uchar_x = bar != 0 ? 2.0 : 10; + + /* At least one branch of ? does not fit in the destination, thus + warn. */ + uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */ + uchar_x = bar != 0 + ? (unsigned char) 1024 + : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ +} + +void func4() +{ + signed_bit.x = -1; /* { dg-bogus "conversion" } */ + signed_bit.x = bar != 0 ? -1.0 : 0.0; /* { dg-bogus "conversion" } */ + signed_bit.x = bar != 0 ? -1 : 0; /* { dg-bogus "conversion" } */ + + + signed_bit.x = 1; /* { dg-warning "conversion" } */ + signed_bit.x = (bar != 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar == 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar <= 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar >= 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar < 0); /* { dg-warning "conversion" } */ + signed_bit.x = (bar > 0); /* { dg-warning "conversion" } */ + signed_bit.x = !bar; /* { dg-warning "conversion" } */ + signed_bit.x = (bar || bar2); /* { dg-warning "conversion" } */ + signed_bit.x = (bar && bar2); /* { dg-warning "conversion" } */ + signed_bit.x = bar != 0 ? 1 : 0; /* { dg-warning "conversion" } */ + signed_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */ +} + -- 2.11.4.GIT