Hi,

the below is my (very conservative, I think) interpretation of what we recently summarized we want to do wrt these -Wconversion warnings in the conditional expressions context. Of course many details could be different, please let me know... This is booted and tested on x86_64-linux.

Thanks,
Paolo.

/////////////////
/c-family
2012-05-12  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c/51294
        * c-common.c (conversion_warning): In case of COND_EXPR don't warn
        when unpromoted integer operands fit the target type.

/testsuite
2012-05-12  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c/51294
        * c-c++-common/Wconversion-pr51294.c: New.

Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c (revision 187424)
+++ c-family/c-common.c (working copy)
@@ -2296,17 +2296,27 @@ conversion_warning (tree type, tree expr)
 
     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.  */
+       /* In case of COND_EXPR, if both operands are real constants,
+          integer types, 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);
+       tree op1_type = TREE_TYPE (op1);
+       tree op2_type = TREE_TYPE (op2);
 
-       if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST
+       if ((TREE_CODE (op1) == REAL_CST || INTEGRAL_TYPE_P (op1_type)
             || TREE_CODE (op1) == COND_EXPR)
-           && (TREE_CODE (op2) == REAL_CST || TREE_CODE (op2) == INTEGER_CST
+           && (TREE_CODE (op2) == REAL_CST || INTEGRAL_TYPE_P (op2_type)
                || TREE_CODE (op2) == COND_EXPR))
          {
+           /* Don't warn about char y = 0xff, x = cond ? y : 0;  */
+           if (INTEGRAL_TYPE_P (op1_type)
+               && TREE_CODE (op1) != INTEGER_CST)
+             op1 = get_unwidened (op1, 0);
+           if (INTEGRAL_TYPE_P (op2_type)
+               && TREE_CODE (op2) != INTEGER_CST)
+             op2 = get_unwidened (op2, 0);
+
            conversion_warning (type, op1);
            conversion_warning (type, op2);
            return;
Index: testsuite/c-c++-common/Wconversion-pr51294.c
===================================================================
--- testsuite/c-c++-common/Wconversion-pr51294.c        (revision 0)
+++ testsuite/c-c++-common/Wconversion-pr51294.c        (revision 0)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Wconversion" } */
+
+#ifdef __cplusplus
+#define BOOL bool
+#else
+#define BOOL _Bool
+#endif
+
+void foo (BOOL cond, char c, int i)
+{
+  c = cond ? c : 0;
+  c = cond ? 0 : c;
+  c = cond ? i : 0;  /* { dg-warning "conversion" } */
+  c = cond ? 0 : i;  /* { dg-warning "conversion" } */
+
+  c = cond ? (cond ? 0 : c) : 0;
+  c = cond ? 0 : (cond ? c : 0);
+  c = cond ? (cond ? 0 : i) : 0;  /* { dg-warning "conversion" } */
+  c = cond ? 0 : (cond ? i : 0);  /* { dg-warning "conversion" } */
+}

Reply via email to