OSDN Git Service

./:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jun 2009 14:24:40 +0000 (14:24 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Jun 2009 14:24:40 +0000 (14:24 +0000)
* 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.
cp/:
* 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.
testsuite/:
* g++.dg/warn/skip-1.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148535 138bc75d-0d04-0410-961f-82ee72b054a4

19 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-parser.c
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl2.c
gcc/cp/mangle.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/skip-1.C [new file with mode: 0644]

index ab1db07..6c525da 100644 (file)
@@ -1,3 +1,22 @@
+2009-06-16  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.
+
 2009-06-16  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-alias.c (is_escape_site): Remove.
 2009-06-16  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-alias.c (is_escape_site): Remove.
index 139a5d2..43b2c13 100644 (file)
@@ -442,9 +442,9 @@ tree *ridpointers;
 
 tree (*make_fname_decl) (location_t, tree, int);
 
 
 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.  */
 
 /* 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)
 {
 void
 overflow_warning (location_t loc, tree value)
 {
-  if (skip_evaluation) return;
+  if (c_inhibit_evaluation_warnings != 0)
+    return;
 
   switch (TREE_CODE (value))
     {
 
   switch (TREE_CODE (value))
     {
@@ -2225,7 +2226,9 @@ convert_and_check (tree type, tree expr)
   
   result = convert (type, 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;
     warnings_for_convert_and_check (type, expr_for_warning, result);
 
   return result;
@@ -8952,7 +8955,7 @@ warn_for_div_by_zero (location_t loc, tree divisor)
      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.  */
      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");
 }
       && (integer_zerop (divisor) || fixed_zerop (divisor)))
     warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
 }
index eecb189..04a1945 100644 (file)
@@ -719,10 +719,13 @@ extern int warn_strict_null_sentinel;
 
 extern int max_tinst_depth;
 
 
 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.  */
 
 /* Whether lexing has been completed, so subsequent preprocessor
    errors should use the compiler's input_location.  */
index 6c7b830..2b78c30 100644 (file)
@@ -2102,18 +2102,18 @@ c_parser_typeof_specifier (c_parser *parser)
   ret.expr_const_operands = true;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
   c_parser_consume_token (parser);
   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 %<(%>"))
     {
   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);
       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)
        {
       in_typeof--;
       if (type != NULL)
        {
@@ -2126,7 +2126,7 @@ c_parser_typeof_specifier (c_parser *parser)
       bool was_vm;
       location_t here = c_parser_peek_token (parser)->location;
       struct c_expr expr = c_parser_expression (parser);
       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)))
       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_parser *parser, struct c_expr *after)
        exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
       exp1.original_type = NULL;
       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
        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));
     }
   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);
       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 %<:%>"))
     {
     }
 
   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;
       ret.value = error_mark_node;
       ret.original_code = ERROR_MARK;
       ret.original_type = NULL;
@@ -4595,7 +4596,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
     exp2 = c_parser_conditional_expression (parser, NULL);
     exp2 = default_function_array_conversion (exp2_loc, exp2);
   }
     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);
   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 *parser, struct c_expr *after)
      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
      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.  */
 
   /* 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 *parser, struct c_expr *after)
     switch (stack[sp].op)                                                    \
       {                                                                              \
       case TRUTH_ANDIF_EXPR:                                                 \
     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:                                                  \
        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;                                                                \
        break;                                                                \
       default:                                                               \
        break;                                                                \
@@ -4855,7 +4858,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
                                                 stack[sp].expr);
          stack[sp].expr.value = c_objc_common_truthvalue_conversion
            (stack[sp].loc, default_conversion (stack[sp].expr.value));
                                                 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
          break;
        case TRUTH_ORIF_EXPR:
          stack[sp].expr
@@ -4863,7 +4867,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
                                                 stack[sp].expr);
          stack[sp].expr.value = c_objc_common_truthvalue_conversion
            (stack[sp].loc, default_conversion (stack[sp].expr.value));
                                                 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;
          break;
        default:
          break;
@@ -5086,7 +5091,7 @@ c_parser_sizeof_expression (c_parser *parser)
   location_t expr_loc;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
   c_parser_consume_token (parser);
   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)))
   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 *parser)
       if (type_name == NULL)
        {
          struct c_expr ret;
       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;
          in_sizeof--;
          ret.value = error_mark_node;
          ret.original_code = ERROR_MARK;
@@ -5116,7 +5121,7 @@ c_parser_sizeof_expression (c_parser *parser)
          goto sizeof_expr;
        }
       /* sizeof ( type-name ).  */
          goto sizeof_expr;
        }
       /* sizeof ( type-name ).  */
-      skip_evaluation--;
+      c_inhibit_evaluation_warnings--;
       in_sizeof--;
       return c_expr_sizeof_type (expr_loc, type_name);
     }
       in_sizeof--;
       return c_expr_sizeof_type (expr_loc, type_name);
     }
@@ -5125,7 +5130,7 @@ c_parser_sizeof_expression (c_parser *parser)
       expr_loc = c_parser_peek_token (parser)->location;
       expr = c_parser_unary_expression (parser);
     sizeof_expr:
       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)))
       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 *parser)
   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);
   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)))
   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 *parser)
       if (type_name == NULL)
        {
          struct c_expr ret;
       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;
          in_alignof--;
          ret.value = error_mark_node;
          ret.original_code = ERROR_MARK;
@@ -5175,7 +5180,7 @@ c_parser_alignof_expression (c_parser *parser)
          goto alignof_expr;
        }
       /* alignof ( type-name ).  */
          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;
       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 *parser)
       struct c_expr ret;
       expr = c_parser_unary_expression (parser);
     alignof_expr:
       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;
       in_alignof--;
       ret.value = c_alignof_expr (loc, expr.value);
       ret.original_code = ERROR_MARK;
index 0dd97d3..07d51a4 100644 (file)
@@ -2079,7 +2079,7 @@ build_indirect_ref (location_t loc, tree ptr, const char *errorstring)
              error_at (loc, "dereferencing pointer to incomplete type");
              return error_mark_node;
            }
              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,
            warning_at (loc, 0, "dereferencing %<void *%> pointer");
 
          /* We *must* set TREE_READONLY when dereferencing a pointer to const,
@@ -3864,7 +3864,7 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
         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.  */
         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));
        {
          int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1));
          int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2));
@@ -9074,7 +9074,7 @@ build_binary_op (location_t location, enum tree_code code,
              if (tree_int_cst_sgn (op1) < 0)
                {
                  int_const = false;
              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
                    warning (0, "right shift count is negative");
                }
              else
@@ -9085,7 +9085,7 @@ build_binary_op (location_t location, enum tree_code code,
                  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
                    {
                      int_const = false;
                  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");
                    }
                }
                        warning (0, "right shift count >= width of type");
                    }
                }
@@ -9111,14 +9111,14 @@ build_binary_op (location_t location, enum tree_code code,
              if (tree_int_cst_sgn (op1) < 0)
                {
                  int_const = false;
              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;
                    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");
                }
            }
                    warning (0, "left shift count >= width of type");
                }
            }
@@ -9458,7 +9458,7 @@ build_binary_op (location_t location, enum tree_code code,
          converted = 1;
          resultcode = xresultcode;
 
          converted = 1;
          resultcode = xresultcode;
 
-         if (!skip_evaluation)
+         if (c_inhibit_evaluation_warnings == 0)
            {
              bool op0_maybe_const = true;
              bool op1_maybe_const = true;
            {
              bool op0_maybe_const = true;
              bool op1_maybe_const = true;
index 911081a..3912688 100644 (file)
@@ -1,3 +1,46 @@
+2009-06-16  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.
+
 2009-06-15  Ian Lance Taylor  <iant@google.com>
 
        * parser.c (cp_parser_direct_declarator): Add braces around
 2009-06-15  Ian Lance Taylor  <iant@google.com>
 
        * parser.c (cp_parser_direct_declarator): Add braces around
index f33d645..e89d585 100644 (file)
@@ -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 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 ();
        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 94b75ca..b762019 100644 (file)
@@ -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.  */
 
   /* 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)
     {
       expr = build_nop (build_pointer_type (target_type), expr);
       if (!want_pointer)
index 4cb34f5..8c45b8a 100644 (file)
@@ -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;
   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;
 
 
   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;
 
    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
 /* in pt.c  */
 
 /* These values are used for the `STRICT' parameter to type_unification and
index 596e81c..dfd0ea8 100644 (file)
@@ -565,7 +565,9 @@ cp_convert_and_check (tree type, tree expr)
   
   result = cp_convert (type, expr);
 
   
   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;
     warnings_for_convert_and_check (type, expr, result);
 
   return result;
index 495c8e7..308f767 100644 (file)
@@ -3815,7 +3815,7 @@ mark_used (tree decl)
       return;
     }
   /* If we don't need a value, then we don't need to synthesize 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
     return;
 
   /* If within finish_function, defer the rest until that function
index c905304..f7d9d41 100644 (file)
@@ -1684,9 +1684,9 @@ write_type (tree type)
                 write_char ('t');
               else
                 write_char ('T');
                 write_char ('t');
               else
                 write_char ('T');
-             ++skip_evaluation;
+             ++cp_unevaluated_operand;
               write_expression (DECLTYPE_TYPE_EXPR (type));
               write_expression (DECLTYPE_TYPE_EXPR (type));
-             --skip_evaluation;
+             --cp_unevaluated_operand;
               write_char ('E');
               break;
 
               write_char ('E');
               break;
 
index f6b22bb..143fcf3 100644 (file)
@@ -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->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;
 
   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 ();
   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);
 }
 
   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;
   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);
 }
 
   timevar_pop (TV_NAME_LOOKUP);
 }
 
index 0314bb3..bdf3058 100644 (file)
@@ -247,6 +247,10 @@ static void cp_parser_initial_pragma
 static FILE *cp_lexer_debug_stream;
 #endif /* ENABLE_CHECKING */
 
 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.  */
 
 /* Create a new main C++ lexer, the lexer that gets tokens from the
    preprocessor.  */
 
@@ -6385,16 +6389,26 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
   cp_lexer_consume_token (parser->lexer);
   if (cp_parser_allow_gnu_extensions_p (parser)
       && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   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
   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);
 
   /* 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,
 
   /* 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.  */
   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, "%<(%>"))
 
   /* 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.  */
     }
 
   /* Go back to evaluating expressions.  */
-  --skip_evaluation;
+  --cp_unevaluated_operand;
+  --c_inhibit_evaluation_warnings;
 
   /* Restore the old message and the integral constant expression
      flags.  */
 
   /* Restore the old message and the integral constant expression
      flags.  */
@@ -18188,7 +18206,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   tree saved_qualifying_scope;
   tree saved_object_scope;
   bool saved_greater_than_is_operator_p;
   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]
 
 
   /* [temp.names]
 
@@ -18205,8 +18224,10 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   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_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))
   /* 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))
@@ -18273,7 +18294,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
   parser->scope = saved_scope;
   parser->qualifying_scope = saved_qualifying_scope;
   parser->object_scope = saved_object_scope;
   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;
 }
 
   return arguments;
 }
@@ -18507,7 +18529,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
     }
 
   /* Do not actually evaluate the expression.  */
     }
 
   /* 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))
   /* 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))
@@ -18556,7 +18579,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
     expr = make_pack_expansion (expr);
 
   /* Go back to evaluating expressions.  */
     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);
 
   /* Free the message we created.  */
   free (tmp);
index 7fe4012..5645b23 100644 (file)
@@ -5264,7 +5264,8 @@ coerce_template_parms (tree parms,
   tree inner_args;
   tree new_args;
   tree new_inner_args;
   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
 
   /* 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".  */
 
   /* 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++)
   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;
     }
        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;
 
   if (lost)
     return error_mark_node;
@@ -7553,7 +7557,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
              /* 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.  */
              /* 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);
            }
              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;
          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".  */
 
          /* 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.  */
 
          /* 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);
            }
 
              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;
        }
 
          return r;
        }
@@ -9782,13 +9790,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       {
        tree type;
 
       {
        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);
 
 
        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,
 
        type =
           finish_decltype_type (type,
@@ -10047,7 +10057,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          /* 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.  */
          /* 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);
          /* 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
        {
        }
       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);
          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), 
        }
       if (TYPE_P (op1))
        return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), 
index bacb09a..9a43863 100644 (file)
@@ -1423,7 +1423,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 {
   gcc_assert (TREE_CODE (decl) == FIELD_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.  */
     {
       /* DR 613: Can use non-static data members without an associated
          object in sizeof/decltype/alignof.  */
index 1ad7506..e3ed871 100644 (file)
@@ -2019,7 +2019,7 @@ build_class_member_access_expr (tree object, tree member,
       if (null_object_p && warn_invalid_offsetof
          && CLASSTYPE_NON_POD_P (object_type)
          && !DECL_FIELD_IS_BASE (member)
       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, 
          && (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 (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
                    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");
                }
            }
                    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 (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)
                {
                    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");
                }
            }
                    warning (0, "left shift count >= width of type");
                }
            }
index 6895978..020d8a3 100644 (file)
@@ -1,3 +1,7 @@
+2009-06-16  Ian Lance Taylor  <iant@google.com>
+
+       * g++.dg/warn/skip-1.C: New testcase.
+
 2009-06-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/40446
 2009-06-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/40446
diff --git a/gcc/testsuite/g++.dg/warn/skip-1.C b/gcc/testsuite/g++.dg/warn/skip-1.C
new file mode 100644 (file)
index 0000000..027c405
--- /dev/null
@@ -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);
+}