#include "tree.h"
#include "langhooks.h"
#include "c-tree.h"
+#include "c-lang.h"
#include "tm_p.h"
#include "flags.h"
#include "output.h"
/* The level of nesting inside "typeof". */
int in_typeof;
-struct c_label_context_se *label_context_stack_se;
-struct c_label_context_vm *label_context_stack_vm;
-
/* Nonzero if we've already printed a "missing braces around initializer"
message within this initializer. */
static int missing_braces_mentioned;
static tree lookup_field (tree, tree);
static int convert_arguments (tree, VEC(tree,gc) *, VEC(tree,gc) *, tree,
tree);
-static tree pointer_diff (tree, tree);
+static tree pointer_diff (location_t, tree, tree);
static tree convert_for_assignment (location_t, tree, tree, tree,
enum impl_conv, bool, tree, tree, int);
static tree valid_compound_expr_initializer (tree, tree);
}
/* Convert in case a char is more than one unit. */
- return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
- size_int (TYPE_PRECISION (char_type_node)
- / BITS_PER_UNIT));
+ return size_binop_loc (input_location, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+ size_int (TYPE_PRECISION (char_type_node)
+ / BITS_PER_UNIT));
}
\f
/* Return either DECL or its known constant value (if it has one). */
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,
if (VOID_TYPE_P (return_type))
{
if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED)
- pedwarn (input_location, 0,
+ pedwarn (loc, 0,
"function with qualified void return type called");
return trap;
}
build_constructor (return_type, 0),
false);
else
- rhs = fold_convert (return_type, integer_zero_node);
+ rhs = fold_convert_loc (loc, return_type, integer_zero_node);
return require_complete_type (build2 (COMPOUND_EXPR, return_type,
trap, rhs));
&& !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
{
if (require_constant_value)
- result = fold_build_call_array_initializer (TREE_TYPE (fntype),
- function, nargs, argarray);
+ result =
+ fold_build_call_array_initializer_loc (loc, TREE_TYPE (fntype),
+ function, nargs, argarray);
else
- result = fold_build_call_array (TREE_TYPE (fntype),
- function, nargs, argarray);
+ result = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
+ function, nargs, argarray);
if (TREE_CODE (result) == NOP_EXPR
&& TREE_CODE (TREE_OPERAND (result, 0)) == INTEGER_CST)
STRIP_TYPE_NOPS (result);
}
else
- result = build_call_array (TREE_TYPE (fntype),
- function, nargs, argarray);
+ result = build_call_array_loc (loc, TREE_TYPE (fntype),
+ function, nargs, argarray);
if (VOID_TYPE_P (TREE_TYPE (result)))
{
if (TYPE_QUALS (TREE_TYPE (result)) != TYPE_UNQUALIFIED)
- pedwarn (input_location, 0,
+ pedwarn (loc, 0,
"function with qualified void return type called");
return result;
}
The resulting tree has type int. */
static tree
-pointer_diff (tree op0, tree op1)
+pointer_diff (location_t loc, tree op0, tree op1)
{
tree restype = ptrdiff_type_node;
tree orig_op1 = op1;
if (TREE_CODE (target_type) == VOID_TYPE)
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"pointer of type %<void *%> used in subtraction");
if (TREE_CODE (target_type) == FUNCTION_TYPE)
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"pointer to a function used in subtraction");
/* If the conversion to ptrdiff_type does anything like widening or
Do not do default conversions on the minus operator
in case restype is a short type. */
- op0 = build_binary_op (input_location,
+ op0 = build_binary_op (loc,
MINUS_EXPR, convert (restype, op0),
convert (restype, op1), 0);
/* This generates an error if op1 is pointer to incomplete type. */
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
- error ("arithmetic on pointer to an incomplete type");
+ error_at (loc, "arithmetic on pointer to an incomplete type");
/* This generates an error if op0 is pointer to incomplete type. */
op1 = c_size_in_bytes (target_type);
/* Divide by the size, in easiest possible way. */
- return fold_build2 (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
+ return fold_build2_loc (loc, EXACT_DIV_EXPR, restype,
+ op0, convert (restype, op1));
}
\f
/* Construct and perhaps optimize a tree representation
}
else if (!noconvert)
arg = default_conversion (arg);
- arg = non_lvalue (arg);
+ arg = non_lvalue_loc (location, arg);
break;
case NEGATE_EXPR:
return error_mark_node;
}
arg = c_objc_common_truthvalue_conversion (location, arg);
- ret = invert_truthvalue (arg);
+ ret = invert_truthvalue_loc (location, arg);
/* If the TRUTH_NOT_EXPR has been folded, reset the location. */
if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret))
location = EXPR_LOCATION (ret);
if (TREE_CODE (arg) == COMPLEX_CST)
ret = TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- ret = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1_loc (location,
+ REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
ret = arg;
if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE)
if (TREE_CODE (arg) == COMPLEX_CST)
ret = TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- ret = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1_loc (location,
+ IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- ret = omit_one_operand (TREE_TYPE (arg), integer_zero_node, arg);
+ ret = omit_one_operand_loc (location, TREE_TYPE (arg),
+ integer_zero_node, arg);
if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE)
eptype = TREE_TYPE (eptype);
goto return_build_unary_op;
}
inc = c_size_in_bytes (TREE_TYPE (argtype));
- inc = fold_convert (sizetype, inc);
+ inc = fold_convert_loc (location, sizetype, inc);
}
else if (FRACT_MODE_P (TYPE_MODE (argtype)))
{
{
/* Don't let this be an lvalue. */
if (lvalue_p (TREE_OPERAND (arg, 0)))
- return non_lvalue (TREE_OPERAND (arg, 0));
+ return non_lvalue_loc (location, TREE_OPERAND (arg, 0));
ret = TREE_OPERAND (arg, 0);
goto return_build_unary_op;
}
if (val && TREE_CODE (val) == INDIRECT_REF
&& TREE_CONSTANT (TREE_OPERAND (val, 0)))
{
- tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
+ tree op0 = fold_convert_loc (location, sizetype,
+ fold_offsetof (arg, val)), op1;
- op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
- ret = fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
+ op1 = fold_convert_loc (location, argtype, TREE_OPERAND (val, 0));
+ ret = fold_build2_loc (location, POINTER_PLUS_EXPR, argtype, op1, op0);
goto return_build_unary_op;
}
argtype = TREE_TYPE (arg);
if (TREE_CODE (arg) == INTEGER_CST)
ret = (require_constant_value
- ? fold_build1_initializer (code, argtype, arg)
- : fold_build1 (code, argtype, arg));
+ ? fold_build1_initializer_loc (location, code, argtype, arg)
+ : fold_build1_loc (location, code, argtype, arg));
else
ret = build1 (code, argtype, arg);
return_build_unary_op:
tree
build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
- tree op1, tree op2)
+ tree op1, tree op1_original_type, tree op2,
+ tree op2_original_type)
{
tree type1;
tree type2;
}
}
+ if (warn_cxx_compat)
+ {
+ tree t1 = op1_original_type ? op1_original_type : TREE_TYPE (orig_op1);
+ tree t2 = op2_original_type ? op2_original_type : TREE_TYPE (orig_op2);
+
+ if (TREE_CODE (t1) == ENUMERAL_TYPE
+ && TREE_CODE (t2) == ENUMERAL_TYPE
+ && TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2))
+ warning_at (colon_loc, OPT_Wc___compat,
+ ("different enum types in conditional is "
+ "invalid in C++: %qT vs %qT"),
+ t1, t2);
+ }
+
/* Quickly detect the usual case where op1 and op2 have the same type
after promotion. */
if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
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));
that folding in this case even without
warn_sign_compare to avoid warning options
possibly affecting code generation. */
+ c_inhibit_evaluation_warnings
+ += (ifexp == truthvalue_false_node);
op1 = c_fully_fold (op1, require_constant_value,
&op1_maybe_const);
+ c_inhibit_evaluation_warnings
+ -= (ifexp == truthvalue_false_node);
+
+ c_inhibit_evaluation_warnings
+ += (ifexp == truthvalue_true_node);
op2 = c_fully_fold (op2, require_constant_value,
&op2_maybe_const);
+ c_inhibit_evaluation_warnings
+ -= (ifexp == truthvalue_true_node);
if (warn_sign_compare)
{
&& !TREE_OVERFLOW (orig_op2)));
}
if (int_const || (ifexp_bcp && TREE_CODE (ifexp) == INTEGER_CST))
- ret = fold_build3 (COND_EXPR, result_type, ifexp, op1, op2);
+ ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2);
else
{
ret = build3 (COND_EXPR, result_type, ifexp, op1, op2);
/* Don't let a cast be an lvalue. */
if (value == expr)
- value = non_lvalue (value);
+ value = non_lvalue_loc (loc, value);
/* Don't allow the results of casting to floating-point or complex
types be confused with actual constants, or casts involving
pedwarn (location, OPT_pedantic,
"ISO C prohibits argument conversion to union type");
- rhs = fold_convert (TREE_TYPE (memb), rhs);
+ rhs = fold_convert_loc (location, TREE_TYPE (memb), rhs);
return build_constructor_single (type, memb, rhs);
}
}
TREE_TYPE (inside_init) = type;
if (TYPE_DOMAIN (type) != 0
&& TYPE_SIZE (type) != 0
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ {
+ unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init);
+
/* Subtract the size of a single (possibly wide) character
because it's ok to ignore the terminating null char
that is counted in the length of the constant. */
- && 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
- TREE_STRING_LENGTH (inside_init)
- - (TYPE_PRECISION (typ1)
- / BITS_PER_UNIT)))
- pedwarn_init (init_loc, 0,
- "initializer-string for array of chars is too long");
+ if (0 > compare_tree_int (TYPE_SIZE_UNIT (type),
+ (len
+ - (TYPE_PRECISION (typ1)
+ / BITS_PER_UNIT))))
+ pedwarn_init (init_loc, 0,
+ ("initializer-string for array of chars "
+ "is too long"));
+ else if (warn_cxx_compat
+ && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), len))
+ warning_at (init_loc, OPT_Wc___compat,
+ ("initializer-string for array chars "
+ "is too long for C++"));
+ }
return inside_init;
}
/* Advance the variable that indicates sequential elements output. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE)
constructor_unfilled_index
- = size_binop (PLUS_EXPR, constructor_unfilled_index,
- bitsize_one_node);
+ = size_binop_loc (input_location, PLUS_EXPR, constructor_unfilled_index,
+ bitsize_one_node);
else if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
constructor_unfilled_fields
/* For a record, keep track of end position of last field. */
if (DECL_SIZE (constructor_fields))
constructor_bit_index
- = size_binop (PLUS_EXPR,
- bit_position (constructor_fields),
- DECL_SIZE (constructor_fields));
+ = size_binop_loc (input_location, PLUS_EXPR,
+ bit_position (constructor_fields),
+ DECL_SIZE (constructor_fields));
/* If the current field was the first one not yet written out,
it isn't now, so update. */
}
constructor_index
- = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
+ = size_binop_loc (input_location, PLUS_EXPR,
+ constructor_index, bitsize_one_node);
if (!value.value)
/* If we are doing the bookkeeping for an element that was
}
constructor_index
- = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
+ = size_binop_loc (input_location,
+ PLUS_EXPR, constructor_index, bitsize_one_node);
if (!value.value)
/* If we are doing the bookkeeping for an element that was
process_init_element (pop_init_level (1), true);
}
- p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node);
+ p->index = size_binop_loc (input_location,
+ PLUS_EXPR, p->index, bitsize_one_node);
if (tree_int_cst_equal (p->index, p->range_end) && !p->prev)
finish = 1;
tree
c_finish_goto_label (location_t loc, tree label)
{
- tree decl = lookup_label (label);
+ tree decl = lookup_label_for_goto (loc, label);
if (!decl)
return NULL_TREE;
-
- if (C_DECL_UNJUMPABLE_STMT_EXPR (decl))
- {
- error_at (loc, "jump into statement expression");
- return NULL_TREE;
- }
-
- if (C_DECL_UNJUMPABLE_VM (decl))
- {
- error_at (loc,
- "jump into scope of identifier with variably modified type");
- return NULL_TREE;
- }
-
- if (!C_DECL_UNDEFINABLE_STMT_EXPR (decl))
- {
- /* No jump from outside this statement expression context, so
- record that there is a jump from within this context. */
- struct c_label_list *nlist;
- nlist = XOBNEW (&parser_obstack, struct c_label_list);
- nlist->next = label_context_stack_se->labels_used;
- nlist->label = decl;
- label_context_stack_se->labels_used = nlist;
- }
-
- if (!C_DECL_UNDEFINABLE_VM (decl))
- {
- /* No jump from outside this context context of identifiers with
- variably modified type, so record that there is a jump from
- within this context. */
- struct c_label_list *nlist;
- nlist = XOBNEW (&parser_obstack, struct c_label_list);
- nlist->next = label_context_stack_vm->labels_used;
- nlist->label = decl;
- label_context_stack_vm->labels_used = nlist;
- }
-
TREE_USED (decl) = 1;
{
tree t = build1 (GOTO_EXPR, void_type_node, decl);
of the GNU case range extension. */
splay_tree cases;
- /* Number of nested statement expressions within this switch
- statement; if nonzero, case and default labels may not
- appear. */
- unsigned int blocked_stmt_expr;
-
- /* Scope of outermost declarations of identifiers with variably
- modified type within this switch statement; if nonzero, case and
- default labels may not appear. */
- unsigned int blocked_vm;
+ /* The bindings at the point of the switch. This is used for
+ warnings crossing decls when branching to a case label. */
+ struct c_spot_bindings *bindings;
/* The next node on the stack. */
struct c_switch *next;
SET_EXPR_LOCATION (cs->switch_expr, switch_loc);
cs->orig_type = orig_type;
cs->cases = splay_tree_new (case_compare, NULL, NULL);
- cs->blocked_stmt_expr = 0;
- cs->blocked_vm = 0;
+ cs->bindings = c_get_switch_bindings ();
cs->next = c_switch_stack;
c_switch_stack = cs;
"case label is not an integer constant expression");
}
- if (c_switch_stack && !c_switch_stack->blocked_stmt_expr
- && !c_switch_stack->blocked_vm)
- {
- label = c_add_case_label (loc, c_switch_stack->cases,
- SWITCH_COND (c_switch_stack->switch_expr),
- c_switch_stack->orig_type,
- low_value, high_value);
- if (label == error_mark_node)
- label = NULL_TREE;
- }
- else if (c_switch_stack && c_switch_stack->blocked_stmt_expr)
+ if (c_switch_stack == NULL)
{
if (low_value)
- error_at (loc, "case label in statement expression not containing "
- "enclosing switch statement");
+ error_at (loc, "case label not within a switch statement");
else
- error_at (loc, "%<default%> label in statement expression not containing "
- "enclosing switch statement");
- }
- else if (c_switch_stack && c_switch_stack->blocked_vm)
- {
- if (low_value)
- error_at (loc, "case label in scope of identifier with variably "
- "modified type not containing enclosing switch statement");
- else
- error_at (loc, "%<default%> label in scope of identifier with "
- "variably modified type not containing enclosing switch "
- "statement");
+ error_at (loc, "%<default%> label not within a switch statement");
+ return NULL_TREE;
}
- else if (low_value)
- error_at (loc, "case label not within a switch statement");
- else
- error_at (loc, "%<default%> label not within a switch statement");
+ if (c_check_switch_jump_warnings (c_switch_stack->bindings,
+ EXPR_LOCATION (c_switch_stack->switch_expr),
+ loc))
+ return NULL_TREE;
+
+ label = c_add_case_label (loc, c_switch_stack->cases,
+ SWITCH_COND (c_switch_stack->switch_expr),
+ c_switch_stack->orig_type,
+ low_value, high_value);
+ if (label == error_mark_node)
+ label = NULL_TREE;
return label;
}
SWITCH_BODY (cs->switch_expr) = body;
- /* We must not be within a statement expression nested in the switch
- at this point; we might, however, be within the scope of an
- identifier with variably modified type nested in the switch. */
- gcc_assert (!cs->blocked_stmt_expr);
-
/* Emit warnings as needed. */
switch_location = EXPR_LOCATION (cs->switch_expr);
c_do_switch_warnings (cs->cases, switch_location,
/* Pop the stack. */
c_switch_stack = cs->next;
splay_tree_delete (cs->cases);
+ c_release_switch_bindings (cs->bindings);
XDELETE (cs);
}
\f
found:
if (COND_EXPR_ELSE (inner_if))
- warning (OPT_Wparentheses,
- "%Hsuggest explicit braces to avoid ambiguous %<else%>",
- &if_locus);
+ warning_at (if_locus, OPT_Wparentheses,
+ "suggest explicit braces to avoid ambiguous %<else%>");
}
stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
}
t = build_and_jump (&blab);
- exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
if (cond_is_first)
- SET_EXPR_LOCATION (exit, start_locus);
+ exit = fold_build3_loc (start_locus,
+ COND_EXPR, void_type_node, cond, exit, t);
else
- SET_EXPR_LOCATION (exit, input_location);
+ exit = fold_build3_loc (input_location,
+ COND_EXPR, void_type_node, cond, exit, t);
}
add_stmt (top);
c_begin_stmt_expr (void)
{
tree ret;
- struct c_label_context_se *nstack;
- struct c_label_list *glist;
/* We must force a BLOCK for this level so that, if it is not expanded
later, there is a way to turn off the entire subtree of blocks that
are contained in it. */
keep_next_level ();
ret = c_begin_compound_stmt (true);
- if (c_switch_stack)
- {
- c_switch_stack->blocked_stmt_expr++;
- gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
- }
- for (glist = label_context_stack_se->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 1;
- }
- nstack = XOBNEW (&parser_obstack, struct c_label_context_se);
- nstack->labels_def = NULL;
- nstack->labels_used = NULL;
- nstack->next = label_context_stack_se;
- label_context_stack_se = nstack;
+
+ c_bindings_start_stmt_expr (c_switch_stack == NULL
+ ? NULL
+ : c_switch_stack->bindings);
/* Mark the current statement list as belonging to a statement list. */
STATEMENT_LIST_STMT_EXPR (ret) = 1;
{
tree last, type, tmp, val;
tree *last_p;
- struct c_label_list *dlist, *glist, *glist_prev = NULL;
body = c_end_compound_stmt (loc, body, true);
- if (c_switch_stack)
- {
- gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
- c_switch_stack->blocked_stmt_expr--;
- }
- /* It is no longer possible to jump to labels defined within this
- statement expression. */
- for (dlist = label_context_stack_se->labels_def;
- dlist != NULL;
- dlist = dlist->next)
- {
- C_DECL_UNJUMPABLE_STMT_EXPR (dlist->label) = 1;
- }
- /* It is again possible to define labels with a goto just outside
- this statement expression. */
- for (glist = label_context_stack_se->next->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 0;
- glist_prev = glist;
- }
- if (glist_prev != NULL)
- glist_prev->next = label_context_stack_se->labels_used;
- else
- label_context_stack_se->next->labels_used
- = label_context_stack_se->labels_used;
- label_context_stack_se = label_context_stack_se->next;
+
+ c_bindings_end_stmt_expr (c_switch_stack == NULL
+ ? NULL
+ : c_switch_stack->bindings);
/* Locate the last statement in BODY. See c_end_compound_stmt
about always returning a BIND_EXPR. */
val = TREE_OPERAND (val, 0);
*last_p = build2 (MODIFY_EXPR, void_type_node, tmp, val);
- SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last));
+ SET_EXPR_LOCATION (*last_p, EXPR_LOCATION (last));
{
tree t = build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
return t;
}
}
-
-/* Begin the scope of an identifier of variably modified type, scope
- number SCOPE. Jumping from outside this scope to inside it is not
- permitted. */
-
-void
-c_begin_vm_scope (unsigned int scope)
-{
- struct c_label_context_vm *nstack;
- struct c_label_list *glist;
-
- gcc_assert (scope > 0);
-
- /* At file_scope, we don't have to do any processing. */
- if (label_context_stack_vm == NULL)
- return;
-
- if (c_switch_stack && !c_switch_stack->blocked_vm)
- c_switch_stack->blocked_vm = scope;
- for (glist = label_context_stack_vm->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_VM (glist->label) = 1;
- }
- nstack = XOBNEW (&parser_obstack, struct c_label_context_vm);
- nstack->labels_def = NULL;
- nstack->labels_used = NULL;
- nstack->scope = scope;
- nstack->next = label_context_stack_vm;
- label_context_stack_vm = nstack;
-}
-
-/* End a scope which may contain identifiers of variably modified
- type, scope number SCOPE. */
-
-void
-c_end_vm_scope (unsigned int scope)
-{
- if (label_context_stack_vm == NULL)
- return;
- if (c_switch_stack && c_switch_stack->blocked_vm == scope)
- c_switch_stack->blocked_vm = 0;
- /* We may have a number of nested scopes of identifiers with
- variably modified type, all at this depth. Pop each in turn. */
- while (label_context_stack_vm->scope == scope)
- {
- struct c_label_list *dlist, *glist, *glist_prev = NULL;
-
- /* It is no longer possible to jump to labels defined within this
- scope. */
- for (dlist = label_context_stack_vm->labels_def;
- dlist != NULL;
- dlist = dlist->next)
- {
- C_DECL_UNJUMPABLE_VM (dlist->label) = 1;
- }
- /* It is again possible to define labels with a goto just outside
- this scope. */
- for (glist = label_context_stack_vm->next->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_VM (glist->label) = 0;
- glist_prev = glist;
- }
- if (glist_prev != NULL)
- glist_prev->next = label_context_stack_vm->labels_used;
- else
- label_context_stack_vm->next->labels_used
- = label_context_stack_vm->labels_used;
- label_context_stack_vm = label_context_stack_vm->next;
- }
-}
\f
/* Begin and end compound statements. This is as simple as pushing
and popping new statement lists from the tree. */
/* Handle the pointer + int case. */
if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
- ret = pointer_int_sum (PLUS_EXPR, op0, op1);
+ ret = pointer_int_sum (location, PLUS_EXPR, op0, op1);
goto return_build_binary_op;
}
else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
{
- ret = pointer_int_sum (PLUS_EXPR, op1, op0);
+ ret = pointer_int_sum (location, PLUS_EXPR, op1, op0);
goto return_build_binary_op;
}
else
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& comp_target_types (location, type0, type1))
{
- ret = pointer_diff (op0, op1);
+ ret = pointer_diff (location, op0, op1);
goto return_build_binary_op;
}
/* Handle pointer minus int. Just like pointer plus int. */
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
- ret = pointer_int_sum (MINUS_EXPR, op0, op1);
+ ret = pointer_int_sum (location, MINUS_EXPR, op0, op1);
goto return_build_binary_op;
}
else
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;
build_conditional_expr. This requires the
"original" values to be folded, not just op0 and
op1. */
+ c_inhibit_evaluation_warnings++;
op0 = c_fully_fold (op0, require_constant_value,
&op0_maybe_const);
op1 = c_fully_fold (op1, require_constant_value,
&op1_maybe_const);
+ c_inhibit_evaluation_warnings--;
orig_op0_folded = c_fully_fold (orig_op0,
require_constant_value,
NULL);
/* Treat expressions in initializers specially as they can't trap. */
if (int_const_or_overflow)
ret = (require_constant_value
- ? fold_build2_initializer (resultcode, build_type, op0, op1)
- : fold_build2 (resultcode, build_type, op0, op1));
+ ? fold_build2_initializer_loc (location, resultcode, build_type,
+ op0, op1)
+ : fold_build2_loc (location, resultcode, build_type, op0, op1));
else
ret = build2 (resultcode, build_type, op0, op1);
if (final_type != 0)