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]

Re: PATCH RFA: C++ frontend: Don't warn about shifts which will not be run


Jason Merrill <jason@redhat.com> writes:

> On 06/12/2009 09:01 PM, Ian Lance Taylor wrote:
>> Suppose we eliminate skip_evaluation from the C and C++ frontends, since
>> it seems to be poorly named, and replace it with "c_parsing_sizeof_arg"
>> (which would also apply to typeof and alignof; better names solicited)
>> and "c_never_executed".
>
> This makes sense to me.  For the former, the C++ standard term is
> "unevaluated operand".  I'd rather not use the word "parsing" since we
> look into these expressions during template substitution as well.

OK, here is my attempt to balance the suggestions.

In the C frontend, I renamed skip_evaluation to
c_inhibit_evaluation_warnings.  In the C++ frontend, I introduced a new
variable, cp_unevaluated_operand, and I changed the uses of
skip_evaluation in the C++ frontend to use cp_unevaluated_frontend
instead.  I then changed the C++ frontend to also set
c_inhibit_evaluation_warnings when appropriate--basically when
cp_unevaluated_operand (the old skip_evaluation) was set, plus the new
case of a known conditional operand.  Along the way I fixed a few cases
in the C++ frontend which assumed that skip_evaluation was a boolean
rather than a count.

This leaves c_inhibit_evaluation_warnings (the old skip_evaluation) as
the right thing to test in the common C/C++ frontend code.  Most C++
specific tests now test cp_unevaluated_operand, while some new ones test
c_inhibit_evaluation_warnings.

I hope this makes the variables clearer while preserving both the
differences and the similarities of the frontends.

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

Ian


gcc/ChangeLog:

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

	* c-common.c (skip_evaluation): Don't define.
	(c_inhibit_evaluation_warnings): Define global variable.
	(overflow_warning): Check c_inhibit_evaluation_warnings rather
	than skip_evaluation.
	(convert_and_check, warn_for_div_by_zero): Likewise.
	* c-common.h (skip_evaluation): Don't declare.
	(c_inhibit_evaluation_warnings): Declare.
	* c-parser.c (c_parser_typeof_specifier): Set
	c_inhibit_evaluation_warnings rather than skip_evaluation.
	(c_parser_conditional_expression): Likewise.
	(c_parser_binary_expression): Likewise.
	(c_parser_sizeof_expression): Likewise.
	(c_parser_alignof_expression): Likewise.
	* c-typeck.c (build_indirect_ref): Check
	c_inhibit_evaluation_warnings rather than skip_evaluation.
	(build_conditional_expr, build_binary_op): Likewise.

gcc/cp/ChangeLog:

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

	* parser.c (cp_unevaluated_operand): Define global variable.
	(cp_parser_question_colon_clause): Increment
	c_inhibit_evaluation_warnings when evaluating an expression which
	will never be executed.
	(cp_parser_decltype): Increment cp_unevaluated_operand and
	c_inhibit_evaluation_warnings, not skip_evaluation.
	(cp_parser_sizeof_operand): Likewise.
	(cp_parser_enclosed_template_argument_list): Save
	cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
	skip_evaluation.
	* cp-tree.h (struct saved_scope): Remove skip_evaluation field.
	Add unevaluated_operand and inhibit_evaluation_warnings fields.
	(cp_unevaluated_operand): Declare.
	* name-lookup.c (push_to_top_level): Save cp_unevaluated_operand
	and c_inhibit_evaluation_warnings rather than skip_evaluation.
	(pop_from_top_level): Restore cp_unevaluated_operand and
	c_inhibit_evaluation_warnings rather than skip_evaluation.
	* class.c (build_base_path): Check cp_unevaluated_operand rather
	than skip_evaluation.
	* typeck.c (build_class_member_access_expr): Likewise.
	(cp_build_binary_op): Don't warn about bad shift counts if
	c_inhibit_evaluation_warnings is non-zero.
	* pt.c (coerce_template_parms): Save state of
	cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
	skip_evaluation.
	(tsubst_aggr_type): Likewise.
	(tsubst_pack_expansion): Check cp_unevaluated_operand rather than
	skip_evaluation.
	(tsubst_copy): Likewise.
	(tsubst): Set cp_unevaluated_operand and
	c_inhibit_evaluation_warnings, not skip_evaluation.
	(tsubst_copy_and_build): Likewise.
	* call.c (convert_arg_to_ellipsis): Check cp_unevaluated_operand
	rather than skip_evaluation.
	* decl2.c (mark_used): Likewise.
	* semantics.c (finish_non_static_data_member): Likewise.
	* cvt.c (cp_convert_and_check): Check
	c_inhibit_evaluation_warnings rather than skip_evaluation.
	* mangle.c (write_type): Set cp_unevaluated_operand rather than
	skip_evaluation.

gcc/testsuite/ChangeLog:

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

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


Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 148507)
+++ cp/typeck.c	(working copy)
@@ -2019,7 +2019,7 @@ build_class_member_access_expr (tree obj
       if (null_object_p && warn_invalid_offsetof
 	  && CLASSTYPE_NON_POD_P (object_type)
 	  && !DECL_FIELD_IS_BASE (member)
-	  && !skip_evaluation
+	  && cp_unevaluated_operand == 0
 	  && (complain & tf_warning))
 	{
 	  warning (OPT_Winvalid_offsetof, 
@@ -3559,13 +3559,15 @@ cp_build_binary_op (location_t location,
 	    {
 	      if (tree_int_cst_lt (op1, integer_zero_node))
 		{
-		  if (complain & tf_warning)
+		  if ((complain & tf_warning)
+		      && c_inhibit_evaluation_warnings == 0)
 		    warning (0, "right shift count is negative");
 		}
 	      else
 		{
 		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
-		      && (complain & tf_warning))
+		      && (complain & tf_warning)
+		      && c_inhibit_evaluation_warnings == 0)
 		    warning (0, "right shift count >= width of type");
 		}
 	    }
@@ -3586,12 +3588,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)
+		      && c_inhibit_evaluation_warnings == 0)
 		    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)
+		      && c_inhibit_evaluation_warnings == 0)
 		    warning (0, "left shift count >= width of type");
 		}
 	    }
Index: cp/class.c
===================================================================
--- cp/class.c	(revision 148507)
+++ cp/class.c	(working copy)
@@ -295,7 +295,7 @@ build_base_path (enum tree_code code,
 
   /* Don't bother with the calculations inside sizeof; they'll ICE if the
      source type is incomplete and the pointer value doesn't matter.  */
-  if (skip_evaluation)
+  if (cp_unevaluated_operand != 0)
     {
       expr = build_nop (build_pointer_type (target_type), expr);
       if (!want_pointer)
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 148507)
+++ cp/pt.c	(working copy)
@@ -5264,7 +5264,8 @@ coerce_template_parms (tree parms,
   tree inner_args;
   tree new_args;
   tree new_inner_args;
-  bool saved_skip_evaluation;
+  int saved_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings;
 
   /* When used as a boolean value, indicates whether this is a
      variadic template parameter list. Since it's an int, we can also
@@ -5322,8 +5323,10 @@ coerce_template_parms (tree parms,
 
   /* We need to evaluate the template arguments, even though this
      template-id may be nested within a "sizeof".  */
-  saved_skip_evaluation = skip_evaluation;
-  skip_evaluation = false;
+  saved_unevaluated_operand = cp_unevaluated_operand;
+  cp_unevaluated_operand = 0;
+  saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  c_inhibit_evaluation_warnings = 0;
   new_inner_args = make_tree_vec (nparms);
   new_args = add_outermost_template_args (args, new_inner_args);
   for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
@@ -5416,7 +5419,8 @@ coerce_template_parms (tree parms,
 	lost++;
       TREE_VEC_ELT (new_inner_args, arg_idx) = arg;
     }
-  skip_evaluation = saved_skip_evaluation;
+  cp_unevaluated_operand = saved_unevaluated_operand;
+  c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
   if (lost)
     return error_mark_node;
@@ -7553,7 +7557,7 @@ tsubst_pack_expansion (tree t, tree args
 	      /* This can happen for a parameter name used later in a function
 		 declaration (such as in a late-specified return type).  Just
 		 make a dummy decl, since it's only used for its type.  */
-	      gcc_assert (skip_evaluation);
+	      gcc_assert (cp_unevaluated_operand != 0);
 	      arg_pack = tsubst_decl (parm_pack, args, complain);
 	      arg_pack = make_fnparm_pack (arg_pack);
 	    }
@@ -7944,11 +7948,14 @@ tsubst_aggr_type (tree t,
 	  tree argvec;
 	  tree context;
 	  tree r;
-	  bool saved_skip_evaluation;
+	  int saved_unevaluated_operand;
+	  int saved_inhibit_evaluation_warnings;
 
 	  /* In "sizeof(X<I>)" we need to evaluate "I".  */
-	  saved_skip_evaluation = skip_evaluation;
-	  skip_evaluation = false;
+	  saved_unevaluated_operand = cp_unevaluated_operand;
+	  cp_unevaluated_operand = 0;
+	  saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+	  c_inhibit_evaluation_warnings = 0;
 
 	  /* First, determine the context for the type we are looking
 	     up.  */
@@ -7983,7 +7990,8 @@ tsubst_aggr_type (tree t,
 	      r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
 	    }
 
-	  skip_evaluation = saved_skip_evaluation;
+	  cp_unevaluated_operand = saved_unevaluated_operand;
+	  c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
 	  return r;
 	}
@@ -9782,13 +9790,15 @@ tsubst (tree t, tree args, tsubst_flags_
       {
 	tree type;
 
-	++skip_evaluation;
+	++cp_unevaluated_operand;
+	++c_inhibit_evaluation_warnings;
 
 	type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
 			    complain, in_decl,
 			    /*integral_constant_expression_p=*/false);
 
-	--skip_evaluation;
+	--cp_unevaluated_operand;
+	--c_inhibit_evaluation_warnings;
 
 	type =
           finish_decltype_type (type,
@@ -10047,7 +10057,7 @@ tsubst_copy (tree t, tree args, tsubst_f
 	  /* This can happen for a parameter name used later in a function
 	     declaration (such as in a late-specified return type).  Just
 	     make a dummy decl, since it's only used for its type.  */
-	  gcc_assert (skip_evaluation);	  
+	  gcc_assert (cp_unevaluated_operand != 0);
 	  /* We copy T because want to tsubst the PARM_DECL only,
 	     not the following PARM_DECLs that are chained to T.  */
 	  c = copy_node (t);
@@ -11407,11 +11417,13 @@ tsubst_copy_and_build (tree t,
 	}
       else
 	{
-	  ++skip_evaluation;
+	  ++cp_unevaluated_operand;
+	  ++c_inhibit_evaluation_warnings;
 	  op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
 				       /*function_p=*/false,
 				       /*integral_constant_expression_p=*/false);
-	  --skip_evaluation;
+	  --cp_unevaluated_operand;
+	  --c_inhibit_evaluation_warnings;
 	}
       if (TYPE_P (op1))
 	return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), 
Index: cp/semantics.c
===================================================================
--- cp/semantics.c	(revision 148507)
+++ cp/semantics.c	(working copy)
@@ -1423,7 +1423,7 @@ finish_non_static_data_member (tree decl
 {
   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
-  if (!object && skip_evaluation)
+  if (!object && cp_unevaluated_operand != 0)
     {
       /* DR 613: Can use non-static data members without an associated
          object in sizeof/decltype/alignof.  */
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 148507)
+++ cp/decl2.c	(working copy)
@@ -3815,7 +3815,7 @@ mark_used (tree decl)
       return;
     }
   /* If we don't need a value, then we don't need to synthesize DECL.  */
-  if (skip_evaluation)
+  if (cp_unevaluated_operand != 0)
     return;
 
   /* If within finish_function, defer the rest until that function
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 148507)
+++ cp/parser.c	(working copy)
@@ -247,6 +247,10 @@ static void cp_parser_initial_pragma
 static FILE *cp_lexer_debug_stream;
 #endif /* ENABLE_CHECKING */
 
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+   sizeof, typeof, or alignof.  */
+int cp_unevaluated_operand;
+
 /* Create a new main C++ lexer, the lexer that gets tokens from the
    preprocessor.  */
 
@@ -6385,16 +6389,26 @@ 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;
+      c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
+    }
   else
-    /* Parse the expression.  */
-    expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+    {
+      /* Parse the expression.  */
+      c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node;
+      expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+      c_inhibit_evaluation_warnings +=
+	((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);
+  c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node;
 
   /* Build the conditional-expression.  */
   return build_x_conditional_expr (logical_or_expr,
@@ -8857,7 +8871,10 @@ cp_parser_decltype (cp_parser *parser)
   parser->integral_constant_expression_p = false;
 
   /* Do not actually evaluate the expression.  */
-  ++skip_evaluation;
+  ++cp_unevaluated_operand;
+
+  /* Do not warn about problems with the expression.  */
+  ++c_inhibit_evaluation_warnings;
 
   /* Parse the opening `('.  */
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
@@ -8961,7 +8978,8 @@ cp_parser_decltype (cp_parser *parser)
     }
 
   /* Go back to evaluating expressions.  */
-  --skip_evaluation;
+  --cp_unevaluated_operand;
+  --c_inhibit_evaluation_warnings;
 
   /* Restore the old message and the integral constant expression
      flags.  */
@@ -18186,7 +18204,8 @@ cp_parser_enclosed_template_argument_lis
   tree saved_qualifying_scope;
   tree saved_object_scope;
   bool saved_greater_than_is_operator_p;
-  bool saved_skip_evaluation;
+  int saved_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings;
 
   /* [temp.names]
 
@@ -18203,8 +18222,10 @@ cp_parser_enclosed_template_argument_lis
   saved_object_scope = parser->object_scope;
   /* We need to evaluate the template arguments, even though this
      template-id may be nested within a "sizeof".  */
-  saved_skip_evaluation = skip_evaluation;
-  skip_evaluation = false;
+  saved_unevaluated_operand = cp_unevaluated_operand;
+  cp_unevaluated_operand = 0;
+  saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  c_inhibit_evaluation_warnings = 0;
   /* Parse the template-argument-list itself.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
       || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
@@ -18271,7 +18292,8 @@ cp_parser_enclosed_template_argument_lis
   parser->scope = saved_scope;
   parser->qualifying_scope = saved_qualifying_scope;
   parser->object_scope = saved_object_scope;
-  skip_evaluation = saved_skip_evaluation;
+  cp_unevaluated_operand = saved_unevaluated_operand;
+  c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
 
   return arguments;
 }
@@ -18505,7 +18527,8 @@ cp_parser_sizeof_operand (cp_parser* par
     }
 
   /* Do not actually evaluate the expression.  */
-  ++skip_evaluation;
+  ++cp_unevaluated_operand;
+  ++c_inhibit_evaluation_warnings;
   /* If it's a `(', then we might be looking at the type-id
      construction.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -18554,7 +18577,8 @@ cp_parser_sizeof_operand (cp_parser* par
     expr = make_pack_expansion (expr);
 
   /* Go back to evaluating expressions.  */
-  --skip_evaluation;
+  --cp_unevaluated_operand;
+  --c_inhibit_evaluation_warnings;
 
   /* Free the message we created.  */
   free (tmp);
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 148507)
+++ cp/call.c	(working copy)
@@ -5064,7 +5064,7 @@ convert_arg_to_ellipsis (tree arg)
 	 If the call appears in the context of a sizeof expression,
 	 there is no need to emit a warning, since the expression won't be
 	 evaluated. We keep the builtin_trap just as a safety check.  */
-      if (!skip_evaluation)
+      if (cp_unevaluated_operand == 0)
 	warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; "
 		 "call will abort at runtime", TREE_TYPE (arg));
       arg = call_builtin_trap ();
Index: cp/cvt.c
===================================================================
--- cp/cvt.c	(revision 148507)
+++ cp/cvt.c	(working copy)
@@ -565,7 +565,9 @@ cp_convert_and_check (tree type, tree ex
   
   result = cp_convert (type, expr);
 
-  if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
+  if (c_inhibit_evaluation_warnings == 0
+      && !TREE_OVERFLOW_P (expr)
+      && result != error_mark_node)
     warnings_for_convert_and_check (type, expr, result);
 
   return result;
Index: cp/mangle.c
===================================================================
--- cp/mangle.c	(revision 148507)
+++ cp/mangle.c	(working copy)
@@ -1684,9 +1684,9 @@ write_type (tree type)
                 write_char ('t');
               else
                 write_char ('T');
-	      ++skip_evaluation;
+	      ++cp_unevaluated_operand;
               write_expression (DECLTYPE_TYPE_EXPR (type));
-	      --skip_evaluation;
+	      --cp_unevaluated_operand;
               write_char ('E');
               break;
 
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 148507)
+++ cp/cp-tree.h	(working copy)
@@ -755,7 +755,9 @@ struct GTY(()) saved_scope {
   int x_processing_specialization;
   BOOL_BITFIELD x_processing_explicit_instantiation : 1;
   BOOL_BITFIELD need_pop_function_context : 1;
-  BOOL_BITFIELD skip_evaluation : 1;
+
+  int unevaluated_operand;
+  int inhibit_evaluation_warnings;
 
   struct stmt_tree_s x_stmt_tree;
 
@@ -3621,6 +3623,14 @@ extern GTY(()) tree integer_three_node;
    function, two inside the body of a function in a local class, etc.)  */
 extern int function_depth;
 
+/* In parser.c.  */
+
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+   sizeof, typeof, or alignof.  This is a count since operands to
+   sizeof can be nested.  */
+
+extern int cp_unevaluated_operand;
+
 /* in pt.c  */
 
 /* These values are used for the `STRICT' parameter to type_unification and
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 148507)
+++ cp/name-lookup.c	(working copy)
@@ -5319,7 +5319,8 @@ push_to_top_level (void)
   s->bindings = b;
   s->need_pop_function_context = need_pop;
   s->function_decl = current_function_decl;
-  s->skip_evaluation = skip_evaluation;
+  s->unevaluated_operand = cp_unevaluated_operand;
+  s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
 
   scope_chain = s;
   current_function_decl = NULL_TREE;
@@ -5327,7 +5328,8 @@ push_to_top_level (void)
   current_lang_name = lang_name_cplusplus;
   current_namespace = global_namespace;
   push_class_stack ();
-  skip_evaluation = 0;
+  cp_unevaluated_operand = 0;
+  c_inhibit_evaluation_warnings = 0;
   timevar_pop (TV_NAME_LOOKUP);
 }
 
@@ -5360,7 +5362,8 @@ pop_from_top_level (void)
   if (s->need_pop_function_context)
     pop_function_context ();
   current_function_decl = s->function_decl;
-  skip_evaluation = s->skip_evaluation;
+  cp_unevaluated_operand = s->unevaluated_operand;
+  c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
   timevar_pop (TV_NAME_LOOKUP);
 }
 
Index: c-typeck.c
===================================================================
--- c-typeck.c	(revision 148507)
+++ c-typeck.c	(working copy)
@@ -2082,7 +2082,7 @@ build_indirect_ref (location_t loc, tree
 	      error_at (loc, "dereferencing pointer to incomplete type");
 	      return error_mark_node;
 	    }
-	  if (VOID_TYPE_P (t) && skip_evaluation == 0)
+	  if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0)
 	    warning_at (loc, 0, "dereferencing %<void *%> pointer");
 
 	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
@@ -3867,7 +3867,7 @@ build_conditional_expr (location_t colon
 	 and later code won't know it used to be different.
 	 Do this check on the original types, so that explicit casts
 	 will be considered, but default promotions won't.  */
-      if (!skip_evaluation)
+      if (c_inhibit_evaluation_warnings == 0)
 	{
 	  int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1));
 	  int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2));
@@ -9252,7 +9252,7 @@ build_binary_op (location_t location, en
 	      if (tree_int_cst_sgn (op1) < 0)
 		{
 		  int_const = false;
-		  if (skip_evaluation == 0)
+		  if (c_inhibit_evaluation_warnings == 0)
 		    warning (0, "right shift count is negative");
 		}
 	      else
@@ -9263,7 +9263,7 @@ build_binary_op (location_t location, en
 		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
 		    {
 		      int_const = false;
-		      if (skip_evaluation == 0)
+		      if (c_inhibit_evaluation_warnings == 0)
 			warning (0, "right shift count >= width of type");
 		    }
 		}
@@ -9289,14 +9289,14 @@ build_binary_op (location_t location, en
 	      if (tree_int_cst_sgn (op1) < 0)
 		{
 		  int_const = false;
-		  if (skip_evaluation == 0)
+		  if (c_inhibit_evaluation_warnings == 0)
 		    warning (0, "left shift count is negative");
 		}
 
 	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
 		{
 		  int_const = false;
-		  if (skip_evaluation == 0)
+		  if (c_inhibit_evaluation_warnings == 0)
 		    warning (0, "left shift count >= width of type");
 		}
 	    }
@@ -9636,7 +9636,7 @@ build_binary_op (location_t location, en
 	  converted = 1;
 	  resultcode = xresultcode;
 
-	  if (!skip_evaluation)
+	  if (c_inhibit_evaluation_warnings == 0)
 	    {
 	      bool op0_maybe_const = true;
 	      bool op1_maybe_const = true;
Index: c-common.c
===================================================================
--- c-common.c	(revision 148507)
+++ c-common.c	(working copy)
@@ -442,9 +442,9 @@ tree *ridpointers;
 
 tree (*make_fname_decl) (location_t, tree, int);
 
-/* Nonzero means the expression being parsed will never be evaluated.
-   This is a count, since unevaluated expressions can nest.  */
-int skip_evaluation;
+/* Nonzero means don't warn about problems that occur when the code is
+   executed.  */
+int c_inhibit_evaluation_warnings;
 
 /* Whether lexing has been completed, so subsequent preprocessor
    errors should use the compiler's input_location.  */
@@ -1507,7 +1507,8 @@ constant_expression_error (tree value)
 void
 overflow_warning (location_t loc, tree value)
 {
-  if (skip_evaluation) return;
+  if (c_inhibit_evaluation_warnings != 0)
+    return;
 
   switch (TREE_CODE (value))
     {
@@ -2225,7 +2226,9 @@ convert_and_check (tree type, tree expr)
   
   result = convert (type, expr);
 
-  if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
+  if (c_inhibit_evaluation_warnings == 0
+      && !TREE_OVERFLOW_P (expr)
+      && result != error_mark_node)
     warnings_for_convert_and_check (type, expr_for_warning, result);
 
   return result;
@@ -8952,7 +8955,7 @@ warn_for_div_by_zero (location_t loc, tr
      about division by zero.  Do not issue a warning if DIVISOR has a
      floating-point type, since we consider 0.0/0.0 a valid way of
      generating a NaN.  */
-  if (skip_evaluation == 0
+  if (c_inhibit_evaluation_warnings == 0
       && (integer_zerop (divisor) || fixed_zerop (divisor)))
     warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
 }
Index: c-common.h
===================================================================
--- c-common.h	(revision 148507)
+++ c-common.h	(working copy)
@@ -719,10 +719,13 @@ extern int warn_strict_null_sentinel;
 
 extern int max_tinst_depth;
 
-/* Nonzero means the expression being parsed will never be evaluated.
-   This is a count, since unevaluated expressions can nest.  */
+/* Nonzero means that we should not issue warnings about problems that
+   occur when the code is executed, because the code being processed
+   is not expected to be executed.  This is set during parsing.  This
+   is used for cases like sizeof() and "0 ? a : b".  This is a count,
+   not a bool, because unexecuted expressions can nest.  */
 
-extern int skip_evaluation;
+extern int c_inhibit_evaluation_warnings;
 
 /* Whether lexing has been completed, so subsequent preprocessor
    errors should use the compiler's input_location.  */
Index: c-parser.c
===================================================================
--- c-parser.c	(revision 148507)
+++ c-parser.c	(working copy)
@@ -2102,18 +2102,18 @@ c_parser_typeof_specifier (c_parser *par
   ret.expr_const_operands = true;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
   c_parser_consume_token (parser);
-  skip_evaluation++;
+  c_inhibit_evaluation_warnings++;
   in_typeof++;
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_typeof--;
       return ret;
     }
   if (c_parser_next_token_starts_typename (parser))
     {
       struct c_type_name *type = c_parser_type_name (parser);
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_typeof--;
       if (type != NULL)
 	{
@@ -2126,7 +2126,7 @@ c_parser_typeof_specifier (c_parser *par
       bool was_vm;
       location_t here = c_parser_peek_token (parser)->location;
       struct c_expr expr = c_parser_expression (parser);
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_typeof--;
       if (TREE_CODE (expr.value) == COMPONENT_REF
 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
@@ -4568,23 +4568,24 @@ c_parser_conditional_expression (c_parse
 	exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
       exp1.original_type = NULL;
       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
-      skip_evaluation += cond.value == truthvalue_true_node;
+      c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
     }
   else
     {
       cond.value
 	= c_objc_common_truthvalue_conversion
 	(cond_loc, default_conversion (cond.value));
-      skip_evaluation += cond.value == truthvalue_false_node;
+      c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
       exp1 = c_parser_expression_conv (parser);
-      skip_evaluation += ((cond.value == truthvalue_true_node)
-			  - (cond.value == truthvalue_false_node));
+      c_inhibit_evaluation_warnings +=
+	((cond.value == truthvalue_true_node)
+	 - (cond.value == truthvalue_false_node));
     }
 
   colon_loc = c_parser_peek_token (parser)->location;
   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
     {
-      skip_evaluation -= cond.value == truthvalue_true_node;
+      c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
       ret.value = error_mark_node;
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
@@ -4595,7 +4596,7 @@ c_parser_conditional_expression (c_parse
     exp2 = c_parser_conditional_expression (parser, NULL);
     exp2 = default_function_array_conversion (exp2_loc, exp2);
   }
-  skip_evaluation -= cond.value == truthvalue_true_node;
+  c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
   ret.value = build_conditional_expr (colon_loc, cond.value,
 				      cond.original_code == C_MAYBE_CONST_EXPR,
 				      exp1.value, exp2.value);
@@ -4696,8 +4697,8 @@ c_parser_binary_expression (c_parser *pa
      the stack has lower precedence than the new operator or there is
      only one element on the stack; then the top expression is the LHS
      of the new operator.  In the case of logical AND and OR
-     expressions, we also need to adjust skip_evaluation as
-     appropriate when the operators are pushed and popped.  */
+     expressions, we also need to adjust c_inhibit_evaluation_warnings
+     as appropriate when the operators are pushed and popped.  */
 
   /* The precedence levels, where 0 is a dummy lowest level used for
      the bottom of the stack.  */
@@ -4734,10 +4735,12 @@ c_parser_binary_expression (c_parser *pa
     switch (stack[sp].op)						      \
       {									      \
       case TRUTH_ANDIF_EXPR:						      \
-	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \
+	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
+					  == truthvalue_false_node);	      \
 	break;								      \
       case TRUTH_ORIF_EXPR:						      \
-	skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node;  \
+	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
+					  == truthvalue_true_node);	      \
 	break;								      \
       default:								      \
 	break;								      \
@@ -4855,7 +4858,8 @@ c_parser_binary_expression (c_parser *pa
 						 stack[sp].expr);
 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
-	  skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
+	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
+					    == truthvalue_false_node);
 	  break;
 	case TRUTH_ORIF_EXPR:
 	  stack[sp].expr
@@ -4863,7 +4867,8 @@ c_parser_binary_expression (c_parser *pa
 						 stack[sp].expr);
 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
-	  skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
+	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
+					    == truthvalue_true_node);
 	  break;
 	default:
 	  break;
@@ -5086,7 +5091,7 @@ c_parser_sizeof_expression (c_parser *pa
   location_t expr_loc;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
   c_parser_consume_token (parser);
-  skip_evaluation++;
+  c_inhibit_evaluation_warnings++;
   in_sizeof++;
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
@@ -5101,7 +5106,7 @@ c_parser_sizeof_expression (c_parser *pa
       if (type_name == NULL)
 	{
 	  struct c_expr ret;
-	  skip_evaluation--;
+	  c_inhibit_evaluation_warnings--;
 	  in_sizeof--;
 	  ret.value = error_mark_node;
 	  ret.original_code = ERROR_MARK;
@@ -5116,7 +5121,7 @@ c_parser_sizeof_expression (c_parser *pa
 	  goto sizeof_expr;
 	}
       /* sizeof ( type-name ).  */
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_sizeof--;
       return c_expr_sizeof_type (expr_loc, type_name);
     }
@@ -5125,7 +5130,7 @@ c_parser_sizeof_expression (c_parser *pa
       expr_loc = c_parser_peek_token (parser)->location;
       expr = c_parser_unary_expression (parser);
     sizeof_expr:
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_sizeof--;
       if (TREE_CODE (expr.value) == COMPONENT_REF
 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
@@ -5143,7 +5148,7 @@ c_parser_alignof_expression (c_parser *p
   location_t loc = c_parser_peek_token (parser)->location;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
   c_parser_consume_token (parser);
-  skip_evaluation++;
+  c_inhibit_evaluation_warnings++;
   in_alignof++;
   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
@@ -5160,7 +5165,7 @@ c_parser_alignof_expression (c_parser *p
       if (type_name == NULL)
 	{
 	  struct c_expr ret;
-	  skip_evaluation--;
+	  c_inhibit_evaluation_warnings--;
 	  in_alignof--;
 	  ret.value = error_mark_node;
 	  ret.original_code = ERROR_MARK;
@@ -5175,7 +5180,7 @@ c_parser_alignof_expression (c_parser *p
 	  goto alignof_expr;
 	}
       /* alignof ( type-name ).  */
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_alignof--;
       ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
       ret.original_code = ERROR_MARK;
@@ -5187,7 +5192,7 @@ c_parser_alignof_expression (c_parser *p
       struct c_expr ret;
       expr = c_parser_unary_expression (parser);
     alignof_expr:
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_alignof--;
       ret.value = c_alignof_expr (loc, expr.value);
       ret.original_code = ERROR_MARK;
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]