aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-common.c105
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/warn/Wconversion-integer.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-conversion.C8
-rw-r--r--gcc/testsuite/g++.dg/warn/pr35635.C89
-rw-r--r--gcc/testsuite/gcc.dg/Wconversion-integer-no-sign.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wconversion-integer.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wsign-conversion.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr35635.c90
10 files changed, 289 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 805d73d..4e03620 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ 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 <rguenther@suse.de>
PR tree-optimization/15255
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 59da62f..9302182 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 ca8c8cf..50096c9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ 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 <rguenther@suse.de>
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 4690082..42d9cb0 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 b097446..83fe2ed 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 0000000..d3b39a2
--- /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 0847db2..c17d502 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 9e3b948..b210107 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 45edd3b..0300850 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 0000000..45d10a6
--- /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" } */
+}
+