diff options
author | Ian Lance Taylor <iant@google.com> | 2009-06-16 14:24:40 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-06-16 14:24:40 +0000 |
commit | 7d882b8356b9ee3e6844bf4898a996289223fab2 (patch) | |
tree | 7a42ffff9a8ca843cf87a59b7858690a5f169948 | |
parent | 2e4078422e64a42224ca69daa70604885698a942 (diff) | |
download | gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.zip gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.tar.gz gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.tar.bz2 |
c-common.c (skip_evaluation): Don't define.
./: * 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.
From-SVN: r148535
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/c-common.c | 15 | ||||
-rw-r--r-- | gcc/c-common.h | 9 | ||||
-rw-r--r-- | gcc/c-parser.c | 53 | ||||
-rw-r--r-- | gcc/c-typeck.c | 14 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 43 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 12 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 4 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 9 | ||||
-rw-r--r-- | gcc/cp/parser.c | 48 | ||||
-rw-r--r-- | gcc/cp/pt.c | 40 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/skip-1.C | 17 |
19 files changed, 231 insertions, 82 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab1db07..6c525da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/c-common.c b/gcc/c-common.c index 139a5d2..43b2c13 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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, 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. */ - 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"); } diff --git a/gcc/c-common.h b/gcc/c-common.h index eecb189..04a1945 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -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. */ diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 6c7b830..2b78c30 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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); - 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 *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))) @@ -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); - 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_parser *parser, struct c_expr *after) 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 *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 - 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 *parser, struct c_expr *after) 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 *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)); - 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 *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)); - 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 *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))) @@ -5101,7 +5106,7 @@ c_parser_sizeof_expression (c_parser *parser) 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 *parser) 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 *parser) 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 *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))) @@ -5160,7 +5165,7 @@ c_parser_alignof_expression (c_parser *parser) 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 *parser) 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 *parser) 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; diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 0dd97d3..07d51a4 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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; } - 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, @@ -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. */ - 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)); @@ -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 (skip_evaluation == 0) + if (c_inhibit_evaluation_warnings == 0) 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 (skip_evaluation == 0) + if (c_inhibit_evaluation_warnings == 0) 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 (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"); } } @@ -9458,7 +9458,7 @@ build_binary_op (location_t location, enum tree_code code, converted = 1; resultcode = xresultcode; - if (!skip_evaluation) + if (c_inhibit_evaluation_warnings == 0) { bool op0_maybe_const = true; bool op1_maybe_const = true; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 911081a..3912688 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f33d645..e89d585 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 (); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 94b75ca..b762019 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4cb34f5..8c45b8a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 596e81c..dfd0ea8 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -565,7 +565,9 @@ cp_convert_and_check (tree type, tree 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; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 495c8e7..308f767 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c905304..f7d9d41 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index f6b22bb..143fcf3 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0314bb3..bdf3058 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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_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)) - /* 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. */ @@ -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; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* [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_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)) @@ -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; - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; return arguments; } @@ -18507,7 +18529,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) } /* 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)) @@ -18556,7 +18579,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) 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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7fe4012..5645b23 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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, 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. */ - 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_t complain, tree in_decl) { 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_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. */ - 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), diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bacb09a..9a43863 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1423,7 +1423,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) { 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. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1ad7506..e3ed871 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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) - && !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"); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6895978..020d8a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/warn/skip-1.C b/gcc/testsuite/g++.dg/warn/skip-1.C new file mode 100644 index 0000000..027c405 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/skip-1.C @@ -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); +} |