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++ frontend: Don't warn about shifts which will not be run


This patch modifies the C++ frontend to not warn about bad shift counts
for shifts which will never be executed.  It uses the existing
skip_evaluation global variable.  It sets the variable when parsing ?:
when the condition is known to be true or false.  It only warns about
bad shift counts when skip_evaluation is zero.

This simply copies what the C frontend does into the C++ frontend.

I want to commit this to support the gcc-in-cxx effort.  It permits the
C++ frontend to compile code like this from the generated file
insn-modes.c:

#define MODE_MASK(m)                          \
  ((m) >= HOST_BITS_PER_WIDE_INT)             \
   ? ~(unsigned HOST_WIDE_INT) 0              \
   : ((unsigned HOST_WIDE_INT) 1 << (m)) - 1

This code is safe, but it currently triggers a warning from the C++
frontend.  This patch disables that warning.

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

Ian


gcc/cp/ChangeLog:

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

	* parser.c (cp_parser_question_colon_clause): Increment
	skip_evaluation when evaluating an expression which will never be
	executed.
	* typeck.c (cp_build_binary_op): Don't warn about bad shift counts
	if skip_evaluation is non-zero.

gcc/testsuite/ChangeLog:

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

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


Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 148327)
+++ cp/typeck.c	(working copy)
@@ -3557,13 +3557,14 @@ cp_build_binary_op (location_t location,
 	    {
 	      if (tree_int_cst_lt (op1, integer_zero_node))
 		{
-		  if (complain & tf_warning)
+		  if ((complain & tf_warning) && !skip_evaluation)
 		    warning (0, "right shift count is negative");
 		}
 	      else
 		{
 		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
-		      && (complain & tf_warning))
+		      && (complain & tf_warning)
+		      && !skip_evaluation)
 		    warning (0, "right shift count >= width of type");
 		}
 	    }
@@ -3584,12 +3585,12 @@ cp_build_binary_op (location_t location,
 	    {
 	      if (tree_int_cst_lt (op1, integer_zero_node))
 		{
-		  if (complain & tf_warning)
+		  if ((complain & tf_warning) && !skip_evaluation)
 		    warning (0, "left shift count is negative");
 		}
 	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
 		{
-		  if (complain & tf_warning)
+		  if ((complain & tf_warning) && !skip_evaluation)
 		    warning (0, "left shift count >= width of type");
 		}
 	    }
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 148327)
+++ cp/parser.c	(working copy)
@@ -6385,16 +6385,25 @@ cp_parser_question_colon_clause (cp_pars
   cp_lexer_consume_token (parser->lexer);
   if (cp_parser_allow_gnu_extensions_p (parser)
       && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-    /* Implicit true clause.  */
-    expr = NULL_TREE;
+    {
+      /* Implicit true clause.  */
+      expr = NULL_TREE;
+      skip_evaluation += logical_or_expr == truthvalue_true_node;
+    }
   else
-    /* Parse the expression.  */
-    expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+    {
+      /* Parse the expression.  */
+      skip_evaluation += logical_or_expr == truthvalue_false_node;
+      expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      skip_evaluation += ((logical_or_expr == truthvalue_true_node)
+			  - (logical_or_expr == truthvalue_false_node));
+    }
 
   /* The next token should be a `:'.  */
   cp_parser_require (parser, CPP_COLON, "%<:%>");
   /* Parse the assignment-expression.  */
   assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+  skip_evaluation -= logical_or_expr == truthvalue_true_node;
 
   /* Build the conditional-expression.  */
   return build_x_conditional_expr (logical_or_expr,
Index: testsuite/g++.dg/warn/skip-1.C
===================================================================
--- testsuite/g++.dg/warn/skip-1.C	(revision 0)
+++ testsuite/g++.dg/warn/skip-1.C	(revision 0)
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+// Check that we don't warn about code that will not be executed.
+extern int f2(int);
+void
+f1(int i)
+{
+  f2(1 == 1 ? 0 : f2(i >> -10));
+  f2(1 == 1 ? 0 : f2(i >> 128));
+  f2(1 == 1 ? 0 : f2(i << -10));
+  f2(1 == 1 ? 0 : f2(1 << 128));
+  f2(1 != 1 ? f2(i >> -10) : 0);
+  f2(1 != 1 ? f2(i >> 128) : 0);
+  f2(1 != 1 ? f2(i << -10) : 0);
+  f2(1 != 1 ? f2(1 << 128) : 0);
+}

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