This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH RFA: C++: Don't warn about logical RHS never executed


This patch does two things.  First, when parsing the right hand side
of "true || x" or "false && x" c_inhibit_evaluation_warnings is set,
since x will never be executed.  Second, if
c_inhibit_evaluation_warnings is set, this disables warnings about
comparisons between signed and unsigned values.  This patch requires
approval from the C++ frontend maintainers.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for mainline?

Ian


gcc/cp/ChangeLog:

2009-06-20  Ian Lance Taylor  <iant@google.com>

	* parser.c (cp_parser_binary_expression): Increment
	c_inhibit_evaluation_warnings while parsing the right hand side of
	"true || x" or "false && x".
	* typeck.c (cp_build_binary_op): Only call warn_for_sign_compare
	if c_inhibit_evaluation_warnings is zero.

gcc/testsuite/ChangeLog:

2009-06-20  Ian Lance Taylor  <iant@google.com>

	* g++.dg/warn/skip-2.C: New testcase.


Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 148740)
+++ cp/typeck.c	(working copy)
@@ -4021,7 +4021,8 @@ cp_build_binary_op (location_t location,
 	  /* Do not warn until the template is instantiated; we cannot
 	     bound the ranges of the arguments until that point.  */
 	  && !processing_template_decl
-          && (complain & tf_warning))
+          && (complain & tf_warning)
+	  && c_inhibit_evaluation_warnings == 0)
 	{
 	  warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1, 
 				 result_type, resultcode);
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 148740)
+++ cp/parser.c	(working copy)
@@ -6287,6 +6287,13 @@ cp_parser_binary_expression (cp_parser* 
       /* We used the operator token.  */
       cp_lexer_consume_token (parser->lexer);
 
+      /* For "false && x" or "true || x", x will never be executed;
+	 disable warnings while evaluating it.  */
+      if (tree_type == TRUTH_ANDIF_EXPR)
+	c_inhibit_evaluation_warnings += lhs == truthvalue_false_node;
+      else if (tree_type == TRUTH_ORIF_EXPR)
+	c_inhibit_evaluation_warnings += lhs == truthvalue_true_node;
+
       /* Extract another operand.  It may be the RHS of this expression
 	 or the LHS of a new, higher priority expression.  */
       rhs = cp_parser_simple_cast_expression (parser);
@@ -6332,6 +6339,12 @@ cp_parser_binary_expression (cp_parser* 
 	  lhs_type = sp->lhs_type;
 	}
 
+      /* Undo the disabling of warnings done above.  */
+      if (tree_type == TRUTH_ANDIF_EXPR)
+	c_inhibit_evaluation_warnings -= lhs == truthvalue_false_node;
+      else if (tree_type == TRUTH_ORIF_EXPR)
+	c_inhibit_evaluation_warnings -= lhs == truthvalue_true_node;
+
       overloaded_p = false;
       /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
 	 ERROR_MARK for everything that is not a binary expression.
Index: testsuite/g++.dg/warn/skip-2.C
===================================================================
--- testsuite/g++.dg/warn/skip-2.C	(revision 0)
+++ testsuite/g++.dg/warn/skip-2.C	(revision 0)
@@ -0,0 +1,37 @@
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+extern int f2(int);
+extern void f3();
+void
+f1(int i)
+{
+  if (1 == 1 || f2(i >> -10))
+    f3();
+  if (1 == 1 || f2(i >> 128))
+    f3();
+  if (1 == 1 || f2(i << -10))
+    f3();
+  if (1 == 1 || f2(i << 128))
+    f3();
+  if (1 == 1 || i < 0xffffffff)
+    f3();
+  if (1 == 1 || i >= -0x80000000)
+    f3();
+  if (1 == 0 && f2(i >> -10))
+    f3();
+  if (1 == 0 && f2(i >> 128))
+    f3();
+  if (1 == 0 && f2(i << -10))
+    f3();
+  if (1 == 0 && f2(i << 128))
+    f3();
+  if (1 == 0 && i < 0xffffffff)
+    f3();
+  if (1 == 0 && i >= -0x80000000)
+    f3();
+  if (1 == 1 && f2(i >> -10))	/* { dg-warning "shift count is negative" } */
+    f3();
+  if (1 == 0 || f2(i << -10))	/* { dg-warning "shift count is negative" } */
+    f3();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]