#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "rtl.h"
#include "tree.h"
#include "langhooks.h"
#include "c-tree.h"
#include "c-lang.h"
+#include "tm_p.h"
#include "flags.h"
#include "output.h"
#include "expr.h"
#include "toplev.h"
#include "intl.h"
+#include "ggc.h"
#include "target.h"
#include "tree-iterator.h"
+#include "gimple.h"
#include "tree-flow.h"
/* Possible cases of implicit bad conversions. Used to select
static char *print_spelling (char *);
static void warning_init (int, const char *);
static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
-static void output_init_element (tree, tree, bool, tree, tree, int, bool,
- struct obstack *);
-static void output_pending_init_elements (int, struct obstack *);
-static int set_designator (int, struct obstack *);
-static void push_range_stack (tree, struct obstack *);
-static void add_pending_init (tree, tree, tree, bool, struct obstack *);
-static void set_nonincremental_init (struct obstack *);
-static void set_nonincremental_init_from_string (tree, struct obstack *);
-static tree find_init_member (tree, struct obstack *);
+static void output_init_element (tree, tree, bool, tree, tree, int, bool);
+static void output_pending_init_elements (int);
+static int set_designator (int);
+static void push_range_stack (tree);
+static void add_pending_init (tree, tree, tree, bool);
+static void set_nonincremental_init (void);
+static void set_nonincremental_init_from_string (tree);
+static tree find_init_member (tree);
static void readonly_error (tree, enum lvalue_use);
static void readonly_warning (tree, enum lvalue_use);
static int lvalue_or_else (const_tree, enum lvalue_use);
return exp;
}
\f
-/* Look up COMPONENT in a structure or union TYPE.
+/* Look up COMPONENT in a structure or union DECL.
If the component name is not found, returns NULL_TREE. Otherwise,
the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL
unions, the list steps down the chain to the component. */
static tree
-lookup_field (tree type, tree component)
+lookup_field (tree decl, tree component)
{
+ tree type = TREE_TYPE (decl);
tree field;
/* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
{
- tree anon = lookup_field (TREE_TYPE (field), component);
+ tree anon = lookup_field (field, component);
if (anon)
return tree_cons (NULL_TREE, field, anon);
&& (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
{
- tree anon = lookup_field (TREE_TYPE (field), component);
+ tree anon = lookup_field (field, component);
if (anon)
return tree_cons (NULL_TREE, field, anon);
return error_mark_node;
}
- field = lookup_field (type, component);
+ field = lookup_field (datum, component);
if (!field)
{
IMPLICIT is 1 (or 2 if the push is because of designator list). */
void
-push_init_level (int implicit, struct obstack * braced_init_obstack)
+push_init_level (int implicit)
{
struct constructor_stack *p;
tree value = NULL_TREE;
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& constructor_max_index
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
else
break;
}
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields)
- value = find_init_member (constructor_fields, braced_init_obstack);
+ value = find_init_member (constructor_fields);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
- value = find_init_member (constructor_index, braced_init_obstack);
+ value = find_init_member (constructor_index);
}
p = XNEW (struct constructor_stack);
if (!VEC_empty (constructor_elt, constructor_elements)
&& (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == ARRAY_TYPE))
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
}
if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
/* We need to split the char/wchar array into individual
characters, so that we don't have to special case it
everywhere. */
- set_nonincremental_init_from_string (value, braced_init_obstack);
+ set_nonincremental_init_from_string (value);
}
}
else
Otherwise, return a CONSTRUCTOR expression as the value. */
struct c_expr
-pop_init_level (int implicit, struct obstack * braced_init_obstack)
+pop_init_level (int implicit)
{
struct constructor_stack *p;
struct c_expr ret;
/* When we come to an explicit close brace,
pop any inner levels that didn't have explicit braces. */
while (constructor_stack->implicit)
- {
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
- }
+ process_init_element (pop_init_level (1), true);
+
gcc_assert (!constructor_range_stack);
}
/* Now output all pending elements. */
constructor_incremental = 1;
- output_pending_init_elements (1, braced_init_obstack);
+ output_pending_init_elements (1);
p = constructor_stack;
ARRAY argument is nonzero for array ranges. Returns zero for success. */
static int
-set_designator (int array, struct obstack * braced_init_obstack)
+set_designator (int array)
{
tree subtype;
enum tree_code subcode;
/* Designator list starts at the level of closest explicit
braces. */
while (constructor_stack->implicit)
- {
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
- }
+ process_init_element (pop_init_level (1), true);
constructor_designated = 1;
return 0;
}
}
constructor_designated = 1;
- push_init_level (2, braced_init_obstack);
+ push_init_level (2);
return 0;
}
NULL_TREE if there is no range designator at this level. */
static void
-push_range_stack (tree range_end, struct obstack * braced_init_obstack)
+push_range_stack (tree range_end)
{
struct constructor_range_stack *p;
- p = (struct constructor_range_stack *)
- obstack_alloc (braced_init_obstack,
- sizeof (struct constructor_range_stack));
+ p = GGC_NEW (struct constructor_range_stack);
p->prev = constructor_range_stack;
p->next = 0;
p->fields = constructor_fields;
of indices, running from FIRST through LAST. */
void
-set_init_index (tree first, tree last,
- struct obstack * braced_init_obstack)
+set_init_index (tree first, tree last)
{
- if (set_designator (1, braced_init_obstack))
+ if (set_designator (1))
return;
designator_erroneous = 1;
designator_depth++;
designator_erroneous = 0;
if (constructor_range_stack || last)
- push_range_stack (last, braced_init_obstack);
+ push_range_stack (last);
}
}
/* Within a struct initializer, specify the next field to be initialized. */
void
-set_init_label (tree fieldname, struct obstack * braced_init_obstack)
+set_init_label (tree fieldname)
{
- tree field;
+ tree tail;
- if (set_designator (0, braced_init_obstack))
+ if (set_designator (0))
return;
designator_erroneous = 1;
return;
}
- field = lookup_field (constructor_type, fieldname);
+ for (tail = TYPE_FIELDS (constructor_type); tail;
+ tail = TREE_CHAIN (tail))
+ {
+ if (DECL_NAME (tail) == fieldname)
+ break;
+ }
- if (field == 0)
+ if (tail == 0)
error ("unknown field %qE specified in initializer", fieldname);
else
- do
- {
- constructor_fields = TREE_VALUE (field);
- designator_depth++;
- designator_erroneous = 0;
- if (constructor_range_stack)
- push_range_stack (NULL_TREE, braced_init_obstack);
- field = TREE_CHAIN (field);
- if (field)
- {
- if (set_designator (0, braced_init_obstack))
- return;
- }
- }
- while (field != NULL_TREE);
+ {
+ constructor_fields = tail;
+ designator_depth++;
+ designator_erroneous = 0;
+ if (constructor_range_stack)
+ push_range_stack (NULL_TREE);
+ }
}
\f
/* Add a new initializer to the tree of pending initializers. PURPOSE
existing initializer. */
static void
-add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
- struct obstack * braced_init_obstack)
+add_pending_init (tree purpose, tree value, tree origtype, bool implicit)
{
struct init_node *p, **q, *r;
}
}
- r = (struct init_node *) obstack_alloc (braced_init_obstack,
- sizeof (struct init_node));
+ r = GGC_NEW (struct init_node);
r->purpose = purpose;
r->value = value;
r->origtype = origtype;
/* Build AVL tree from a sorted chain. */
static void
-set_nonincremental_init (struct obstack * braced_init_obstack)
+set_nonincremental_init (void)
{
unsigned HOST_WIDE_INT ix;
tree index, value;
return;
FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
- {
- add_pending_init (index, value, NULL_TREE, false,
- braced_init_obstack);
- }
+ add_pending_init (index, value, NULL_TREE, false);
constructor_elements = 0;
if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
/* Build AVL tree from a string constant. */
static void
-set_nonincremental_init_from_string (tree str,
- struct obstack * braced_init_obstack)
+set_nonincremental_init_from_string (tree str)
{
tree value, purpose, type;
HOST_WIDE_INT val[2];
}
value = build_int_cst_wide (type, val[1], val[0]);
- add_pending_init (purpose, value, NULL_TREE, false,
- braced_init_obstack);
+ add_pending_init (purpose, value, NULL_TREE, false);
}
constructor_incremental = 0;
not initialized yet. */
static tree
-find_init_member (tree field, struct obstack * braced_init_obstack)
+find_init_member (tree field)
{
struct init_node *p;
{
if (constructor_incremental
&& tree_int_cst_lt (field, constructor_unfilled_index))
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
p = constructor_pending_elts;
while (p)
&& (!constructor_unfilled_fields
|| tree_int_cst_lt (bitpos,
bit_position (constructor_unfilled_fields))))
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
p = constructor_pending_elts;
while (p)
static void
output_init_element (tree value, tree origtype, bool strict_string, tree type,
- tree field, int pending, bool implicit,
- struct obstack * braced_init_obstack)
+ tree field, int pending, bool implicit)
{
tree semantic_type = NULL_TREE;
constructor_elt *celt;
{
if (constructor_incremental
&& tree_int_cst_lt (field, constructor_unfilled_index))
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
- add_pending_init (field, value, origtype, implicit,
- braced_init_obstack);
+ add_pending_init (field, value, origtype, implicit);
return;
}
else if (TREE_CODE (constructor_type) == RECORD_TYPE
if (constructor_incremental)
{
if (!constructor_unfilled_fields)
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
else
{
tree bitpos, unfillpos;
unfillpos = bit_position (constructor_unfilled_fields);
if (tree_int_cst_lt (bitpos, unfillpos))
- set_nonincremental_init (braced_init_obstack);
+ set_nonincremental_init ();
}
}
- add_pending_init (field, value, origtype, implicit,
- braced_init_obstack);
+ add_pending_init (field, value, origtype, implicit);
return;
}
else if (TREE_CODE (constructor_type) == UNION_TYPE
/* Now output any pending elements which have become next. */
if (pending)
- output_pending_init_elements (0, braced_init_obstack);
+ output_pending_init_elements (0);
}
/* Output any pending elements which have become next.
If ALL is 1, we output space as necessary so that
we can output all the pending elements. */
+
static void
-output_pending_init_elements (int all, struct obstack * braced_init_obstack)
+output_pending_init_elements (int all)
{
struct init_node *elt = constructor_pending_elts;
tree next;
constructor_unfilled_index))
output_init_element (elt->value, elt->origtype, true,
TREE_TYPE (constructor_type),
- constructor_unfilled_index, 0, false,
- braced_init_obstack);
+ constructor_unfilled_index, 0, false);
else if (tree_int_cst_lt (constructor_unfilled_index,
elt->purpose))
{
constructor_unfilled_fields = elt->purpose;
output_init_element (elt->value, elt->origtype, true,
TREE_TYPE (elt->purpose),
- elt->purpose, 0, false,
- braced_init_obstack);
+ elt->purpose, 0, false);
}
else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
{
existing initializer. */
void
-process_init_element (struct c_expr value, bool implicit,
- struct obstack * braced_init_obstack)
+process_init_element (struct c_expr value, bool implicit)
{
tree orig_value = value.value;
int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
|| TREE_CODE (constructor_type) == VECTOR_TYPE)
&& (constructor_max_index == 0
|| tree_int_cst_lt (constructor_max_index,
constructor_index)))
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
else
break;
}
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|| fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
{
- push_init_level (1, braced_init_obstack);
+ push_init_level (1);
continue;
}
push_member_name (constructor_fields);
output_init_element (value.value, value.original_type,
strict_string, fieldtype,
- constructor_fields, 1, implicit,
- braced_init_obstack);
+ constructor_fields, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
else
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|| fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
{
- push_init_level (1, braced_init_obstack);
+ push_init_level (1);
continue;
}
push_member_name (constructor_fields);
output_init_element (value.value, value.original_type,
strict_string, fieldtype,
- constructor_fields, 1, implicit,
- braced_init_obstack);
+ constructor_fields, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
else
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
|| eltcode == UNION_TYPE || eltcode == VECTOR_TYPE))
{
- push_init_level (1, braced_init_obstack);
+ push_init_level (1);
continue;
}
push_array_bounds (tree_low_cst (constructor_index, 1));
output_init_element (value.value, value.original_type,
strict_string, elttype,
- constructor_index, 1, implicit,
- braced_init_obstack);
+ constructor_index, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
elttype = TYPE_MAIN_VARIANT (constructor_type);
output_init_element (value.value, value.original_type,
strict_string, elttype,
- constructor_index, 1, implicit,
- braced_init_obstack);
+ constructor_index, 1, implicit);
}
constructor_index
if (value.value)
output_init_element (value.value, value.original_type,
strict_string, constructor_type,
- NULL_TREE, 1, implicit,
- braced_init_obstack);
+ NULL_TREE, 1, implicit);
constructor_fields = 0;
}
while (constructor_stack != range_stack->stack)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1,
- braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
}
for (p = range_stack;
!p->range_end || tree_int_cst_equal (p->index, p->range_end);
p = p->prev)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
+ process_init_element (pop_init_level (1), true);
}
p->index = size_binop_loc (input_location,
p = p->next;
if (!p)
break;
- push_init_level (2, braced_init_obstack);
+ push_init_level (2);
p->stack = constructor_stack;
if (p->range_end && tree_int_cst_equal (p->index, p->range_end))
p->index = p->range_start;
tree
c_process_expr_stmt (location_t loc, tree expr)
{
- tree exprv;
-
if (!expr)
return NULL_TREE;
&& warn_unused_value)
emit_side_effect_warnings (loc, expr);
- exprv = expr;
- while (TREE_CODE (exprv) == COMPOUND_EXPR)
- exprv = TREE_OPERAND (exprv, 1);
- if (DECL_P (exprv) || handled_component_p (exprv))
- mark_exp_read (exprv);
+ if (DECL_P (expr) || handled_component_p (expr))
+ mark_exp_read (expr);
/* If the expression is not of a type to which we cannot assign a line
number, wrap the thing in a no-op NOP_EXPR. */
if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
{
- mark_exp_read (expr);
expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
SET_EXPR_LOCATION (expr, loc);
}
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE))
short_compare = 1;
- else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
- {
- if (TREE_CODE (op0) == ADDR_EXPR
- && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
- {
- if (code == EQ_EXPR)
- warning_at (location,
- OPT_Waddress,
- "the comparison will always evaluate as %<false%> "
- "for the address of %qD will never be NULL",
- TREE_OPERAND (op0, 0));
- else
- warning_at (location,
- OPT_Waddress,
- "the comparison will always evaluate as %<true%> "
- "for the address of %qD will never be NULL",
- TREE_OPERAND (op0, 0));
- }
- result_type = type0;
- }
- else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
- {
- if (TREE_CODE (op1) == ADDR_EXPR
- && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
- {
- if (code == EQ_EXPR)
- warning_at (location,
- OPT_Waddress,
- "the comparison will always evaluate as %<false%> "
- "for the address of %qD will never be NULL",
- TREE_OPERAND (op1, 0));
- else
- warning_at (location,
- OPT_Waddress,
- "the comparison will always evaluate as %<true%> "
- "for the address of %qD will never be NULL",
- TREE_OPERAND (op1, 0));
- }
- result_type = type1;
- }
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
tree tt0 = TREE_TYPE (type0);
and both must be object or both incomplete. */
if (comp_target_types (location, type0, type1))
result_type = common_pointer_type (type0, type1);
+ else if (null_pointer_constant_p (orig_op0))
+ result_type = type1;
+ else if (null_pointer_constant_p (orig_op1))
+ result_type = type0;
else if (!addr_space_superset (as0, as1, &as_common))
{
error_at (location, "comparison of pointers to "
(build_qualified_type (void_type_node, qual));
}
}
+ else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
+ {
+ if (TREE_CODE (op0) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+ warning_at (location,
+ OPT_Waddress, "the address of %qD will never be NULL",
+ TREE_OPERAND (op0, 0));
+ result_type = type0;
+ }
+ else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
+ {
+ if (TREE_CODE (op1) == ADDR_EXPR
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+ warning_at (location,
+ OPT_Waddress, "the address of %qD will never be NULL",
+ TREE_OPERAND (op1, 0));
+ result_type = type1;
+ }
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn (location, OPT_pedantic, "ISO C forbids "
"ordered comparisons of pointers to functions");
- else if (null_pointer_constant_p (orig_op0)
- || null_pointer_constant_p (orig_op1))
- warning_at (location, OPT_Wextra,
- "ordered comparison of pointer with null pointer");
-
}
else if (!addr_space_superset (as0, as1, &as_common))
{
"ordered comparison of pointer with integer zero");
else if (extra_warnings)
warning_at (location, OPT_Wextra,
- "ordered comparison of pointer with integer zero");
+ "ordered comparison of pointer with integer zero");
}
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
result_type = type1;
- if (pedantic)
- pedwarn (location, OPT_pedantic,
- "ordered comparison of pointer with integer zero");
- else if (extra_warnings)
- warning_at (location, OPT_Wextra,
- "ordered comparison of pointer with integer zero");
+ pedwarn (location, OPT_pedantic,
+ "ordered comparison of pointer with integer zero");
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{