* 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
+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.
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. */
void
overflow_warning (location_t loc, tree value)
{
- if (skip_evaluation) return;
+ if (c_inhibit_evaluation_warnings != 0)
+ return;
switch (TREE_CODE (value))
{
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;
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");
}
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. */
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)
{
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)))
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;
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);
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. */
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; \
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
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;
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)))
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;
goto sizeof_expr;
}
/* sizeof ( type-name ). */
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
return c_expr_sizeof_type (expr_loc, type_name);
}
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)))
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)))
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;
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;
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;
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,
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));
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
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");
}
}
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");
}
}
converted = 1;
resultcode = xresultcode;
- if (!skip_evaluation)
+ if (c_inhibit_evaluation_warnings == 0)
{
bool op0_maybe_const = true;
bool op1_maybe_const = true;
+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
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 ();
/* 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)
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;
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
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;
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
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;
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;
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);
}
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);
}
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. */
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,
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, "%<(%>"))
}
/* Go back to evaluating expressions. */
- --skip_evaluation;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
/* Restore the old message and the integral constant expression
flags. */
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]
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))
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;
}
}
/* 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))
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);
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
/* 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++)
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;
/* 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);
}
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. */
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;
}
{
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,
/* 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);
}
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),
{
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. */
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,
{
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");
}
}
{
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");
}
}
+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
--- /dev/null
+// { 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);
+}