aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2009-06-16 14:24:40 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-06-16 14:24:40 +0000
commit7d882b8356b9ee3e6844bf4898a996289223fab2 (patch)
tree7a42ffff9a8ca843cf87a59b7858690a5f169948
parent2e4078422e64a42224ca69daa70604885698a942 (diff)
downloadgcc-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/ChangeLog19
-rw-r--r--gcc/c-common.c15
-rw-r--r--gcc/c-common.h9
-rw-r--r--gcc/c-parser.c53
-rw-r--r--gcc/c-typeck.c14
-rw-r--r--gcc/cp/ChangeLog43
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h12
-rw-r--r--gcc/cp/cvt.c4
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/mangle.c4
-rw-r--r--gcc/cp/name-lookup.c9
-rw-r--r--gcc/cp/parser.c48
-rw-r--r--gcc/cp/pt.c40
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/cp/typeck.c14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/warn/skip-1.C17
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);
+}