[C/C++ Patch] PR 51294

Paolo Carlini paolo.carlini@oracle.com
Sat May 12 17:36:00 GMT 2012


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.

/////////////////
-------------- next part --------------
/c-family
2012-05-12  Paolo Carlini  <paolo.carlini@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.carlini@oracle.com>

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

-------------- next part --------------
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" } */
+}


More information about the Gcc-patches mailing list