diff mbox

Fix a few simple cases where -Wparentheses does not warn for omitted middle value

Message ID AM4PR0701MB2162FE497AB386295BF943E6E4E60@AM4PR0701MB2162.eurprd07.prod.outlook.com
State New
Headers show

Commit Message

Bernd Edlinger Sept. 5, 2016, 9:50 p.m. UTC
Hi,

I've noticed that there is already a -Wparentheses warning for code like

  int y = x == 2 ?: 1

=> warning: the omitted middle operand in ?: will always be 'true',
suggest explicit middle operand [-Wparentheses]

But it is not emitted for code that uses bool, like:

void foo(bool x)
{
   int y = x ?: 1;

and under C it is not emitted for compound expressions
that end with a comparison, like:

   int y = (i++,i==1) ?: 1;

C++ is OK, but does only miss to warn on the bool data type.

The attached patch should fix these warnings.


Bootstrap and reg-testing is still running,
Is it OK for trunk after reg-testing?



Thanks
Bernd.
diff mbox

Patch

gcc/c-family:
2016-09-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c-common.c (warn_for_omitted_condop): Also warn for boolean data.

gcc/c:
2016-09-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c-parser.c (c_parser_conditional_expression): Pass the rightmost
	COMPOUND_EXPR to warn_for_omitted_condop.

testsuite:
2016-09-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c-c++-common/warn-ommitted-condop.c: Add more test cases.


Index: gcc/c/c-parser.c
===================================================================
--- gcc/c/c-parser.c	(revision 240001)
+++ gcc/c/c-parser.c	(working copy)
@@ -6423,16 +6423,20 @@  c_parser_conditional_expression (c_parser *parser,
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
       tree eptype = NULL_TREE;
+      tree e;
 
       middle_loc = c_parser_peek_token (parser)->location;
       pedwarn (middle_loc, OPT_Wpedantic, 
 	       "ISO C forbids omitting the middle term of a ?: expression");
-      warn_for_omitted_condop (middle_loc, cond.value);
       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
 	{
 	  eptype = TREE_TYPE (cond.value);
 	  cond.value = TREE_OPERAND (cond.value, 0);
 	}
+      e = cond.value;
+      while (TREE_CODE (e) == COMPOUND_EXPR)
+	e = TREE_OPERAND (e, 1);
+      warn_for_omitted_condop (middle_loc, e);
       /* Make sure first operand is calculated only once.  */
       exp1.value = c_save_expr (default_conversion (cond.value));
       if (eptype)
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 240001)
+++ gcc/c-family/c-common.c	(working copy)
@@ -10619,7 +10619,8 @@  fold_offsetof (tree expr)
 void
 warn_for_omitted_condop (location_t location, tree cond) 
 { 
-  if (truth_value_p (TREE_CODE (cond))) 
+  if (TREE_CODE (TREE_TYPE (cond)) == BOOLEAN_TYPE
+      || truth_value_p (TREE_CODE (cond))) 
       warning_at (location, OPT_Wparentheses, 
 		"the omitted middle operand in ?: will always be %<true%>, "
 		"suggest explicit middle operand");
Index: gcc/testsuite/c-c++-common/warn-ommitted-condop.c
===================================================================
--- gcc/testsuite/c-c++-common/warn-ommitted-condop.c	(revision 240001)
+++ gcc/testsuite/c-c++-common/warn-ommitted-condop.c	(working copy)
@@ -1,8 +1,12 @@ 
 /* { dg-options "-Wparentheses -ftrack-macro-expansion=0" } */
 
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
 extern void f2 (int);
 
-void bar (int x, int y, int z)
+void bar (int x, int y, int z, bool b)
 {
 #define T(op) f2 (x op y ? : 1) 
 #define T2(op) f2 (x op y ? 2 : 1) 
@@ -16,6 +20,8 @@  extern void f2 (int);
   T(||); /* { dg-warning "omitted middle operand" } */
   T(&&); /* { dg-warning "omitted middle operand" } */
   f2 (!x ? : 1);  /* { dg-warning "omitted middle operand" } */
+  f2 ((x,!x) ? : 1);  /* { dg-warning "omitted middle operand" } */
+  f2 ((x,y,!x) ? : 1);  /* { dg-warning "omitted middle operand" } */
   T2(<); /* { dg-bogus "omitted middle operand" } */
   T2(>); /* { dg-bogus "omitted middle operand" } */
   T2(==); /* { dg-bogus "omitted middle operand" } */
@@ -26,4 +32,5 @@  extern void f2 (int);
   T(*); /* { dg-bogus "omitted middle operand" } */
   T(/); /* { dg-bogus "omitted middle operand" } */
   T(^); /* { dg-bogus "omitted middle operand" } */
+  f2 (b ? : 1);  /* { dg-warning "omitted middle operand" } */
 }