1e4b17023SJohn Marino /* Build expressions with type checking for C compiler.
2e4b17023SJohn Marino Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4e4b17023SJohn Marino Free Software Foundation, Inc.
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino
23e4b17023SJohn Marino /* This file is part of the C front end.
24e4b17023SJohn Marino It contains routines to build C expressions given their operands,
25e4b17023SJohn Marino including computing the types of the result, C-specific error checks,
26e4b17023SJohn Marino and some optimization. */
27e4b17023SJohn Marino
28e4b17023SJohn Marino #include "config.h"
29e4b17023SJohn Marino #include "system.h"
30e4b17023SJohn Marino #include "coretypes.h"
31e4b17023SJohn Marino #include "tm.h"
32e4b17023SJohn Marino #include "tree.h"
33e4b17023SJohn Marino #include "langhooks.h"
34e4b17023SJohn Marino #include "c-tree.h"
35e4b17023SJohn Marino #include "c-lang.h"
36e4b17023SJohn Marino #include "flags.h"
37e4b17023SJohn Marino #include "output.h"
38e4b17023SJohn Marino #include "intl.h"
39e4b17023SJohn Marino #include "target.h"
40e4b17023SJohn Marino #include "tree-iterator.h"
41e4b17023SJohn Marino #include "bitmap.h"
42e4b17023SJohn Marino #include "gimple.h"
43e4b17023SJohn Marino #include "c-family/c-objc.h"
44e4b17023SJohn Marino
45e4b17023SJohn Marino /* Possible cases of implicit bad conversions. Used to select
46e4b17023SJohn Marino diagnostic messages in convert_for_assignment. */
47e4b17023SJohn Marino enum impl_conv {
48e4b17023SJohn Marino ic_argpass,
49e4b17023SJohn Marino ic_assign,
50e4b17023SJohn Marino ic_init,
51e4b17023SJohn Marino ic_return
52e4b17023SJohn Marino };
53e4b17023SJohn Marino
54e4b17023SJohn Marino /* Possibe cases of scalar_to_vector conversion. */
55e4b17023SJohn Marino enum stv_conv {
56e4b17023SJohn Marino stv_error, /* Error occured. */
57e4b17023SJohn Marino stv_nothing, /* Nothing happened. */
58e4b17023SJohn Marino stv_firstarg, /* First argument must be expanded. */
59e4b17023SJohn Marino stv_secondarg /* Second argument must be expanded. */
60e4b17023SJohn Marino };
61e4b17023SJohn Marino
62e4b17023SJohn Marino /* The level of nesting inside "__alignof__". */
63e4b17023SJohn Marino int in_alignof;
64e4b17023SJohn Marino
65e4b17023SJohn Marino /* The level of nesting inside "sizeof". */
66e4b17023SJohn Marino int in_sizeof;
67e4b17023SJohn Marino
68e4b17023SJohn Marino /* The level of nesting inside "typeof". */
69e4b17023SJohn Marino int in_typeof;
70e4b17023SJohn Marino
71e4b17023SJohn Marino /* Nonzero if we've already printed a "missing braces around initializer"
72e4b17023SJohn Marino message within this initializer. */
73e4b17023SJohn Marino static int missing_braces_mentioned;
74e4b17023SJohn Marino
75e4b17023SJohn Marino static int require_constant_value;
76e4b17023SJohn Marino static int require_constant_elements;
77e4b17023SJohn Marino
78e4b17023SJohn Marino static bool null_pointer_constant_p (const_tree);
79e4b17023SJohn Marino static tree qualify_type (tree, tree);
80e4b17023SJohn Marino static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *,
81e4b17023SJohn Marino bool *);
82e4b17023SJohn Marino static int comp_target_types (location_t, tree, tree);
83e4b17023SJohn Marino static int function_types_compatible_p (const_tree, const_tree, bool *,
84e4b17023SJohn Marino bool *);
85e4b17023SJohn Marino static int type_lists_compatible_p (const_tree, const_tree, bool *, bool *);
86e4b17023SJohn Marino static tree lookup_field (tree, tree);
87e4b17023SJohn Marino static int convert_arguments (tree, VEC(tree,gc) *, VEC(tree,gc) *, tree,
88e4b17023SJohn Marino tree);
89e4b17023SJohn Marino static tree pointer_diff (location_t, tree, tree);
90e4b17023SJohn Marino static tree convert_for_assignment (location_t, tree, tree, tree,
91e4b17023SJohn Marino enum impl_conv, bool, tree, tree, int);
92e4b17023SJohn Marino static tree valid_compound_expr_initializer (tree, tree);
93e4b17023SJohn Marino static void push_string (const char *);
94e4b17023SJohn Marino static void push_member_name (tree);
95e4b17023SJohn Marino static int spelling_length (void);
96e4b17023SJohn Marino static char *print_spelling (char *);
97e4b17023SJohn Marino static void warning_init (int, const char *);
98e4b17023SJohn Marino static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
99e4b17023SJohn Marino static void output_init_element (tree, tree, bool, tree, tree, int, bool,
100e4b17023SJohn Marino struct obstack *);
101e4b17023SJohn Marino static void output_pending_init_elements (int, struct obstack *);
102e4b17023SJohn Marino static int set_designator (int, struct obstack *);
103e4b17023SJohn Marino static void push_range_stack (tree, struct obstack *);
104e4b17023SJohn Marino static void add_pending_init (tree, tree, tree, bool, struct obstack *);
105e4b17023SJohn Marino static void set_nonincremental_init (struct obstack *);
106e4b17023SJohn Marino static void set_nonincremental_init_from_string (tree, struct obstack *);
107e4b17023SJohn Marino static tree find_init_member (tree, struct obstack *);
108e4b17023SJohn Marino static void readonly_warning (tree, enum lvalue_use);
109e4b17023SJohn Marino static int lvalue_or_else (location_t, const_tree, enum lvalue_use);
110e4b17023SJohn Marino static void record_maybe_used_decl (tree);
111e4b17023SJohn Marino static int comptypes_internal (const_tree, const_tree, bool *, bool *);
112e4b17023SJohn Marino
113e4b17023SJohn Marino /* Return true if EXP is a null pointer constant, false otherwise. */
114e4b17023SJohn Marino
115e4b17023SJohn Marino static bool
null_pointer_constant_p(const_tree expr)116e4b17023SJohn Marino null_pointer_constant_p (const_tree expr)
117e4b17023SJohn Marino {
118e4b17023SJohn Marino /* This should really operate on c_expr structures, but they aren't
119e4b17023SJohn Marino yet available everywhere required. */
120e4b17023SJohn Marino tree type = TREE_TYPE (expr);
121e4b17023SJohn Marino return (TREE_CODE (expr) == INTEGER_CST
122e4b17023SJohn Marino && !TREE_OVERFLOW (expr)
123e4b17023SJohn Marino && integer_zerop (expr)
124e4b17023SJohn Marino && (INTEGRAL_TYPE_P (type)
125e4b17023SJohn Marino || (TREE_CODE (type) == POINTER_TYPE
126e4b17023SJohn Marino && VOID_TYPE_P (TREE_TYPE (type))
127e4b17023SJohn Marino && TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED)));
128e4b17023SJohn Marino }
129e4b17023SJohn Marino
130e4b17023SJohn Marino /* EXPR may appear in an unevaluated part of an integer constant
131e4b17023SJohn Marino expression, but not in an evaluated part. Wrap it in a
132e4b17023SJohn Marino C_MAYBE_CONST_EXPR, or mark it with TREE_OVERFLOW if it is just an
133e4b17023SJohn Marino INTEGER_CST and we cannot create a C_MAYBE_CONST_EXPR. */
134e4b17023SJohn Marino
135e4b17023SJohn Marino static tree
note_integer_operands(tree expr)136e4b17023SJohn Marino note_integer_operands (tree expr)
137e4b17023SJohn Marino {
138e4b17023SJohn Marino tree ret;
139e4b17023SJohn Marino if (TREE_CODE (expr) == INTEGER_CST && in_late_binary_op)
140e4b17023SJohn Marino {
141e4b17023SJohn Marino ret = copy_node (expr);
142e4b17023SJohn Marino TREE_OVERFLOW (ret) = 1;
143e4b17023SJohn Marino }
144e4b17023SJohn Marino else
145e4b17023SJohn Marino {
146e4b17023SJohn Marino ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL_TREE, expr);
147e4b17023SJohn Marino C_MAYBE_CONST_EXPR_INT_OPERANDS (ret) = 1;
148e4b17023SJohn Marino }
149e4b17023SJohn Marino return ret;
150e4b17023SJohn Marino }
151e4b17023SJohn Marino
152e4b17023SJohn Marino /* Having checked whether EXPR may appear in an unevaluated part of an
153e4b17023SJohn Marino integer constant expression and found that it may, remove any
154e4b17023SJohn Marino C_MAYBE_CONST_EXPR noting this fact and return the resulting
155e4b17023SJohn Marino expression. */
156e4b17023SJohn Marino
157e4b17023SJohn Marino static inline tree
remove_c_maybe_const_expr(tree expr)158e4b17023SJohn Marino remove_c_maybe_const_expr (tree expr)
159e4b17023SJohn Marino {
160e4b17023SJohn Marino if (TREE_CODE (expr) == C_MAYBE_CONST_EXPR)
161e4b17023SJohn Marino return C_MAYBE_CONST_EXPR_EXPR (expr);
162e4b17023SJohn Marino else
163e4b17023SJohn Marino return expr;
164e4b17023SJohn Marino }
165e4b17023SJohn Marino
166e4b17023SJohn Marino /* This is a cache to hold if two types are compatible or not. */
167e4b17023SJohn Marino
168e4b17023SJohn Marino struct tagged_tu_seen_cache {
169e4b17023SJohn Marino const struct tagged_tu_seen_cache * next;
170e4b17023SJohn Marino const_tree t1;
171e4b17023SJohn Marino const_tree t2;
172e4b17023SJohn Marino /* The return value of tagged_types_tu_compatible_p if we had seen
173e4b17023SJohn Marino these two types already. */
174e4b17023SJohn Marino int val;
175e4b17023SJohn Marino };
176e4b17023SJohn Marino
177e4b17023SJohn Marino static const struct tagged_tu_seen_cache * tagged_tu_seen_base;
178e4b17023SJohn Marino static void free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *);
179e4b17023SJohn Marino
180e4b17023SJohn Marino /* Do `exp = require_complete_type (exp);' to make sure exp
181e4b17023SJohn Marino does not have an incomplete type. (That includes void types.) */
182e4b17023SJohn Marino
183e4b17023SJohn Marino tree
require_complete_type(tree value)184e4b17023SJohn Marino require_complete_type (tree value)
185e4b17023SJohn Marino {
186e4b17023SJohn Marino tree type = TREE_TYPE (value);
187e4b17023SJohn Marino
188e4b17023SJohn Marino if (value == error_mark_node || type == error_mark_node)
189e4b17023SJohn Marino return error_mark_node;
190e4b17023SJohn Marino
191e4b17023SJohn Marino /* First, detect a valid value with a complete type. */
192e4b17023SJohn Marino if (COMPLETE_TYPE_P (type))
193e4b17023SJohn Marino return value;
194e4b17023SJohn Marino
195e4b17023SJohn Marino c_incomplete_type_error (value, type);
196e4b17023SJohn Marino return error_mark_node;
197e4b17023SJohn Marino }
198e4b17023SJohn Marino
199e4b17023SJohn Marino /* Print an error message for invalid use of an incomplete type.
200e4b17023SJohn Marino VALUE is the expression that was used (or 0 if that isn't known)
201e4b17023SJohn Marino and TYPE is the type that was invalid. */
202e4b17023SJohn Marino
203e4b17023SJohn Marino void
c_incomplete_type_error(const_tree value,const_tree type)204e4b17023SJohn Marino c_incomplete_type_error (const_tree value, const_tree type)
205e4b17023SJohn Marino {
206e4b17023SJohn Marino const char *type_code_string;
207e4b17023SJohn Marino
208e4b17023SJohn Marino /* Avoid duplicate error message. */
209e4b17023SJohn Marino if (TREE_CODE (type) == ERROR_MARK)
210e4b17023SJohn Marino return;
211e4b17023SJohn Marino
212e4b17023SJohn Marino if (value != 0 && (TREE_CODE (value) == VAR_DECL
213e4b17023SJohn Marino || TREE_CODE (value) == PARM_DECL))
214e4b17023SJohn Marino error ("%qD has an incomplete type", value);
215e4b17023SJohn Marino else
216e4b17023SJohn Marino {
217e4b17023SJohn Marino retry:
218e4b17023SJohn Marino /* We must print an error message. Be clever about what it says. */
219e4b17023SJohn Marino
220e4b17023SJohn Marino switch (TREE_CODE (type))
221e4b17023SJohn Marino {
222e4b17023SJohn Marino case RECORD_TYPE:
223e4b17023SJohn Marino type_code_string = "struct";
224e4b17023SJohn Marino break;
225e4b17023SJohn Marino
226e4b17023SJohn Marino case UNION_TYPE:
227e4b17023SJohn Marino type_code_string = "union";
228e4b17023SJohn Marino break;
229e4b17023SJohn Marino
230e4b17023SJohn Marino case ENUMERAL_TYPE:
231e4b17023SJohn Marino type_code_string = "enum";
232e4b17023SJohn Marino break;
233e4b17023SJohn Marino
234e4b17023SJohn Marino case VOID_TYPE:
235e4b17023SJohn Marino error ("invalid use of void expression");
236e4b17023SJohn Marino return;
237e4b17023SJohn Marino
238e4b17023SJohn Marino case ARRAY_TYPE:
239e4b17023SJohn Marino if (TYPE_DOMAIN (type))
240e4b17023SJohn Marino {
241e4b17023SJohn Marino if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
242e4b17023SJohn Marino {
243e4b17023SJohn Marino error ("invalid use of flexible array member");
244e4b17023SJohn Marino return;
245e4b17023SJohn Marino }
246e4b17023SJohn Marino type = TREE_TYPE (type);
247e4b17023SJohn Marino goto retry;
248e4b17023SJohn Marino }
249e4b17023SJohn Marino error ("invalid use of array with unspecified bounds");
250e4b17023SJohn Marino return;
251e4b17023SJohn Marino
252e4b17023SJohn Marino default:
253e4b17023SJohn Marino gcc_unreachable ();
254e4b17023SJohn Marino }
255e4b17023SJohn Marino
256e4b17023SJohn Marino if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
257e4b17023SJohn Marino error ("invalid use of undefined type %<%s %E%>",
258e4b17023SJohn Marino type_code_string, TYPE_NAME (type));
259e4b17023SJohn Marino else
260e4b17023SJohn Marino /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
261e4b17023SJohn Marino error ("invalid use of incomplete typedef %qD", TYPE_NAME (type));
262e4b17023SJohn Marino }
263e4b17023SJohn Marino }
264e4b17023SJohn Marino
265e4b17023SJohn Marino /* Given a type, apply default promotions wrt unnamed function
266e4b17023SJohn Marino arguments and return the new type. */
267e4b17023SJohn Marino
268e4b17023SJohn Marino tree
c_type_promotes_to(tree type)269e4b17023SJohn Marino c_type_promotes_to (tree type)
270e4b17023SJohn Marino {
271e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (type) == float_type_node)
272e4b17023SJohn Marino return double_type_node;
273e4b17023SJohn Marino
274e4b17023SJohn Marino if (c_promoting_integer_type_p (type))
275e4b17023SJohn Marino {
276e4b17023SJohn Marino /* Preserve unsignedness if not really getting any wider. */
277e4b17023SJohn Marino if (TYPE_UNSIGNED (type)
278e4b17023SJohn Marino && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
279e4b17023SJohn Marino return unsigned_type_node;
280e4b17023SJohn Marino return integer_type_node;
281e4b17023SJohn Marino }
282e4b17023SJohn Marino
283e4b17023SJohn Marino return type;
284e4b17023SJohn Marino }
285e4b17023SJohn Marino
286e4b17023SJohn Marino /* Return true if between two named address spaces, whether there is a superset
287e4b17023SJohn Marino named address space that encompasses both address spaces. If there is a
288e4b17023SJohn Marino superset, return which address space is the superset. */
289e4b17023SJohn Marino
290e4b17023SJohn Marino static bool
addr_space_superset(addr_space_t as1,addr_space_t as2,addr_space_t * common)291e4b17023SJohn Marino addr_space_superset (addr_space_t as1, addr_space_t as2, addr_space_t *common)
292e4b17023SJohn Marino {
293e4b17023SJohn Marino if (as1 == as2)
294e4b17023SJohn Marino {
295e4b17023SJohn Marino *common = as1;
296e4b17023SJohn Marino return true;
297e4b17023SJohn Marino }
298e4b17023SJohn Marino else if (targetm.addr_space.subset_p (as1, as2))
299e4b17023SJohn Marino {
300e4b17023SJohn Marino *common = as2;
301e4b17023SJohn Marino return true;
302e4b17023SJohn Marino }
303e4b17023SJohn Marino else if (targetm.addr_space.subset_p (as2, as1))
304e4b17023SJohn Marino {
305e4b17023SJohn Marino *common = as1;
306e4b17023SJohn Marino return true;
307e4b17023SJohn Marino }
308e4b17023SJohn Marino else
309e4b17023SJohn Marino return false;
310e4b17023SJohn Marino }
311e4b17023SJohn Marino
312e4b17023SJohn Marino /* Return a variant of TYPE which has all the type qualifiers of LIKE
313e4b17023SJohn Marino as well as those of TYPE. */
314e4b17023SJohn Marino
315e4b17023SJohn Marino static tree
qualify_type(tree type,tree like)316e4b17023SJohn Marino qualify_type (tree type, tree like)
317e4b17023SJohn Marino {
318e4b17023SJohn Marino addr_space_t as_type = TYPE_ADDR_SPACE (type);
319e4b17023SJohn Marino addr_space_t as_like = TYPE_ADDR_SPACE (like);
320e4b17023SJohn Marino addr_space_t as_common;
321e4b17023SJohn Marino
322e4b17023SJohn Marino /* If the two named address spaces are different, determine the common
323e4b17023SJohn Marino superset address space. If there isn't one, raise an error. */
324e4b17023SJohn Marino if (!addr_space_superset (as_type, as_like, &as_common))
325e4b17023SJohn Marino {
326e4b17023SJohn Marino as_common = as_type;
327e4b17023SJohn Marino error ("%qT and %qT are in disjoint named address spaces",
328e4b17023SJohn Marino type, like);
329e4b17023SJohn Marino }
330e4b17023SJohn Marino
331e4b17023SJohn Marino return c_build_qualified_type (type,
332e4b17023SJohn Marino TYPE_QUALS_NO_ADDR_SPACE (type)
333e4b17023SJohn Marino | TYPE_QUALS_NO_ADDR_SPACE (like)
334e4b17023SJohn Marino | ENCODE_QUAL_ADDR_SPACE (as_common));
335e4b17023SJohn Marino }
336e4b17023SJohn Marino
337e4b17023SJohn Marino /* Return true iff the given tree T is a variable length array. */
338e4b17023SJohn Marino
339e4b17023SJohn Marino bool
c_vla_type_p(const_tree t)340e4b17023SJohn Marino c_vla_type_p (const_tree t)
341e4b17023SJohn Marino {
342e4b17023SJohn Marino if (TREE_CODE (t) == ARRAY_TYPE
343e4b17023SJohn Marino && C_TYPE_VARIABLE_SIZE (t))
344e4b17023SJohn Marino return true;
345e4b17023SJohn Marino return false;
346e4b17023SJohn Marino }
347e4b17023SJohn Marino
348e4b17023SJohn Marino /* Return the composite type of two compatible types.
349e4b17023SJohn Marino
350e4b17023SJohn Marino We assume that comptypes has already been done and returned
351e4b17023SJohn Marino nonzero; if that isn't so, this may crash. In particular, we
352e4b17023SJohn Marino assume that qualifiers match. */
353e4b17023SJohn Marino
354e4b17023SJohn Marino tree
composite_type(tree t1,tree t2)355e4b17023SJohn Marino composite_type (tree t1, tree t2)
356e4b17023SJohn Marino {
357e4b17023SJohn Marino enum tree_code code1;
358e4b17023SJohn Marino enum tree_code code2;
359e4b17023SJohn Marino tree attributes;
360e4b17023SJohn Marino
361e4b17023SJohn Marino /* Save time if the two types are the same. */
362e4b17023SJohn Marino
363e4b17023SJohn Marino if (t1 == t2) return t1;
364e4b17023SJohn Marino
365e4b17023SJohn Marino /* If one type is nonsense, use the other. */
366e4b17023SJohn Marino if (t1 == error_mark_node)
367e4b17023SJohn Marino return t2;
368e4b17023SJohn Marino if (t2 == error_mark_node)
369e4b17023SJohn Marino return t1;
370e4b17023SJohn Marino
371e4b17023SJohn Marino code1 = TREE_CODE (t1);
372e4b17023SJohn Marino code2 = TREE_CODE (t2);
373e4b17023SJohn Marino
374e4b17023SJohn Marino /* Merge the attributes. */
375e4b17023SJohn Marino attributes = targetm.merge_type_attributes (t1, t2);
376e4b17023SJohn Marino
377e4b17023SJohn Marino /* If one is an enumerated type and the other is the compatible
378e4b17023SJohn Marino integer type, the composite type might be either of the two
379e4b17023SJohn Marino (DR#013 question 3). For consistency, use the enumerated type as
380e4b17023SJohn Marino the composite type. */
381e4b17023SJohn Marino
382e4b17023SJohn Marino if (code1 == ENUMERAL_TYPE && code2 == INTEGER_TYPE)
383e4b17023SJohn Marino return t1;
384e4b17023SJohn Marino if (code2 == ENUMERAL_TYPE && code1 == INTEGER_TYPE)
385e4b17023SJohn Marino return t2;
386e4b17023SJohn Marino
387e4b17023SJohn Marino gcc_assert (code1 == code2);
388e4b17023SJohn Marino
389e4b17023SJohn Marino switch (code1)
390e4b17023SJohn Marino {
391e4b17023SJohn Marino case POINTER_TYPE:
392e4b17023SJohn Marino /* For two pointers, do this recursively on the target type. */
393e4b17023SJohn Marino {
394e4b17023SJohn Marino tree pointed_to_1 = TREE_TYPE (t1);
395e4b17023SJohn Marino tree pointed_to_2 = TREE_TYPE (t2);
396e4b17023SJohn Marino tree target = composite_type (pointed_to_1, pointed_to_2);
397e4b17023SJohn Marino t1 = build_pointer_type_for_mode (target, TYPE_MODE (t1), false);
398e4b17023SJohn Marino t1 = build_type_attribute_variant (t1, attributes);
399e4b17023SJohn Marino return qualify_type (t1, t2);
400e4b17023SJohn Marino }
401e4b17023SJohn Marino
402e4b17023SJohn Marino case ARRAY_TYPE:
403e4b17023SJohn Marino {
404e4b17023SJohn Marino tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
405e4b17023SJohn Marino int quals;
406e4b17023SJohn Marino tree unqual_elt;
407e4b17023SJohn Marino tree d1 = TYPE_DOMAIN (t1);
408e4b17023SJohn Marino tree d2 = TYPE_DOMAIN (t2);
409e4b17023SJohn Marino bool d1_variable, d2_variable;
410e4b17023SJohn Marino bool d1_zero, d2_zero;
411e4b17023SJohn Marino bool t1_complete, t2_complete;
412e4b17023SJohn Marino
413e4b17023SJohn Marino /* We should not have any type quals on arrays at all. */
414e4b17023SJohn Marino gcc_assert (!TYPE_QUALS_NO_ADDR_SPACE (t1)
415e4b17023SJohn Marino && !TYPE_QUALS_NO_ADDR_SPACE (t2));
416e4b17023SJohn Marino
417e4b17023SJohn Marino t1_complete = COMPLETE_TYPE_P (t1);
418e4b17023SJohn Marino t2_complete = COMPLETE_TYPE_P (t2);
419e4b17023SJohn Marino
420e4b17023SJohn Marino d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1);
421e4b17023SJohn Marino d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2);
422e4b17023SJohn Marino
423e4b17023SJohn Marino d1_variable = (!d1_zero
424e4b17023SJohn Marino && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
425e4b17023SJohn Marino || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
426e4b17023SJohn Marino d2_variable = (!d2_zero
427e4b17023SJohn Marino && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
428e4b17023SJohn Marino || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
429e4b17023SJohn Marino d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
430e4b17023SJohn Marino d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
431e4b17023SJohn Marino
432e4b17023SJohn Marino /* Save space: see if the result is identical to one of the args. */
433e4b17023SJohn Marino if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)
434e4b17023SJohn Marino && (d2_variable || d2_zero || !d1_variable))
435e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
436e4b17023SJohn Marino if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)
437e4b17023SJohn Marino && (d1_variable || d1_zero || !d2_variable))
438e4b17023SJohn Marino return build_type_attribute_variant (t2, attributes);
439e4b17023SJohn Marino
440e4b17023SJohn Marino if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
441e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
442e4b17023SJohn Marino if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
443e4b17023SJohn Marino return build_type_attribute_variant (t2, attributes);
444e4b17023SJohn Marino
445e4b17023SJohn Marino /* Merge the element types, and have a size if either arg has
446e4b17023SJohn Marino one. We may have qualifiers on the element types. To set
447e4b17023SJohn Marino up TYPE_MAIN_VARIANT correctly, we need to form the
448e4b17023SJohn Marino composite of the unqualified types and add the qualifiers
449e4b17023SJohn Marino back at the end. */
450e4b17023SJohn Marino quals = TYPE_QUALS (strip_array_types (elt));
451e4b17023SJohn Marino unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
452e4b17023SJohn Marino t1 = build_array_type (unqual_elt,
453e4b17023SJohn Marino TYPE_DOMAIN ((TYPE_DOMAIN (t1)
454e4b17023SJohn Marino && (d2_variable
455e4b17023SJohn Marino || d2_zero
456e4b17023SJohn Marino || !d1_variable))
457e4b17023SJohn Marino ? t1
458e4b17023SJohn Marino : t2));
459e4b17023SJohn Marino /* Ensure a composite type involving a zero-length array type
460e4b17023SJohn Marino is a zero-length type not an incomplete type. */
461e4b17023SJohn Marino if (d1_zero && d2_zero
462e4b17023SJohn Marino && (t1_complete || t2_complete)
463e4b17023SJohn Marino && !COMPLETE_TYPE_P (t1))
464e4b17023SJohn Marino {
465e4b17023SJohn Marino TYPE_SIZE (t1) = bitsize_zero_node;
466e4b17023SJohn Marino TYPE_SIZE_UNIT (t1) = size_zero_node;
467e4b17023SJohn Marino }
468e4b17023SJohn Marino t1 = c_build_qualified_type (t1, quals);
469e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
470e4b17023SJohn Marino }
471e4b17023SJohn Marino
472e4b17023SJohn Marino case ENUMERAL_TYPE:
473e4b17023SJohn Marino case RECORD_TYPE:
474e4b17023SJohn Marino case UNION_TYPE:
475e4b17023SJohn Marino if (attributes != NULL)
476e4b17023SJohn Marino {
477e4b17023SJohn Marino /* Try harder not to create a new aggregate type. */
478e4b17023SJohn Marino if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
479e4b17023SJohn Marino return t1;
480e4b17023SJohn Marino if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
481e4b17023SJohn Marino return t2;
482e4b17023SJohn Marino }
483e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
484e4b17023SJohn Marino
485e4b17023SJohn Marino case FUNCTION_TYPE:
486e4b17023SJohn Marino /* Function types: prefer the one that specified arg types.
487e4b17023SJohn Marino If both do, merge the arg types. Also merge the return types. */
488e4b17023SJohn Marino {
489e4b17023SJohn Marino tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
490e4b17023SJohn Marino tree p1 = TYPE_ARG_TYPES (t1);
491e4b17023SJohn Marino tree p2 = TYPE_ARG_TYPES (t2);
492e4b17023SJohn Marino int len;
493e4b17023SJohn Marino tree newargs, n;
494e4b17023SJohn Marino int i;
495e4b17023SJohn Marino
496e4b17023SJohn Marino /* Save space: see if the result is identical to one of the args. */
497e4b17023SJohn Marino if (valtype == TREE_TYPE (t1) && !TYPE_ARG_TYPES (t2))
498e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
499e4b17023SJohn Marino if (valtype == TREE_TYPE (t2) && !TYPE_ARG_TYPES (t1))
500e4b17023SJohn Marino return build_type_attribute_variant (t2, attributes);
501e4b17023SJohn Marino
502e4b17023SJohn Marino /* Simple way if one arg fails to specify argument types. */
503e4b17023SJohn Marino if (TYPE_ARG_TYPES (t1) == 0)
504e4b17023SJohn Marino {
505e4b17023SJohn Marino t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2));
506e4b17023SJohn Marino t1 = build_type_attribute_variant (t1, attributes);
507e4b17023SJohn Marino return qualify_type (t1, t2);
508e4b17023SJohn Marino }
509e4b17023SJohn Marino if (TYPE_ARG_TYPES (t2) == 0)
510e4b17023SJohn Marino {
511e4b17023SJohn Marino t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1));
512e4b17023SJohn Marino t1 = build_type_attribute_variant (t1, attributes);
513e4b17023SJohn Marino return qualify_type (t1, t2);
514e4b17023SJohn Marino }
515e4b17023SJohn Marino
516e4b17023SJohn Marino /* If both args specify argument types, we must merge the two
517e4b17023SJohn Marino lists, argument by argument. */
518e4b17023SJohn Marino
519e4b17023SJohn Marino len = list_length (p1);
520e4b17023SJohn Marino newargs = 0;
521e4b17023SJohn Marino
522e4b17023SJohn Marino for (i = 0; i < len; i++)
523e4b17023SJohn Marino newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
524e4b17023SJohn Marino
525e4b17023SJohn Marino n = newargs;
526e4b17023SJohn Marino
527e4b17023SJohn Marino for (; p1;
528e4b17023SJohn Marino p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
529e4b17023SJohn Marino {
530e4b17023SJohn Marino /* A null type means arg type is not specified.
531e4b17023SJohn Marino Take whatever the other function type has. */
532e4b17023SJohn Marino if (TREE_VALUE (p1) == 0)
533e4b17023SJohn Marino {
534e4b17023SJohn Marino TREE_VALUE (n) = TREE_VALUE (p2);
535e4b17023SJohn Marino goto parm_done;
536e4b17023SJohn Marino }
537e4b17023SJohn Marino if (TREE_VALUE (p2) == 0)
538e4b17023SJohn Marino {
539e4b17023SJohn Marino TREE_VALUE (n) = TREE_VALUE (p1);
540e4b17023SJohn Marino goto parm_done;
541e4b17023SJohn Marino }
542e4b17023SJohn Marino
543e4b17023SJohn Marino /* Given wait (union {union wait *u; int *i} *)
544e4b17023SJohn Marino and wait (union wait *),
545e4b17023SJohn Marino prefer union wait * as type of parm. */
546e4b17023SJohn Marino if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
547e4b17023SJohn Marino && TREE_VALUE (p1) != TREE_VALUE (p2))
548e4b17023SJohn Marino {
549e4b17023SJohn Marino tree memb;
550e4b17023SJohn Marino tree mv2 = TREE_VALUE (p2);
551e4b17023SJohn Marino if (mv2 && mv2 != error_mark_node
552e4b17023SJohn Marino && TREE_CODE (mv2) != ARRAY_TYPE)
553e4b17023SJohn Marino mv2 = TYPE_MAIN_VARIANT (mv2);
554e4b17023SJohn Marino for (memb = TYPE_FIELDS (TREE_VALUE (p1));
555e4b17023SJohn Marino memb; memb = DECL_CHAIN (memb))
556e4b17023SJohn Marino {
557e4b17023SJohn Marino tree mv3 = TREE_TYPE (memb);
558e4b17023SJohn Marino if (mv3 && mv3 != error_mark_node
559e4b17023SJohn Marino && TREE_CODE (mv3) != ARRAY_TYPE)
560e4b17023SJohn Marino mv3 = TYPE_MAIN_VARIANT (mv3);
561e4b17023SJohn Marino if (comptypes (mv3, mv2))
562e4b17023SJohn Marino {
563e4b17023SJohn Marino TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
564e4b17023SJohn Marino TREE_VALUE (p2));
565e4b17023SJohn Marino pedwarn (input_location, OPT_pedantic,
566e4b17023SJohn Marino "function types not truly compatible in ISO C");
567e4b17023SJohn Marino goto parm_done;
568e4b17023SJohn Marino }
569e4b17023SJohn Marino }
570e4b17023SJohn Marino }
571e4b17023SJohn Marino if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
572e4b17023SJohn Marino && TREE_VALUE (p2) != TREE_VALUE (p1))
573e4b17023SJohn Marino {
574e4b17023SJohn Marino tree memb;
575e4b17023SJohn Marino tree mv1 = TREE_VALUE (p1);
576e4b17023SJohn Marino if (mv1 && mv1 != error_mark_node
577e4b17023SJohn Marino && TREE_CODE (mv1) != ARRAY_TYPE)
578e4b17023SJohn Marino mv1 = TYPE_MAIN_VARIANT (mv1);
579e4b17023SJohn Marino for (memb = TYPE_FIELDS (TREE_VALUE (p2));
580e4b17023SJohn Marino memb; memb = DECL_CHAIN (memb))
581e4b17023SJohn Marino {
582e4b17023SJohn Marino tree mv3 = TREE_TYPE (memb);
583e4b17023SJohn Marino if (mv3 && mv3 != error_mark_node
584e4b17023SJohn Marino && TREE_CODE (mv3) != ARRAY_TYPE)
585e4b17023SJohn Marino mv3 = TYPE_MAIN_VARIANT (mv3);
586e4b17023SJohn Marino if (comptypes (mv3, mv1))
587e4b17023SJohn Marino {
588e4b17023SJohn Marino TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
589e4b17023SJohn Marino TREE_VALUE (p1));
590e4b17023SJohn Marino pedwarn (input_location, OPT_pedantic,
591e4b17023SJohn Marino "function types not truly compatible in ISO C");
592e4b17023SJohn Marino goto parm_done;
593e4b17023SJohn Marino }
594e4b17023SJohn Marino }
595e4b17023SJohn Marino }
596e4b17023SJohn Marino TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
597e4b17023SJohn Marino parm_done: ;
598e4b17023SJohn Marino }
599e4b17023SJohn Marino
600e4b17023SJohn Marino t1 = build_function_type (valtype, newargs);
601e4b17023SJohn Marino t1 = qualify_type (t1, t2);
602e4b17023SJohn Marino /* ... falls through ... */
603e4b17023SJohn Marino }
604e4b17023SJohn Marino
605e4b17023SJohn Marino default:
606e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
607e4b17023SJohn Marino }
608e4b17023SJohn Marino
609e4b17023SJohn Marino }
610e4b17023SJohn Marino
611e4b17023SJohn Marino /* Return the type of a conditional expression between pointers to
612e4b17023SJohn Marino possibly differently qualified versions of compatible types.
613e4b17023SJohn Marino
614e4b17023SJohn Marino We assume that comp_target_types has already been done and returned
615e4b17023SJohn Marino nonzero; if that isn't so, this may crash. */
616e4b17023SJohn Marino
617e4b17023SJohn Marino static tree
common_pointer_type(tree t1,tree t2)618e4b17023SJohn Marino common_pointer_type (tree t1, tree t2)
619e4b17023SJohn Marino {
620e4b17023SJohn Marino tree attributes;
621e4b17023SJohn Marino tree pointed_to_1, mv1;
622e4b17023SJohn Marino tree pointed_to_2, mv2;
623e4b17023SJohn Marino tree target;
624e4b17023SJohn Marino unsigned target_quals;
625e4b17023SJohn Marino addr_space_t as1, as2, as_common;
626e4b17023SJohn Marino int quals1, quals2;
627e4b17023SJohn Marino
628e4b17023SJohn Marino /* Save time if the two types are the same. */
629e4b17023SJohn Marino
630e4b17023SJohn Marino if (t1 == t2) return t1;
631e4b17023SJohn Marino
632e4b17023SJohn Marino /* If one type is nonsense, use the other. */
633e4b17023SJohn Marino if (t1 == error_mark_node)
634e4b17023SJohn Marino return t2;
635e4b17023SJohn Marino if (t2 == error_mark_node)
636e4b17023SJohn Marino return t1;
637e4b17023SJohn Marino
638e4b17023SJohn Marino gcc_assert (TREE_CODE (t1) == POINTER_TYPE
639e4b17023SJohn Marino && TREE_CODE (t2) == POINTER_TYPE);
640e4b17023SJohn Marino
641e4b17023SJohn Marino /* Merge the attributes. */
642e4b17023SJohn Marino attributes = targetm.merge_type_attributes (t1, t2);
643e4b17023SJohn Marino
644e4b17023SJohn Marino /* Find the composite type of the target types, and combine the
645e4b17023SJohn Marino qualifiers of the two types' targets. Do not lose qualifiers on
646e4b17023SJohn Marino array element types by taking the TYPE_MAIN_VARIANT. */
647e4b17023SJohn Marino mv1 = pointed_to_1 = TREE_TYPE (t1);
648e4b17023SJohn Marino mv2 = pointed_to_2 = TREE_TYPE (t2);
649e4b17023SJohn Marino if (TREE_CODE (mv1) != ARRAY_TYPE)
650e4b17023SJohn Marino mv1 = TYPE_MAIN_VARIANT (pointed_to_1);
651e4b17023SJohn Marino if (TREE_CODE (mv2) != ARRAY_TYPE)
652e4b17023SJohn Marino mv2 = TYPE_MAIN_VARIANT (pointed_to_2);
653e4b17023SJohn Marino target = composite_type (mv1, mv2);
654e4b17023SJohn Marino
655e4b17023SJohn Marino /* For function types do not merge const qualifiers, but drop them
656e4b17023SJohn Marino if used inconsistently. The middle-end uses these to mark const
657e4b17023SJohn Marino and noreturn functions. */
658e4b17023SJohn Marino quals1 = TYPE_QUALS_NO_ADDR_SPACE (pointed_to_1);
659e4b17023SJohn Marino quals2 = TYPE_QUALS_NO_ADDR_SPACE (pointed_to_2);
660e4b17023SJohn Marino
661e4b17023SJohn Marino if (TREE_CODE (pointed_to_1) == FUNCTION_TYPE)
662e4b17023SJohn Marino target_quals = (quals1 & quals2);
663e4b17023SJohn Marino else
664e4b17023SJohn Marino target_quals = (quals1 | quals2);
665e4b17023SJohn Marino
666e4b17023SJohn Marino /* If the two named address spaces are different, determine the common
667e4b17023SJohn Marino superset address space. This is guaranteed to exist due to the
668e4b17023SJohn Marino assumption that comp_target_type returned non-zero. */
669e4b17023SJohn Marino as1 = TYPE_ADDR_SPACE (pointed_to_1);
670e4b17023SJohn Marino as2 = TYPE_ADDR_SPACE (pointed_to_2);
671e4b17023SJohn Marino if (!addr_space_superset (as1, as2, &as_common))
672e4b17023SJohn Marino gcc_unreachable ();
673e4b17023SJohn Marino
674e4b17023SJohn Marino target_quals |= ENCODE_QUAL_ADDR_SPACE (as_common);
675e4b17023SJohn Marino
676e4b17023SJohn Marino t1 = build_pointer_type (c_build_qualified_type (target, target_quals));
677e4b17023SJohn Marino return build_type_attribute_variant (t1, attributes);
678e4b17023SJohn Marino }
679e4b17023SJohn Marino
680e4b17023SJohn Marino /* Return the common type for two arithmetic types under the usual
681e4b17023SJohn Marino arithmetic conversions. The default conversions have already been
682e4b17023SJohn Marino applied, and enumerated types converted to their compatible integer
683e4b17023SJohn Marino types. The resulting type is unqualified and has no attributes.
684e4b17023SJohn Marino
685e4b17023SJohn Marino This is the type for the result of most arithmetic operations
686e4b17023SJohn Marino if the operands have the given two types. */
687e4b17023SJohn Marino
688e4b17023SJohn Marino static tree
c_common_type(tree t1,tree t2)689e4b17023SJohn Marino c_common_type (tree t1, tree t2)
690e4b17023SJohn Marino {
691e4b17023SJohn Marino enum tree_code code1;
692e4b17023SJohn Marino enum tree_code code2;
693e4b17023SJohn Marino
694e4b17023SJohn Marino /* If one type is nonsense, use the other. */
695e4b17023SJohn Marino if (t1 == error_mark_node)
696e4b17023SJohn Marino return t2;
697e4b17023SJohn Marino if (t2 == error_mark_node)
698e4b17023SJohn Marino return t1;
699e4b17023SJohn Marino
700e4b17023SJohn Marino if (TYPE_QUALS (t1) != TYPE_UNQUALIFIED)
701e4b17023SJohn Marino t1 = TYPE_MAIN_VARIANT (t1);
702e4b17023SJohn Marino
703e4b17023SJohn Marino if (TYPE_QUALS (t2) != TYPE_UNQUALIFIED)
704e4b17023SJohn Marino t2 = TYPE_MAIN_VARIANT (t2);
705e4b17023SJohn Marino
706e4b17023SJohn Marino if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
707e4b17023SJohn Marino t1 = build_type_attribute_variant (t1, NULL_TREE);
708e4b17023SJohn Marino
709e4b17023SJohn Marino if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
710e4b17023SJohn Marino t2 = build_type_attribute_variant (t2, NULL_TREE);
711e4b17023SJohn Marino
712e4b17023SJohn Marino /* Save time if the two types are the same. */
713e4b17023SJohn Marino
714e4b17023SJohn Marino if (t1 == t2) return t1;
715e4b17023SJohn Marino
716e4b17023SJohn Marino code1 = TREE_CODE (t1);
717e4b17023SJohn Marino code2 = TREE_CODE (t2);
718e4b17023SJohn Marino
719e4b17023SJohn Marino gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE
720e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE || code1 == REAL_TYPE
721e4b17023SJohn Marino || code1 == INTEGER_TYPE);
722e4b17023SJohn Marino gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
723e4b17023SJohn Marino || code2 == FIXED_POINT_TYPE || code2 == REAL_TYPE
724e4b17023SJohn Marino || code2 == INTEGER_TYPE);
725e4b17023SJohn Marino
726e4b17023SJohn Marino /* When one operand is a decimal float type, the other operand cannot be
727e4b17023SJohn Marino a generic float type or a complex type. We also disallow vector types
728e4b17023SJohn Marino here. */
729e4b17023SJohn Marino if ((DECIMAL_FLOAT_TYPE_P (t1) || DECIMAL_FLOAT_TYPE_P (t2))
730e4b17023SJohn Marino && !(DECIMAL_FLOAT_TYPE_P (t1) && DECIMAL_FLOAT_TYPE_P (t2)))
731e4b17023SJohn Marino {
732e4b17023SJohn Marino if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE)
733e4b17023SJohn Marino {
734e4b17023SJohn Marino error ("can%'t mix operands of decimal float and vector types");
735e4b17023SJohn Marino return error_mark_node;
736e4b17023SJohn Marino }
737e4b17023SJohn Marino if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
738e4b17023SJohn Marino {
739e4b17023SJohn Marino error ("can%'t mix operands of decimal float and complex types");
740e4b17023SJohn Marino return error_mark_node;
741e4b17023SJohn Marino }
742e4b17023SJohn Marino if (code1 == REAL_TYPE && code2 == REAL_TYPE)
743e4b17023SJohn Marino {
744e4b17023SJohn Marino error ("can%'t mix operands of decimal float and other float types");
745e4b17023SJohn Marino return error_mark_node;
746e4b17023SJohn Marino }
747e4b17023SJohn Marino }
748e4b17023SJohn Marino
749e4b17023SJohn Marino /* If one type is a vector type, return that type. (How the usual
750e4b17023SJohn Marino arithmetic conversions apply to the vector types extension is not
751e4b17023SJohn Marino precisely specified.) */
752e4b17023SJohn Marino if (code1 == VECTOR_TYPE)
753e4b17023SJohn Marino return t1;
754e4b17023SJohn Marino
755e4b17023SJohn Marino if (code2 == VECTOR_TYPE)
756e4b17023SJohn Marino return t2;
757e4b17023SJohn Marino
758e4b17023SJohn Marino /* If one type is complex, form the common type of the non-complex
759e4b17023SJohn Marino components, then make that complex. Use T1 or T2 if it is the
760e4b17023SJohn Marino required type. */
761e4b17023SJohn Marino if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
762e4b17023SJohn Marino {
763e4b17023SJohn Marino tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
764e4b17023SJohn Marino tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
765e4b17023SJohn Marino tree subtype = c_common_type (subtype1, subtype2);
766e4b17023SJohn Marino
767e4b17023SJohn Marino if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
768e4b17023SJohn Marino return t1;
769e4b17023SJohn Marino else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
770e4b17023SJohn Marino return t2;
771e4b17023SJohn Marino else
772e4b17023SJohn Marino return build_complex_type (subtype);
773e4b17023SJohn Marino }
774e4b17023SJohn Marino
775e4b17023SJohn Marino /* If only one is real, use it as the result. */
776e4b17023SJohn Marino
777e4b17023SJohn Marino if (code1 == REAL_TYPE && code2 != REAL_TYPE)
778e4b17023SJohn Marino return t1;
779e4b17023SJohn Marino
780e4b17023SJohn Marino if (code2 == REAL_TYPE && code1 != REAL_TYPE)
781e4b17023SJohn Marino return t2;
782e4b17023SJohn Marino
783e4b17023SJohn Marino /* If both are real and either are decimal floating point types, use
784e4b17023SJohn Marino the decimal floating point type with the greater precision. */
785e4b17023SJohn Marino
786e4b17023SJohn Marino if (code1 == REAL_TYPE && code2 == REAL_TYPE)
787e4b17023SJohn Marino {
788e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == dfloat128_type_node
789e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == dfloat128_type_node)
790e4b17023SJohn Marino return dfloat128_type_node;
791e4b17023SJohn Marino else if (TYPE_MAIN_VARIANT (t1) == dfloat64_type_node
792e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == dfloat64_type_node)
793e4b17023SJohn Marino return dfloat64_type_node;
794e4b17023SJohn Marino else if (TYPE_MAIN_VARIANT (t1) == dfloat32_type_node
795e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == dfloat32_type_node)
796e4b17023SJohn Marino return dfloat32_type_node;
797e4b17023SJohn Marino }
798e4b17023SJohn Marino
799e4b17023SJohn Marino /* Deal with fixed-point types. */
800e4b17023SJohn Marino if (code1 == FIXED_POINT_TYPE || code2 == FIXED_POINT_TYPE)
801e4b17023SJohn Marino {
802e4b17023SJohn Marino unsigned int unsignedp = 0, satp = 0;
803e4b17023SJohn Marino enum machine_mode m1, m2;
804e4b17023SJohn Marino unsigned int fbit1, ibit1, fbit2, ibit2, max_fbit, max_ibit;
805e4b17023SJohn Marino
806e4b17023SJohn Marino m1 = TYPE_MODE (t1);
807e4b17023SJohn Marino m2 = TYPE_MODE (t2);
808e4b17023SJohn Marino
809e4b17023SJohn Marino /* If one input type is saturating, the result type is saturating. */
810e4b17023SJohn Marino if (TYPE_SATURATING (t1) || TYPE_SATURATING (t2))
811e4b17023SJohn Marino satp = 1;
812e4b17023SJohn Marino
813e4b17023SJohn Marino /* If both fixed-point types are unsigned, the result type is unsigned.
814e4b17023SJohn Marino When mixing fixed-point and integer types, follow the sign of the
815e4b17023SJohn Marino fixed-point type.
816e4b17023SJohn Marino Otherwise, the result type is signed. */
817e4b17023SJohn Marino if ((TYPE_UNSIGNED (t1) && TYPE_UNSIGNED (t2)
818e4b17023SJohn Marino && code1 == FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE)
819e4b17023SJohn Marino || (code1 == FIXED_POINT_TYPE && code2 != FIXED_POINT_TYPE
820e4b17023SJohn Marino && TYPE_UNSIGNED (t1))
821e4b17023SJohn Marino || (code1 != FIXED_POINT_TYPE && code2 == FIXED_POINT_TYPE
822e4b17023SJohn Marino && TYPE_UNSIGNED (t2)))
823e4b17023SJohn Marino unsignedp = 1;
824e4b17023SJohn Marino
825e4b17023SJohn Marino /* The result type is signed. */
826e4b17023SJohn Marino if (unsignedp == 0)
827e4b17023SJohn Marino {
828e4b17023SJohn Marino /* If the input type is unsigned, we need to convert to the
829e4b17023SJohn Marino signed type. */
830e4b17023SJohn Marino if (code1 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t1))
831e4b17023SJohn Marino {
832e4b17023SJohn Marino enum mode_class mclass = (enum mode_class) 0;
833e4b17023SJohn Marino if (GET_MODE_CLASS (m1) == MODE_UFRACT)
834e4b17023SJohn Marino mclass = MODE_FRACT;
835e4b17023SJohn Marino else if (GET_MODE_CLASS (m1) == MODE_UACCUM)
836e4b17023SJohn Marino mclass = MODE_ACCUM;
837e4b17023SJohn Marino else
838e4b17023SJohn Marino gcc_unreachable ();
839e4b17023SJohn Marino m1 = mode_for_size (GET_MODE_PRECISION (m1), mclass, 0);
840e4b17023SJohn Marino }
841e4b17023SJohn Marino if (code2 == FIXED_POINT_TYPE && TYPE_UNSIGNED (t2))
842e4b17023SJohn Marino {
843e4b17023SJohn Marino enum mode_class mclass = (enum mode_class) 0;
844e4b17023SJohn Marino if (GET_MODE_CLASS (m2) == MODE_UFRACT)
845e4b17023SJohn Marino mclass = MODE_FRACT;
846e4b17023SJohn Marino else if (GET_MODE_CLASS (m2) == MODE_UACCUM)
847e4b17023SJohn Marino mclass = MODE_ACCUM;
848e4b17023SJohn Marino else
849e4b17023SJohn Marino gcc_unreachable ();
850e4b17023SJohn Marino m2 = mode_for_size (GET_MODE_PRECISION (m2), mclass, 0);
851e4b17023SJohn Marino }
852e4b17023SJohn Marino }
853e4b17023SJohn Marino
854e4b17023SJohn Marino if (code1 == FIXED_POINT_TYPE)
855e4b17023SJohn Marino {
856e4b17023SJohn Marino fbit1 = GET_MODE_FBIT (m1);
857e4b17023SJohn Marino ibit1 = GET_MODE_IBIT (m1);
858e4b17023SJohn Marino }
859e4b17023SJohn Marino else
860e4b17023SJohn Marino {
861e4b17023SJohn Marino fbit1 = 0;
862e4b17023SJohn Marino /* Signed integers need to subtract one sign bit. */
863e4b17023SJohn Marino ibit1 = TYPE_PRECISION (t1) - (!TYPE_UNSIGNED (t1));
864e4b17023SJohn Marino }
865e4b17023SJohn Marino
866e4b17023SJohn Marino if (code2 == FIXED_POINT_TYPE)
867e4b17023SJohn Marino {
868e4b17023SJohn Marino fbit2 = GET_MODE_FBIT (m2);
869e4b17023SJohn Marino ibit2 = GET_MODE_IBIT (m2);
870e4b17023SJohn Marino }
871e4b17023SJohn Marino else
872e4b17023SJohn Marino {
873e4b17023SJohn Marino fbit2 = 0;
874e4b17023SJohn Marino /* Signed integers need to subtract one sign bit. */
875e4b17023SJohn Marino ibit2 = TYPE_PRECISION (t2) - (!TYPE_UNSIGNED (t2));
876e4b17023SJohn Marino }
877e4b17023SJohn Marino
878e4b17023SJohn Marino max_ibit = ibit1 >= ibit2 ? ibit1 : ibit2;
879e4b17023SJohn Marino max_fbit = fbit1 >= fbit2 ? fbit1 : fbit2;
880e4b17023SJohn Marino return c_common_fixed_point_type_for_size (max_ibit, max_fbit, unsignedp,
881e4b17023SJohn Marino satp);
882e4b17023SJohn Marino }
883e4b17023SJohn Marino
884e4b17023SJohn Marino /* Both real or both integers; use the one with greater precision. */
885e4b17023SJohn Marino
886e4b17023SJohn Marino if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
887e4b17023SJohn Marino return t1;
888e4b17023SJohn Marino else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
889e4b17023SJohn Marino return t2;
890e4b17023SJohn Marino
891e4b17023SJohn Marino /* Same precision. Prefer long longs to longs to ints when the
892e4b17023SJohn Marino same precision, following the C99 rules on integer type rank
893e4b17023SJohn Marino (which are equivalent to the C90 rules for C90 types). */
894e4b17023SJohn Marino
895e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
896e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
897e4b17023SJohn Marino return long_long_unsigned_type_node;
898e4b17023SJohn Marino
899e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
900e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
901e4b17023SJohn Marino {
902e4b17023SJohn Marino if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
903e4b17023SJohn Marino return long_long_unsigned_type_node;
904e4b17023SJohn Marino else
905e4b17023SJohn Marino return long_long_integer_type_node;
906e4b17023SJohn Marino }
907e4b17023SJohn Marino
908e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
909e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
910e4b17023SJohn Marino return long_unsigned_type_node;
911e4b17023SJohn Marino
912e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
913e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
914e4b17023SJohn Marino {
915e4b17023SJohn Marino /* But preserve unsignedness from the other type,
916e4b17023SJohn Marino since long cannot hold all the values of an unsigned int. */
917e4b17023SJohn Marino if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
918e4b17023SJohn Marino return long_unsigned_type_node;
919e4b17023SJohn Marino else
920e4b17023SJohn Marino return long_integer_type_node;
921e4b17023SJohn Marino }
922e4b17023SJohn Marino
923e4b17023SJohn Marino /* Likewise, prefer long double to double even if same size. */
924e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
925e4b17023SJohn Marino || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
926e4b17023SJohn Marino return long_double_type_node;
927e4b17023SJohn Marino
928e4b17023SJohn Marino /* Otherwise prefer the unsigned one. */
929e4b17023SJohn Marino
930e4b17023SJohn Marino if (TYPE_UNSIGNED (t1))
931e4b17023SJohn Marino return t1;
932e4b17023SJohn Marino else
933e4b17023SJohn Marino return t2;
934e4b17023SJohn Marino }
935e4b17023SJohn Marino
936e4b17023SJohn Marino /* Wrapper around c_common_type that is used by c-common.c and other
937e4b17023SJohn Marino front end optimizations that remove promotions. ENUMERAL_TYPEs
938e4b17023SJohn Marino are allowed here and are converted to their compatible integer types.
939e4b17023SJohn Marino BOOLEAN_TYPEs are allowed here and return either boolean_type_node or
940e4b17023SJohn Marino preferably a non-Boolean type as the common type. */
941e4b17023SJohn Marino tree
common_type(tree t1,tree t2)942e4b17023SJohn Marino common_type (tree t1, tree t2)
943e4b17023SJohn Marino {
944e4b17023SJohn Marino if (TREE_CODE (t1) == ENUMERAL_TYPE)
945e4b17023SJohn Marino t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
946e4b17023SJohn Marino if (TREE_CODE (t2) == ENUMERAL_TYPE)
947e4b17023SJohn Marino t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
948e4b17023SJohn Marino
949e4b17023SJohn Marino /* If both types are BOOLEAN_TYPE, then return boolean_type_node. */
950e4b17023SJohn Marino if (TREE_CODE (t1) == BOOLEAN_TYPE
951e4b17023SJohn Marino && TREE_CODE (t2) == BOOLEAN_TYPE)
952e4b17023SJohn Marino return boolean_type_node;
953e4b17023SJohn Marino
954e4b17023SJohn Marino /* If either type is BOOLEAN_TYPE, then return the other. */
955e4b17023SJohn Marino if (TREE_CODE (t1) == BOOLEAN_TYPE)
956e4b17023SJohn Marino return t2;
957e4b17023SJohn Marino if (TREE_CODE (t2) == BOOLEAN_TYPE)
958e4b17023SJohn Marino return t1;
959e4b17023SJohn Marino
960e4b17023SJohn Marino return c_common_type (t1, t2);
961e4b17023SJohn Marino }
962e4b17023SJohn Marino
963e4b17023SJohn Marino /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
964e4b17023SJohn Marino or various other operations. Return 2 if they are compatible
965e4b17023SJohn Marino but a warning may be needed if you use them together. */
966e4b17023SJohn Marino
967e4b17023SJohn Marino int
comptypes(tree type1,tree type2)968e4b17023SJohn Marino comptypes (tree type1, tree type2)
969e4b17023SJohn Marino {
970e4b17023SJohn Marino const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
971e4b17023SJohn Marino int val;
972e4b17023SJohn Marino
973e4b17023SJohn Marino val = comptypes_internal (type1, type2, NULL, NULL);
974e4b17023SJohn Marino free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
975e4b17023SJohn Marino
976e4b17023SJohn Marino return val;
977e4b17023SJohn Marino }
978e4b17023SJohn Marino
979e4b17023SJohn Marino /* Like comptypes, but if it returns non-zero because enum and int are
980e4b17023SJohn Marino compatible, it sets *ENUM_AND_INT_P to true. */
981e4b17023SJohn Marino
982e4b17023SJohn Marino static int
comptypes_check_enum_int(tree type1,tree type2,bool * enum_and_int_p)983e4b17023SJohn Marino comptypes_check_enum_int (tree type1, tree type2, bool *enum_and_int_p)
984e4b17023SJohn Marino {
985e4b17023SJohn Marino const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
986e4b17023SJohn Marino int val;
987e4b17023SJohn Marino
988e4b17023SJohn Marino val = comptypes_internal (type1, type2, enum_and_int_p, NULL);
989e4b17023SJohn Marino free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
990e4b17023SJohn Marino
991e4b17023SJohn Marino return val;
992e4b17023SJohn Marino }
993e4b17023SJohn Marino
994e4b17023SJohn Marino /* Like comptypes, but if it returns nonzero for different types, it
995e4b17023SJohn Marino sets *DIFFERENT_TYPES_P to true. */
996e4b17023SJohn Marino
997e4b17023SJohn Marino int
comptypes_check_different_types(tree type1,tree type2,bool * different_types_p)998e4b17023SJohn Marino comptypes_check_different_types (tree type1, tree type2,
999e4b17023SJohn Marino bool *different_types_p)
1000e4b17023SJohn Marino {
1001e4b17023SJohn Marino const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
1002e4b17023SJohn Marino int val;
1003e4b17023SJohn Marino
1004e4b17023SJohn Marino val = comptypes_internal (type1, type2, NULL, different_types_p);
1005e4b17023SJohn Marino free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
1006e4b17023SJohn Marino
1007e4b17023SJohn Marino return val;
1008e4b17023SJohn Marino }
1009e4b17023SJohn Marino
1010e4b17023SJohn Marino /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
1011e4b17023SJohn Marino or various other operations. Return 2 if they are compatible
1012e4b17023SJohn Marino but a warning may be needed if you use them together. If
1013e4b17023SJohn Marino ENUM_AND_INT_P is not NULL, and one type is an enum and the other a
1014e4b17023SJohn Marino compatible integer type, then this sets *ENUM_AND_INT_P to true;
1015e4b17023SJohn Marino *ENUM_AND_INT_P is never set to false. If DIFFERENT_TYPES_P is not
1016e4b17023SJohn Marino NULL, and the types are compatible but different enough not to be
1017e4b17023SJohn Marino permitted in C11 typedef redeclarations, then this sets
1018e4b17023SJohn Marino *DIFFERENT_TYPES_P to true; *DIFFERENT_TYPES_P is never set to
1019e4b17023SJohn Marino false, but may or may not be set if the types are incompatible.
1020e4b17023SJohn Marino This differs from comptypes, in that we don't free the seen
1021e4b17023SJohn Marino types. */
1022e4b17023SJohn Marino
1023e4b17023SJohn Marino static int
comptypes_internal(const_tree type1,const_tree type2,bool * enum_and_int_p,bool * different_types_p)1024e4b17023SJohn Marino comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
1025e4b17023SJohn Marino bool *different_types_p)
1026e4b17023SJohn Marino {
1027e4b17023SJohn Marino const_tree t1 = type1;
1028e4b17023SJohn Marino const_tree t2 = type2;
1029e4b17023SJohn Marino int attrval, val;
1030e4b17023SJohn Marino
1031e4b17023SJohn Marino /* Suppress errors caused by previously reported errors. */
1032e4b17023SJohn Marino
1033e4b17023SJohn Marino if (t1 == t2 || !t1 || !t2
1034e4b17023SJohn Marino || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
1035e4b17023SJohn Marino return 1;
1036e4b17023SJohn Marino
1037e4b17023SJohn Marino /* Enumerated types are compatible with integer types, but this is
1038e4b17023SJohn Marino not transitive: two enumerated types in the same translation unit
1039e4b17023SJohn Marino are compatible with each other only if they are the same type. */
1040e4b17023SJohn Marino
1041e4b17023SJohn Marino if (TREE_CODE (t1) == ENUMERAL_TYPE && TREE_CODE (t2) != ENUMERAL_TYPE)
1042e4b17023SJohn Marino {
1043e4b17023SJohn Marino t1 = c_common_type_for_size (TYPE_PRECISION (t1), TYPE_UNSIGNED (t1));
1044e4b17023SJohn Marino if (TREE_CODE (t2) != VOID_TYPE)
1045e4b17023SJohn Marino {
1046e4b17023SJohn Marino if (enum_and_int_p != NULL)
1047e4b17023SJohn Marino *enum_and_int_p = true;
1048e4b17023SJohn Marino if (different_types_p != NULL)
1049e4b17023SJohn Marino *different_types_p = true;
1050e4b17023SJohn Marino }
1051e4b17023SJohn Marino }
1052e4b17023SJohn Marino else if (TREE_CODE (t2) == ENUMERAL_TYPE && TREE_CODE (t1) != ENUMERAL_TYPE)
1053e4b17023SJohn Marino {
1054e4b17023SJohn Marino t2 = c_common_type_for_size (TYPE_PRECISION (t2), TYPE_UNSIGNED (t2));
1055e4b17023SJohn Marino if (TREE_CODE (t1) != VOID_TYPE)
1056e4b17023SJohn Marino {
1057e4b17023SJohn Marino if (enum_and_int_p != NULL)
1058e4b17023SJohn Marino *enum_and_int_p = true;
1059e4b17023SJohn Marino if (different_types_p != NULL)
1060e4b17023SJohn Marino *different_types_p = true;
1061e4b17023SJohn Marino }
1062e4b17023SJohn Marino }
1063e4b17023SJohn Marino
1064e4b17023SJohn Marino if (t1 == t2)
1065e4b17023SJohn Marino return 1;
1066e4b17023SJohn Marino
1067e4b17023SJohn Marino /* Different classes of types can't be compatible. */
1068e4b17023SJohn Marino
1069e4b17023SJohn Marino if (TREE_CODE (t1) != TREE_CODE (t2))
1070e4b17023SJohn Marino return 0;
1071e4b17023SJohn Marino
1072e4b17023SJohn Marino /* Qualifiers must match. C99 6.7.3p9 */
1073e4b17023SJohn Marino
1074e4b17023SJohn Marino if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
1075e4b17023SJohn Marino return 0;
1076e4b17023SJohn Marino
1077e4b17023SJohn Marino /* Allow for two different type nodes which have essentially the same
1078e4b17023SJohn Marino definition. Note that we already checked for equality of the type
1079e4b17023SJohn Marino qualifiers (just above). */
1080e4b17023SJohn Marino
1081e4b17023SJohn Marino if (TREE_CODE (t1) != ARRAY_TYPE
1082e4b17023SJohn Marino && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
1083e4b17023SJohn Marino return 1;
1084e4b17023SJohn Marino
1085e4b17023SJohn Marino /* 1 if no need for warning yet, 2 if warning cause has been seen. */
1086e4b17023SJohn Marino if (!(attrval = comp_type_attributes (t1, t2)))
1087e4b17023SJohn Marino return 0;
1088e4b17023SJohn Marino
1089e4b17023SJohn Marino /* 1 if no need for warning yet, 2 if warning cause has been seen. */
1090e4b17023SJohn Marino val = 0;
1091e4b17023SJohn Marino
1092e4b17023SJohn Marino switch (TREE_CODE (t1))
1093e4b17023SJohn Marino {
1094e4b17023SJohn Marino case POINTER_TYPE:
1095e4b17023SJohn Marino /* Do not remove mode or aliasing information. */
1096e4b17023SJohn Marino if (TYPE_MODE (t1) != TYPE_MODE (t2)
1097e4b17023SJohn Marino || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
1098e4b17023SJohn Marino break;
1099e4b17023SJohn Marino val = (TREE_TYPE (t1) == TREE_TYPE (t2)
1100e4b17023SJohn Marino ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
1101e4b17023SJohn Marino enum_and_int_p, different_types_p));
1102e4b17023SJohn Marino break;
1103e4b17023SJohn Marino
1104e4b17023SJohn Marino case FUNCTION_TYPE:
1105e4b17023SJohn Marino val = function_types_compatible_p (t1, t2, enum_and_int_p,
1106e4b17023SJohn Marino different_types_p);
1107e4b17023SJohn Marino break;
1108e4b17023SJohn Marino
1109e4b17023SJohn Marino case ARRAY_TYPE:
1110e4b17023SJohn Marino {
1111e4b17023SJohn Marino tree d1 = TYPE_DOMAIN (t1);
1112e4b17023SJohn Marino tree d2 = TYPE_DOMAIN (t2);
1113e4b17023SJohn Marino bool d1_variable, d2_variable;
1114e4b17023SJohn Marino bool d1_zero, d2_zero;
1115e4b17023SJohn Marino val = 1;
1116e4b17023SJohn Marino
1117e4b17023SJohn Marino /* Target types must match incl. qualifiers. */
1118e4b17023SJohn Marino if (TREE_TYPE (t1) != TREE_TYPE (t2)
1119e4b17023SJohn Marino && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
1120e4b17023SJohn Marino enum_and_int_p,
1121e4b17023SJohn Marino different_types_p)))
1122e4b17023SJohn Marino return 0;
1123e4b17023SJohn Marino
1124e4b17023SJohn Marino if (different_types_p != NULL
1125e4b17023SJohn Marino && (d1 == 0) != (d2 == 0))
1126e4b17023SJohn Marino *different_types_p = true;
1127e4b17023SJohn Marino /* Sizes must match unless one is missing or variable. */
1128e4b17023SJohn Marino if (d1 == 0 || d2 == 0 || d1 == d2)
1129e4b17023SJohn Marino break;
1130e4b17023SJohn Marino
1131e4b17023SJohn Marino d1_zero = !TYPE_MAX_VALUE (d1);
1132e4b17023SJohn Marino d2_zero = !TYPE_MAX_VALUE (d2);
1133e4b17023SJohn Marino
1134e4b17023SJohn Marino d1_variable = (!d1_zero
1135e4b17023SJohn Marino && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
1136e4b17023SJohn Marino || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
1137e4b17023SJohn Marino d2_variable = (!d2_zero
1138e4b17023SJohn Marino && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
1139e4b17023SJohn Marino || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
1140e4b17023SJohn Marino d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
1141e4b17023SJohn Marino d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
1142e4b17023SJohn Marino
1143e4b17023SJohn Marino if (different_types_p != NULL
1144e4b17023SJohn Marino && d1_variable != d2_variable)
1145e4b17023SJohn Marino *different_types_p = true;
1146e4b17023SJohn Marino if (d1_variable || d2_variable)
1147e4b17023SJohn Marino break;
1148e4b17023SJohn Marino if (d1_zero && d2_zero)
1149e4b17023SJohn Marino break;
1150e4b17023SJohn Marino if (d1_zero || d2_zero
1151e4b17023SJohn Marino || !tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
1152e4b17023SJohn Marino || !tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
1153e4b17023SJohn Marino val = 0;
1154e4b17023SJohn Marino
1155e4b17023SJohn Marino break;
1156e4b17023SJohn Marino }
1157e4b17023SJohn Marino
1158e4b17023SJohn Marino case ENUMERAL_TYPE:
1159e4b17023SJohn Marino case RECORD_TYPE:
1160e4b17023SJohn Marino case UNION_TYPE:
1161e4b17023SJohn Marino if (val != 1 && !same_translation_unit_p (t1, t2))
1162e4b17023SJohn Marino {
1163e4b17023SJohn Marino tree a1 = TYPE_ATTRIBUTES (t1);
1164e4b17023SJohn Marino tree a2 = TYPE_ATTRIBUTES (t2);
1165e4b17023SJohn Marino
1166e4b17023SJohn Marino if (! attribute_list_contained (a1, a2)
1167e4b17023SJohn Marino && ! attribute_list_contained (a2, a1))
1168e4b17023SJohn Marino break;
1169e4b17023SJohn Marino
1170e4b17023SJohn Marino if (attrval != 2)
1171e4b17023SJohn Marino return tagged_types_tu_compatible_p (t1, t2, enum_and_int_p,
1172e4b17023SJohn Marino different_types_p);
1173e4b17023SJohn Marino val = tagged_types_tu_compatible_p (t1, t2, enum_and_int_p,
1174e4b17023SJohn Marino different_types_p);
1175e4b17023SJohn Marino }
1176e4b17023SJohn Marino break;
1177e4b17023SJohn Marino
1178e4b17023SJohn Marino case VECTOR_TYPE:
1179e4b17023SJohn Marino val = (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
1180e4b17023SJohn Marino && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
1181e4b17023SJohn Marino enum_and_int_p, different_types_p));
1182e4b17023SJohn Marino break;
1183e4b17023SJohn Marino
1184e4b17023SJohn Marino default:
1185e4b17023SJohn Marino break;
1186e4b17023SJohn Marino }
1187e4b17023SJohn Marino return attrval == 2 && val == 1 ? 2 : val;
1188e4b17023SJohn Marino }
1189e4b17023SJohn Marino
1190e4b17023SJohn Marino /* Return 1 if TTL and TTR are pointers to types that are equivalent, ignoring
1191e4b17023SJohn Marino their qualifiers, except for named address spaces. If the pointers point to
1192e4b17023SJohn Marino different named addresses, then we must determine if one address space is a
1193e4b17023SJohn Marino subset of the other. */
1194e4b17023SJohn Marino
1195e4b17023SJohn Marino static int
comp_target_types(location_t location,tree ttl,tree ttr)1196e4b17023SJohn Marino comp_target_types (location_t location, tree ttl, tree ttr)
1197e4b17023SJohn Marino {
1198e4b17023SJohn Marino int val;
1199e4b17023SJohn Marino tree mvl = TREE_TYPE (ttl);
1200e4b17023SJohn Marino tree mvr = TREE_TYPE (ttr);
1201e4b17023SJohn Marino addr_space_t asl = TYPE_ADDR_SPACE (mvl);
1202e4b17023SJohn Marino addr_space_t asr = TYPE_ADDR_SPACE (mvr);
1203e4b17023SJohn Marino addr_space_t as_common;
1204e4b17023SJohn Marino bool enum_and_int_p;
1205e4b17023SJohn Marino
1206e4b17023SJohn Marino /* Fail if pointers point to incompatible address spaces. */
1207e4b17023SJohn Marino if (!addr_space_superset (asl, asr, &as_common))
1208e4b17023SJohn Marino return 0;
1209e4b17023SJohn Marino
1210e4b17023SJohn Marino /* Do not lose qualifiers on element types of array types that are
1211e4b17023SJohn Marino pointer targets by taking their TYPE_MAIN_VARIANT. */
1212e4b17023SJohn Marino if (TREE_CODE (mvl) != ARRAY_TYPE)
1213e4b17023SJohn Marino mvl = TYPE_MAIN_VARIANT (mvl);
1214e4b17023SJohn Marino if (TREE_CODE (mvr) != ARRAY_TYPE)
1215e4b17023SJohn Marino mvr = TYPE_MAIN_VARIANT (mvr);
1216e4b17023SJohn Marino enum_and_int_p = false;
1217e4b17023SJohn Marino val = comptypes_check_enum_int (mvl, mvr, &enum_and_int_p);
1218e4b17023SJohn Marino
1219e4b17023SJohn Marino if (val == 2)
1220e4b17023SJohn Marino pedwarn (location, OPT_pedantic, "types are not quite compatible");
1221e4b17023SJohn Marino
1222e4b17023SJohn Marino if (val == 1 && enum_and_int_p && warn_cxx_compat)
1223e4b17023SJohn Marino warning_at (location, OPT_Wc___compat,
1224e4b17023SJohn Marino "pointer target types incompatible in C++");
1225e4b17023SJohn Marino
1226e4b17023SJohn Marino return val;
1227e4b17023SJohn Marino }
1228e4b17023SJohn Marino
1229e4b17023SJohn Marino /* Subroutines of `comptypes'. */
1230e4b17023SJohn Marino
1231e4b17023SJohn Marino /* Determine whether two trees derive from the same translation unit.
1232e4b17023SJohn Marino If the CONTEXT chain ends in a null, that tree's context is still
1233e4b17023SJohn Marino being parsed, so if two trees have context chains ending in null,
1234e4b17023SJohn Marino they're in the same translation unit. */
1235e4b17023SJohn Marino int
same_translation_unit_p(const_tree t1,const_tree t2)1236e4b17023SJohn Marino same_translation_unit_p (const_tree t1, const_tree t2)
1237e4b17023SJohn Marino {
1238e4b17023SJohn Marino while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
1239e4b17023SJohn Marino switch (TREE_CODE_CLASS (TREE_CODE (t1)))
1240e4b17023SJohn Marino {
1241e4b17023SJohn Marino case tcc_declaration:
1242e4b17023SJohn Marino t1 = DECL_CONTEXT (t1); break;
1243e4b17023SJohn Marino case tcc_type:
1244e4b17023SJohn Marino t1 = TYPE_CONTEXT (t1); break;
1245e4b17023SJohn Marino case tcc_exceptional:
1246e4b17023SJohn Marino t1 = BLOCK_SUPERCONTEXT (t1); break; /* assume block */
1247e4b17023SJohn Marino default: gcc_unreachable ();
1248e4b17023SJohn Marino }
1249e4b17023SJohn Marino
1250e4b17023SJohn Marino while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
1251e4b17023SJohn Marino switch (TREE_CODE_CLASS (TREE_CODE (t2)))
1252e4b17023SJohn Marino {
1253e4b17023SJohn Marino case tcc_declaration:
1254e4b17023SJohn Marino t2 = DECL_CONTEXT (t2); break;
1255e4b17023SJohn Marino case tcc_type:
1256e4b17023SJohn Marino t2 = TYPE_CONTEXT (t2); break;
1257e4b17023SJohn Marino case tcc_exceptional:
1258e4b17023SJohn Marino t2 = BLOCK_SUPERCONTEXT (t2); break; /* assume block */
1259e4b17023SJohn Marino default: gcc_unreachable ();
1260e4b17023SJohn Marino }
1261e4b17023SJohn Marino
1262e4b17023SJohn Marino return t1 == t2;
1263e4b17023SJohn Marino }
1264e4b17023SJohn Marino
1265e4b17023SJohn Marino /* Allocate the seen two types, assuming that they are compatible. */
1266e4b17023SJohn Marino
1267e4b17023SJohn Marino static struct tagged_tu_seen_cache *
alloc_tagged_tu_seen_cache(const_tree t1,const_tree t2)1268e4b17023SJohn Marino alloc_tagged_tu_seen_cache (const_tree t1, const_tree t2)
1269e4b17023SJohn Marino {
1270e4b17023SJohn Marino struct tagged_tu_seen_cache *tu = XNEW (struct tagged_tu_seen_cache);
1271e4b17023SJohn Marino tu->next = tagged_tu_seen_base;
1272e4b17023SJohn Marino tu->t1 = t1;
1273e4b17023SJohn Marino tu->t2 = t2;
1274e4b17023SJohn Marino
1275e4b17023SJohn Marino tagged_tu_seen_base = tu;
1276e4b17023SJohn Marino
1277e4b17023SJohn Marino /* The C standard says that two structures in different translation
1278e4b17023SJohn Marino units are compatible with each other only if the types of their
1279e4b17023SJohn Marino fields are compatible (among other things). We assume that they
1280e4b17023SJohn Marino are compatible until proven otherwise when building the cache.
1281e4b17023SJohn Marino An example where this can occur is:
1282e4b17023SJohn Marino struct a
1283e4b17023SJohn Marino {
1284e4b17023SJohn Marino struct a *next;
1285e4b17023SJohn Marino };
1286e4b17023SJohn Marino If we are comparing this against a similar struct in another TU,
1287e4b17023SJohn Marino and did not assume they were compatible, we end up with an infinite
1288e4b17023SJohn Marino loop. */
1289e4b17023SJohn Marino tu->val = 1;
1290e4b17023SJohn Marino return tu;
1291e4b17023SJohn Marino }
1292e4b17023SJohn Marino
1293e4b17023SJohn Marino /* Free the seen types until we get to TU_TIL. */
1294e4b17023SJohn Marino
1295e4b17023SJohn Marino static void
free_all_tagged_tu_seen_up_to(const struct tagged_tu_seen_cache * tu_til)1296e4b17023SJohn Marino free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *tu_til)
1297e4b17023SJohn Marino {
1298e4b17023SJohn Marino const struct tagged_tu_seen_cache *tu = tagged_tu_seen_base;
1299e4b17023SJohn Marino while (tu != tu_til)
1300e4b17023SJohn Marino {
1301e4b17023SJohn Marino const struct tagged_tu_seen_cache *const tu1
1302e4b17023SJohn Marino = (const struct tagged_tu_seen_cache *) tu;
1303e4b17023SJohn Marino tu = tu1->next;
1304e4b17023SJohn Marino free (CONST_CAST (struct tagged_tu_seen_cache *, tu1));
1305e4b17023SJohn Marino }
1306e4b17023SJohn Marino tagged_tu_seen_base = tu_til;
1307e4b17023SJohn Marino }
1308e4b17023SJohn Marino
1309e4b17023SJohn Marino /* Return 1 if two 'struct', 'union', or 'enum' types T1 and T2 are
1310e4b17023SJohn Marino compatible. If the two types are not the same (which has been
1311e4b17023SJohn Marino checked earlier), this can only happen when multiple translation
1312e4b17023SJohn Marino units are being compiled. See C99 6.2.7 paragraph 1 for the exact
1313e4b17023SJohn Marino rules. ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in
1314e4b17023SJohn Marino comptypes_internal. */
1315e4b17023SJohn Marino
1316e4b17023SJohn Marino static int
tagged_types_tu_compatible_p(const_tree t1,const_tree t2,bool * enum_and_int_p,bool * different_types_p)1317e4b17023SJohn Marino tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
1318e4b17023SJohn Marino bool *enum_and_int_p, bool *different_types_p)
1319e4b17023SJohn Marino {
1320e4b17023SJohn Marino tree s1, s2;
1321e4b17023SJohn Marino bool needs_warning = false;
1322e4b17023SJohn Marino
1323e4b17023SJohn Marino /* We have to verify that the tags of the types are the same. This
1324e4b17023SJohn Marino is harder than it looks because this may be a typedef, so we have
1325e4b17023SJohn Marino to go look at the original type. It may even be a typedef of a
1326e4b17023SJohn Marino typedef...
1327e4b17023SJohn Marino In the case of compiler-created builtin structs the TYPE_DECL
1328e4b17023SJohn Marino may be a dummy, with no DECL_ORIGINAL_TYPE. Don't fault. */
1329e4b17023SJohn Marino while (TYPE_NAME (t1)
1330e4b17023SJohn Marino && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
1331e4b17023SJohn Marino && DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
1332e4b17023SJohn Marino t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
1333e4b17023SJohn Marino
1334e4b17023SJohn Marino while (TYPE_NAME (t2)
1335e4b17023SJohn Marino && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
1336e4b17023SJohn Marino && DECL_ORIGINAL_TYPE (TYPE_NAME (t2)))
1337e4b17023SJohn Marino t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
1338e4b17023SJohn Marino
1339e4b17023SJohn Marino /* C90 didn't have the requirement that the two tags be the same. */
1340e4b17023SJohn Marino if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
1341e4b17023SJohn Marino return 0;
1342e4b17023SJohn Marino
1343e4b17023SJohn Marino /* C90 didn't say what happened if one or both of the types were
1344e4b17023SJohn Marino incomplete; we choose to follow C99 rules here, which is that they
1345e4b17023SJohn Marino are compatible. */
1346e4b17023SJohn Marino if (TYPE_SIZE (t1) == NULL
1347e4b17023SJohn Marino || TYPE_SIZE (t2) == NULL)
1348e4b17023SJohn Marino return 1;
1349e4b17023SJohn Marino
1350e4b17023SJohn Marino {
1351e4b17023SJohn Marino const struct tagged_tu_seen_cache * tts_i;
1352e4b17023SJohn Marino for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
1353e4b17023SJohn Marino if (tts_i->t1 == t1 && tts_i->t2 == t2)
1354e4b17023SJohn Marino return tts_i->val;
1355e4b17023SJohn Marino }
1356e4b17023SJohn Marino
1357e4b17023SJohn Marino switch (TREE_CODE (t1))
1358e4b17023SJohn Marino {
1359e4b17023SJohn Marino case ENUMERAL_TYPE:
1360e4b17023SJohn Marino {
1361e4b17023SJohn Marino struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1362e4b17023SJohn Marino /* Speed up the case where the type values are in the same order. */
1363e4b17023SJohn Marino tree tv1 = TYPE_VALUES (t1);
1364e4b17023SJohn Marino tree tv2 = TYPE_VALUES (t2);
1365e4b17023SJohn Marino
1366e4b17023SJohn Marino if (tv1 == tv2)
1367e4b17023SJohn Marino {
1368e4b17023SJohn Marino return 1;
1369e4b17023SJohn Marino }
1370e4b17023SJohn Marino
1371e4b17023SJohn Marino for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
1372e4b17023SJohn Marino {
1373e4b17023SJohn Marino if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
1374e4b17023SJohn Marino break;
1375e4b17023SJohn Marino if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
1376e4b17023SJohn Marino {
1377e4b17023SJohn Marino tu->val = 0;
1378e4b17023SJohn Marino return 0;
1379e4b17023SJohn Marino }
1380e4b17023SJohn Marino }
1381e4b17023SJohn Marino
1382e4b17023SJohn Marino if (tv1 == NULL_TREE && tv2 == NULL_TREE)
1383e4b17023SJohn Marino {
1384e4b17023SJohn Marino return 1;
1385e4b17023SJohn Marino }
1386e4b17023SJohn Marino if (tv1 == NULL_TREE || tv2 == NULL_TREE)
1387e4b17023SJohn Marino {
1388e4b17023SJohn Marino tu->val = 0;
1389e4b17023SJohn Marino return 0;
1390e4b17023SJohn Marino }
1391e4b17023SJohn Marino
1392e4b17023SJohn Marino if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
1393e4b17023SJohn Marino {
1394e4b17023SJohn Marino tu->val = 0;
1395e4b17023SJohn Marino return 0;
1396e4b17023SJohn Marino }
1397e4b17023SJohn Marino
1398e4b17023SJohn Marino for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
1399e4b17023SJohn Marino {
1400e4b17023SJohn Marino s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
1401e4b17023SJohn Marino if (s2 == NULL
1402e4b17023SJohn Marino || simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1)
1403e4b17023SJohn Marino {
1404e4b17023SJohn Marino tu->val = 0;
1405e4b17023SJohn Marino return 0;
1406e4b17023SJohn Marino }
1407e4b17023SJohn Marino }
1408e4b17023SJohn Marino return 1;
1409e4b17023SJohn Marino }
1410e4b17023SJohn Marino
1411e4b17023SJohn Marino case UNION_TYPE:
1412e4b17023SJohn Marino {
1413e4b17023SJohn Marino struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1414e4b17023SJohn Marino if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2)))
1415e4b17023SJohn Marino {
1416e4b17023SJohn Marino tu->val = 0;
1417e4b17023SJohn Marino return 0;
1418e4b17023SJohn Marino }
1419e4b17023SJohn Marino
1420e4b17023SJohn Marino /* Speed up the common case where the fields are in the same order. */
1421e4b17023SJohn Marino for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); s1 && s2;
1422e4b17023SJohn Marino s1 = DECL_CHAIN (s1), s2 = DECL_CHAIN (s2))
1423e4b17023SJohn Marino {
1424e4b17023SJohn Marino int result;
1425e4b17023SJohn Marino
1426e4b17023SJohn Marino if (DECL_NAME (s1) != DECL_NAME (s2))
1427e4b17023SJohn Marino break;
1428e4b17023SJohn Marino result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
1429e4b17023SJohn Marino enum_and_int_p, different_types_p);
1430e4b17023SJohn Marino
1431e4b17023SJohn Marino if (result != 1 && !DECL_NAME (s1))
1432e4b17023SJohn Marino break;
1433e4b17023SJohn Marino if (result == 0)
1434e4b17023SJohn Marino {
1435e4b17023SJohn Marino tu->val = 0;
1436e4b17023SJohn Marino return 0;
1437e4b17023SJohn Marino }
1438e4b17023SJohn Marino if (result == 2)
1439e4b17023SJohn Marino needs_warning = true;
1440e4b17023SJohn Marino
1441e4b17023SJohn Marino if (TREE_CODE (s1) == FIELD_DECL
1442e4b17023SJohn Marino && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1443e4b17023SJohn Marino DECL_FIELD_BIT_OFFSET (s2)) != 1)
1444e4b17023SJohn Marino {
1445e4b17023SJohn Marino tu->val = 0;
1446e4b17023SJohn Marino return 0;
1447e4b17023SJohn Marino }
1448e4b17023SJohn Marino }
1449e4b17023SJohn Marino if (!s1 && !s2)
1450e4b17023SJohn Marino {
1451e4b17023SJohn Marino tu->val = needs_warning ? 2 : 1;
1452e4b17023SJohn Marino return tu->val;
1453e4b17023SJohn Marino }
1454e4b17023SJohn Marino
1455e4b17023SJohn Marino for (s1 = TYPE_FIELDS (t1); s1; s1 = DECL_CHAIN (s1))
1456e4b17023SJohn Marino {
1457e4b17023SJohn Marino bool ok = false;
1458e4b17023SJohn Marino
1459e4b17023SJohn Marino for (s2 = TYPE_FIELDS (t2); s2; s2 = DECL_CHAIN (s2))
1460e4b17023SJohn Marino if (DECL_NAME (s1) == DECL_NAME (s2))
1461e4b17023SJohn Marino {
1462e4b17023SJohn Marino int result;
1463e4b17023SJohn Marino
1464e4b17023SJohn Marino result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
1465e4b17023SJohn Marino enum_and_int_p,
1466e4b17023SJohn Marino different_types_p);
1467e4b17023SJohn Marino
1468e4b17023SJohn Marino if (result != 1 && !DECL_NAME (s1))
1469e4b17023SJohn Marino continue;
1470e4b17023SJohn Marino if (result == 0)
1471e4b17023SJohn Marino {
1472e4b17023SJohn Marino tu->val = 0;
1473e4b17023SJohn Marino return 0;
1474e4b17023SJohn Marino }
1475e4b17023SJohn Marino if (result == 2)
1476e4b17023SJohn Marino needs_warning = true;
1477e4b17023SJohn Marino
1478e4b17023SJohn Marino if (TREE_CODE (s1) == FIELD_DECL
1479e4b17023SJohn Marino && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1480e4b17023SJohn Marino DECL_FIELD_BIT_OFFSET (s2)) != 1)
1481e4b17023SJohn Marino break;
1482e4b17023SJohn Marino
1483e4b17023SJohn Marino ok = true;
1484e4b17023SJohn Marino break;
1485e4b17023SJohn Marino }
1486e4b17023SJohn Marino if (!ok)
1487e4b17023SJohn Marino {
1488e4b17023SJohn Marino tu->val = 0;
1489e4b17023SJohn Marino return 0;
1490e4b17023SJohn Marino }
1491e4b17023SJohn Marino }
1492e4b17023SJohn Marino tu->val = needs_warning ? 2 : 10;
1493e4b17023SJohn Marino return tu->val;
1494e4b17023SJohn Marino }
1495e4b17023SJohn Marino
1496e4b17023SJohn Marino case RECORD_TYPE:
1497e4b17023SJohn Marino {
1498e4b17023SJohn Marino struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1499e4b17023SJohn Marino
1500e4b17023SJohn Marino for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
1501e4b17023SJohn Marino s1 && s2;
1502e4b17023SJohn Marino s1 = DECL_CHAIN (s1), s2 = DECL_CHAIN (s2))
1503e4b17023SJohn Marino {
1504e4b17023SJohn Marino int result;
1505e4b17023SJohn Marino if (TREE_CODE (s1) != TREE_CODE (s2)
1506e4b17023SJohn Marino || DECL_NAME (s1) != DECL_NAME (s2))
1507e4b17023SJohn Marino break;
1508e4b17023SJohn Marino result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
1509e4b17023SJohn Marino enum_and_int_p, different_types_p);
1510e4b17023SJohn Marino if (result == 0)
1511e4b17023SJohn Marino break;
1512e4b17023SJohn Marino if (result == 2)
1513e4b17023SJohn Marino needs_warning = true;
1514e4b17023SJohn Marino
1515e4b17023SJohn Marino if (TREE_CODE (s1) == FIELD_DECL
1516e4b17023SJohn Marino && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1517e4b17023SJohn Marino DECL_FIELD_BIT_OFFSET (s2)) != 1)
1518e4b17023SJohn Marino break;
1519e4b17023SJohn Marino }
1520e4b17023SJohn Marino if (s1 && s2)
1521e4b17023SJohn Marino tu->val = 0;
1522e4b17023SJohn Marino else
1523e4b17023SJohn Marino tu->val = needs_warning ? 2 : 1;
1524e4b17023SJohn Marino return tu->val;
1525e4b17023SJohn Marino }
1526e4b17023SJohn Marino
1527e4b17023SJohn Marino default:
1528e4b17023SJohn Marino gcc_unreachable ();
1529e4b17023SJohn Marino }
1530e4b17023SJohn Marino }
1531e4b17023SJohn Marino
1532e4b17023SJohn Marino /* Return 1 if two function types F1 and F2 are compatible.
1533e4b17023SJohn Marino If either type specifies no argument types,
1534e4b17023SJohn Marino the other must specify a fixed number of self-promoting arg types.
1535e4b17023SJohn Marino Otherwise, if one type specifies only the number of arguments,
1536e4b17023SJohn Marino the other must specify that number of self-promoting arg types.
1537e4b17023SJohn Marino Otherwise, the argument types must match.
1538e4b17023SJohn Marino ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in comptypes_internal. */
1539e4b17023SJohn Marino
1540e4b17023SJohn Marino static int
function_types_compatible_p(const_tree f1,const_tree f2,bool * enum_and_int_p,bool * different_types_p)1541e4b17023SJohn Marino function_types_compatible_p (const_tree f1, const_tree f2,
1542e4b17023SJohn Marino bool *enum_and_int_p, bool *different_types_p)
1543e4b17023SJohn Marino {
1544e4b17023SJohn Marino tree args1, args2;
1545e4b17023SJohn Marino /* 1 if no need for warning yet, 2 if warning cause has been seen. */
1546e4b17023SJohn Marino int val = 1;
1547e4b17023SJohn Marino int val1;
1548e4b17023SJohn Marino tree ret1, ret2;
1549e4b17023SJohn Marino
1550e4b17023SJohn Marino ret1 = TREE_TYPE (f1);
1551e4b17023SJohn Marino ret2 = TREE_TYPE (f2);
1552e4b17023SJohn Marino
1553e4b17023SJohn Marino /* 'volatile' qualifiers on a function's return type used to mean
1554e4b17023SJohn Marino the function is noreturn. */
1555e4b17023SJohn Marino if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
1556e4b17023SJohn Marino pedwarn (input_location, 0, "function return types not compatible due to %<volatile%>");
1557e4b17023SJohn Marino if (TYPE_VOLATILE (ret1))
1558e4b17023SJohn Marino ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
1559e4b17023SJohn Marino TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
1560e4b17023SJohn Marino if (TYPE_VOLATILE (ret2))
1561e4b17023SJohn Marino ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
1562e4b17023SJohn Marino TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
1563e4b17023SJohn Marino val = comptypes_internal (ret1, ret2, enum_and_int_p, different_types_p);
1564e4b17023SJohn Marino if (val == 0)
1565e4b17023SJohn Marino return 0;
1566e4b17023SJohn Marino
1567e4b17023SJohn Marino args1 = TYPE_ARG_TYPES (f1);
1568e4b17023SJohn Marino args2 = TYPE_ARG_TYPES (f2);
1569e4b17023SJohn Marino
1570e4b17023SJohn Marino if (different_types_p != NULL
1571e4b17023SJohn Marino && (args1 == 0) != (args2 == 0))
1572e4b17023SJohn Marino *different_types_p = true;
1573e4b17023SJohn Marino
1574e4b17023SJohn Marino /* An unspecified parmlist matches any specified parmlist
1575e4b17023SJohn Marino whose argument types don't need default promotions. */
1576e4b17023SJohn Marino
1577e4b17023SJohn Marino if (args1 == 0)
1578e4b17023SJohn Marino {
1579e4b17023SJohn Marino if (!self_promoting_args_p (args2))
1580e4b17023SJohn Marino return 0;
1581e4b17023SJohn Marino /* If one of these types comes from a non-prototype fn definition,
1582e4b17023SJohn Marino compare that with the other type's arglist.
1583e4b17023SJohn Marino If they don't match, ask for a warning (but no error). */
1584e4b17023SJohn Marino if (TYPE_ACTUAL_ARG_TYPES (f1)
1585e4b17023SJohn Marino && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1),
1586e4b17023SJohn Marino enum_and_int_p, different_types_p))
1587e4b17023SJohn Marino val = 2;
1588e4b17023SJohn Marino return val;
1589e4b17023SJohn Marino }
1590e4b17023SJohn Marino if (args2 == 0)
1591e4b17023SJohn Marino {
1592e4b17023SJohn Marino if (!self_promoting_args_p (args1))
1593e4b17023SJohn Marino return 0;
1594e4b17023SJohn Marino if (TYPE_ACTUAL_ARG_TYPES (f2)
1595e4b17023SJohn Marino && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2),
1596e4b17023SJohn Marino enum_and_int_p, different_types_p))
1597e4b17023SJohn Marino val = 2;
1598e4b17023SJohn Marino return val;
1599e4b17023SJohn Marino }
1600e4b17023SJohn Marino
1601e4b17023SJohn Marino /* Both types have argument lists: compare them and propagate results. */
1602e4b17023SJohn Marino val1 = type_lists_compatible_p (args1, args2, enum_and_int_p,
1603e4b17023SJohn Marino different_types_p);
1604e4b17023SJohn Marino return val1 != 1 ? val1 : val;
1605e4b17023SJohn Marino }
1606e4b17023SJohn Marino
1607e4b17023SJohn Marino /* Check two lists of types for compatibility, returning 0 for
1608e4b17023SJohn Marino incompatible, 1 for compatible, or 2 for compatible with
1609e4b17023SJohn Marino warning. ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in
1610e4b17023SJohn Marino comptypes_internal. */
1611e4b17023SJohn Marino
1612e4b17023SJohn Marino static int
type_lists_compatible_p(const_tree args1,const_tree args2,bool * enum_and_int_p,bool * different_types_p)1613e4b17023SJohn Marino type_lists_compatible_p (const_tree args1, const_tree args2,
1614e4b17023SJohn Marino bool *enum_and_int_p, bool *different_types_p)
1615e4b17023SJohn Marino {
1616e4b17023SJohn Marino /* 1 if no need for warning yet, 2 if warning cause has been seen. */
1617e4b17023SJohn Marino int val = 1;
1618e4b17023SJohn Marino int newval = 0;
1619e4b17023SJohn Marino
1620e4b17023SJohn Marino while (1)
1621e4b17023SJohn Marino {
1622e4b17023SJohn Marino tree a1, mv1, a2, mv2;
1623e4b17023SJohn Marino if (args1 == 0 && args2 == 0)
1624e4b17023SJohn Marino return val;
1625e4b17023SJohn Marino /* If one list is shorter than the other,
1626e4b17023SJohn Marino they fail to match. */
1627e4b17023SJohn Marino if (args1 == 0 || args2 == 0)
1628e4b17023SJohn Marino return 0;
1629e4b17023SJohn Marino mv1 = a1 = TREE_VALUE (args1);
1630e4b17023SJohn Marino mv2 = a2 = TREE_VALUE (args2);
1631e4b17023SJohn Marino if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE)
1632e4b17023SJohn Marino mv1 = TYPE_MAIN_VARIANT (mv1);
1633e4b17023SJohn Marino if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE)
1634e4b17023SJohn Marino mv2 = TYPE_MAIN_VARIANT (mv2);
1635e4b17023SJohn Marino /* A null pointer instead of a type
1636e4b17023SJohn Marino means there is supposed to be an argument
1637e4b17023SJohn Marino but nothing is specified about what type it has.
1638e4b17023SJohn Marino So match anything that self-promotes. */
1639e4b17023SJohn Marino if (different_types_p != NULL
1640e4b17023SJohn Marino && (a1 == 0) != (a2 == 0))
1641e4b17023SJohn Marino *different_types_p = true;
1642e4b17023SJohn Marino if (a1 == 0)
1643e4b17023SJohn Marino {
1644e4b17023SJohn Marino if (c_type_promotes_to (a2) != a2)
1645e4b17023SJohn Marino return 0;
1646e4b17023SJohn Marino }
1647e4b17023SJohn Marino else if (a2 == 0)
1648e4b17023SJohn Marino {
1649e4b17023SJohn Marino if (c_type_promotes_to (a1) != a1)
1650e4b17023SJohn Marino return 0;
1651e4b17023SJohn Marino }
1652e4b17023SJohn Marino /* If one of the lists has an error marker, ignore this arg. */
1653e4b17023SJohn Marino else if (TREE_CODE (a1) == ERROR_MARK
1654e4b17023SJohn Marino || TREE_CODE (a2) == ERROR_MARK)
1655e4b17023SJohn Marino ;
1656e4b17023SJohn Marino else if (!(newval = comptypes_internal (mv1, mv2, enum_and_int_p,
1657e4b17023SJohn Marino different_types_p)))
1658e4b17023SJohn Marino {
1659e4b17023SJohn Marino if (different_types_p != NULL)
1660e4b17023SJohn Marino *different_types_p = true;
1661e4b17023SJohn Marino /* Allow wait (union {union wait *u; int *i} *)
1662e4b17023SJohn Marino and wait (union wait *) to be compatible. */
1663e4b17023SJohn Marino if (TREE_CODE (a1) == UNION_TYPE
1664e4b17023SJohn Marino && (TYPE_NAME (a1) == 0
1665e4b17023SJohn Marino || TYPE_TRANSPARENT_AGGR (a1))
1666e4b17023SJohn Marino && TREE_CODE (TYPE_SIZE (a1)) == INTEGER_CST
1667e4b17023SJohn Marino && tree_int_cst_equal (TYPE_SIZE (a1),
1668e4b17023SJohn Marino TYPE_SIZE (a2)))
1669e4b17023SJohn Marino {
1670e4b17023SJohn Marino tree memb;
1671e4b17023SJohn Marino for (memb = TYPE_FIELDS (a1);
1672e4b17023SJohn Marino memb; memb = DECL_CHAIN (memb))
1673e4b17023SJohn Marino {
1674e4b17023SJohn Marino tree mv3 = TREE_TYPE (memb);
1675e4b17023SJohn Marino if (mv3 && mv3 != error_mark_node
1676e4b17023SJohn Marino && TREE_CODE (mv3) != ARRAY_TYPE)
1677e4b17023SJohn Marino mv3 = TYPE_MAIN_VARIANT (mv3);
1678e4b17023SJohn Marino if (comptypes_internal (mv3, mv2, enum_and_int_p,
1679e4b17023SJohn Marino different_types_p))
1680e4b17023SJohn Marino break;
1681e4b17023SJohn Marino }
1682e4b17023SJohn Marino if (memb == 0)
1683e4b17023SJohn Marino return 0;
1684e4b17023SJohn Marino }
1685e4b17023SJohn Marino else if (TREE_CODE (a2) == UNION_TYPE
1686e4b17023SJohn Marino && (TYPE_NAME (a2) == 0
1687e4b17023SJohn Marino || TYPE_TRANSPARENT_AGGR (a2))
1688e4b17023SJohn Marino && TREE_CODE (TYPE_SIZE (a2)) == INTEGER_CST
1689e4b17023SJohn Marino && tree_int_cst_equal (TYPE_SIZE (a2),
1690e4b17023SJohn Marino TYPE_SIZE (a1)))
1691e4b17023SJohn Marino {
1692e4b17023SJohn Marino tree memb;
1693e4b17023SJohn Marino for (memb = TYPE_FIELDS (a2);
1694e4b17023SJohn Marino memb; memb = DECL_CHAIN (memb))
1695e4b17023SJohn Marino {
1696e4b17023SJohn Marino tree mv3 = TREE_TYPE (memb);
1697e4b17023SJohn Marino if (mv3 && mv3 != error_mark_node
1698e4b17023SJohn Marino && TREE_CODE (mv3) != ARRAY_TYPE)
1699e4b17023SJohn Marino mv3 = TYPE_MAIN_VARIANT (mv3);
1700e4b17023SJohn Marino if (comptypes_internal (mv3, mv1, enum_and_int_p,
1701e4b17023SJohn Marino different_types_p))
1702e4b17023SJohn Marino break;
1703e4b17023SJohn Marino }
1704e4b17023SJohn Marino if (memb == 0)
1705e4b17023SJohn Marino return 0;
1706e4b17023SJohn Marino }
1707e4b17023SJohn Marino else
1708e4b17023SJohn Marino return 0;
1709e4b17023SJohn Marino }
1710e4b17023SJohn Marino
1711e4b17023SJohn Marino /* comptypes said ok, but record if it said to warn. */
1712e4b17023SJohn Marino if (newval > val)
1713e4b17023SJohn Marino val = newval;
1714e4b17023SJohn Marino
1715e4b17023SJohn Marino args1 = TREE_CHAIN (args1);
1716e4b17023SJohn Marino args2 = TREE_CHAIN (args2);
1717e4b17023SJohn Marino }
1718e4b17023SJohn Marino }
1719e4b17023SJohn Marino
1720e4b17023SJohn Marino /* Compute the size to increment a pointer by. */
1721e4b17023SJohn Marino
1722e4b17023SJohn Marino static tree
c_size_in_bytes(const_tree type)1723e4b17023SJohn Marino c_size_in_bytes (const_tree type)
1724e4b17023SJohn Marino {
1725e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
1726e4b17023SJohn Marino
1727e4b17023SJohn Marino if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
1728e4b17023SJohn Marino return size_one_node;
1729e4b17023SJohn Marino
1730e4b17023SJohn Marino if (!COMPLETE_OR_VOID_TYPE_P (type))
1731e4b17023SJohn Marino {
1732e4b17023SJohn Marino error ("arithmetic on pointer to an incomplete type");
1733e4b17023SJohn Marino return size_one_node;
1734e4b17023SJohn Marino }
1735e4b17023SJohn Marino
1736e4b17023SJohn Marino /* Convert in case a char is more than one unit. */
1737e4b17023SJohn Marino return size_binop_loc (input_location, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
1738e4b17023SJohn Marino size_int (TYPE_PRECISION (char_type_node)
1739e4b17023SJohn Marino / BITS_PER_UNIT));
1740e4b17023SJohn Marino }
1741e4b17023SJohn Marino
1742e4b17023SJohn Marino /* Return either DECL or its known constant value (if it has one). */
1743e4b17023SJohn Marino
1744e4b17023SJohn Marino tree
decl_constant_value(tree decl)1745e4b17023SJohn Marino decl_constant_value (tree decl)
1746e4b17023SJohn Marino {
1747e4b17023SJohn Marino if (/* Don't change a variable array bound or initial value to a constant
1748e4b17023SJohn Marino in a place where a variable is invalid. Note that DECL_INITIAL
1749e4b17023SJohn Marino isn't valid for a PARM_DECL. */
1750e4b17023SJohn Marino current_function_decl != 0
1751e4b17023SJohn Marino && TREE_CODE (decl) != PARM_DECL
1752e4b17023SJohn Marino && !TREE_THIS_VOLATILE (decl)
1753e4b17023SJohn Marino && TREE_READONLY (decl)
1754e4b17023SJohn Marino && DECL_INITIAL (decl) != 0
1755e4b17023SJohn Marino && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
1756e4b17023SJohn Marino /* This is invalid if initial value is not constant.
1757e4b17023SJohn Marino If it has either a function call, a memory reference,
1758e4b17023SJohn Marino or a variable, then re-evaluating it could give different results. */
1759e4b17023SJohn Marino && TREE_CONSTANT (DECL_INITIAL (decl))
1760e4b17023SJohn Marino /* Check for cases where this is sub-optimal, even though valid. */
1761e4b17023SJohn Marino && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
1762e4b17023SJohn Marino return DECL_INITIAL (decl);
1763e4b17023SJohn Marino return decl;
1764e4b17023SJohn Marino }
1765e4b17023SJohn Marino
1766e4b17023SJohn Marino /* Convert the array expression EXP to a pointer. */
1767e4b17023SJohn Marino static tree
array_to_pointer_conversion(location_t loc,tree exp)1768e4b17023SJohn Marino array_to_pointer_conversion (location_t loc, tree exp)
1769e4b17023SJohn Marino {
1770e4b17023SJohn Marino tree orig_exp = exp;
1771e4b17023SJohn Marino tree type = TREE_TYPE (exp);
1772e4b17023SJohn Marino tree adr;
1773e4b17023SJohn Marino tree restype = TREE_TYPE (type);
1774e4b17023SJohn Marino tree ptrtype;
1775e4b17023SJohn Marino
1776e4b17023SJohn Marino gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1777e4b17023SJohn Marino
1778e4b17023SJohn Marino STRIP_TYPE_NOPS (exp);
1779e4b17023SJohn Marino
1780e4b17023SJohn Marino if (TREE_NO_WARNING (orig_exp))
1781e4b17023SJohn Marino TREE_NO_WARNING (exp) = 1;
1782e4b17023SJohn Marino
1783e4b17023SJohn Marino ptrtype = build_pointer_type (restype);
1784e4b17023SJohn Marino
1785e4b17023SJohn Marino if (TREE_CODE (exp) == INDIRECT_REF)
1786e4b17023SJohn Marino return convert (ptrtype, TREE_OPERAND (exp, 0));
1787e4b17023SJohn Marino
1788e4b17023SJohn Marino /* In C++ array compound literals are temporary objects unless they are
1789e4b17023SJohn Marino const or appear in namespace scope, so they are destroyed too soon
1790e4b17023SJohn Marino to use them for much of anything (c++/53220). */
1791e4b17023SJohn Marino if (warn_cxx_compat && TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
1792e4b17023SJohn Marino {
1793e4b17023SJohn Marino tree decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1794e4b17023SJohn Marino if (!TREE_READONLY (decl) && !TREE_STATIC (decl))
1795e4b17023SJohn Marino warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
1796e4b17023SJohn Marino "converting an array compound literal to a pointer "
1797e4b17023SJohn Marino "is ill-formed in C++");
1798e4b17023SJohn Marino }
1799e4b17023SJohn Marino
1800e4b17023SJohn Marino adr = build_unary_op (loc, ADDR_EXPR, exp, 1);
1801e4b17023SJohn Marino return convert (ptrtype, adr);
1802e4b17023SJohn Marino }
1803e4b17023SJohn Marino
1804e4b17023SJohn Marino /* Convert the function expression EXP to a pointer. */
1805e4b17023SJohn Marino static tree
function_to_pointer_conversion(location_t loc,tree exp)1806e4b17023SJohn Marino function_to_pointer_conversion (location_t loc, tree exp)
1807e4b17023SJohn Marino {
1808e4b17023SJohn Marino tree orig_exp = exp;
1809e4b17023SJohn Marino
1810e4b17023SJohn Marino gcc_assert (TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE);
1811e4b17023SJohn Marino
1812e4b17023SJohn Marino STRIP_TYPE_NOPS (exp);
1813e4b17023SJohn Marino
1814e4b17023SJohn Marino if (TREE_NO_WARNING (orig_exp))
1815e4b17023SJohn Marino TREE_NO_WARNING (exp) = 1;
1816e4b17023SJohn Marino
1817e4b17023SJohn Marino return build_unary_op (loc, ADDR_EXPR, exp, 0);
1818e4b17023SJohn Marino }
1819e4b17023SJohn Marino
1820e4b17023SJohn Marino /* Mark EXP as read, not just set, for set but not used -Wunused
1821e4b17023SJohn Marino warning purposes. */
1822e4b17023SJohn Marino
1823e4b17023SJohn Marino void
mark_exp_read(tree exp)1824e4b17023SJohn Marino mark_exp_read (tree exp)
1825e4b17023SJohn Marino {
1826e4b17023SJohn Marino switch (TREE_CODE (exp))
1827e4b17023SJohn Marino {
1828e4b17023SJohn Marino case VAR_DECL:
1829e4b17023SJohn Marino case PARM_DECL:
1830e4b17023SJohn Marino DECL_READ_P (exp) = 1;
1831e4b17023SJohn Marino break;
1832e4b17023SJohn Marino case ARRAY_REF:
1833e4b17023SJohn Marino case COMPONENT_REF:
1834e4b17023SJohn Marino case MODIFY_EXPR:
1835e4b17023SJohn Marino case REALPART_EXPR:
1836e4b17023SJohn Marino case IMAGPART_EXPR:
1837e4b17023SJohn Marino CASE_CONVERT:
1838e4b17023SJohn Marino case ADDR_EXPR:
1839e4b17023SJohn Marino mark_exp_read (TREE_OPERAND (exp, 0));
1840e4b17023SJohn Marino break;
1841e4b17023SJohn Marino case COMPOUND_EXPR:
1842e4b17023SJohn Marino case C_MAYBE_CONST_EXPR:
1843e4b17023SJohn Marino mark_exp_read (TREE_OPERAND (exp, 1));
1844e4b17023SJohn Marino break;
1845e4b17023SJohn Marino default:
1846e4b17023SJohn Marino break;
1847e4b17023SJohn Marino }
1848e4b17023SJohn Marino }
1849e4b17023SJohn Marino
1850e4b17023SJohn Marino /* Perform the default conversion of arrays and functions to pointers.
1851e4b17023SJohn Marino Return the result of converting EXP. For any other expression, just
1852e4b17023SJohn Marino return EXP.
1853e4b17023SJohn Marino
1854e4b17023SJohn Marino LOC is the location of the expression. */
1855e4b17023SJohn Marino
1856e4b17023SJohn Marino struct c_expr
default_function_array_conversion(location_t loc,struct c_expr exp)1857e4b17023SJohn Marino default_function_array_conversion (location_t loc, struct c_expr exp)
1858e4b17023SJohn Marino {
1859e4b17023SJohn Marino tree orig_exp = exp.value;
1860e4b17023SJohn Marino tree type = TREE_TYPE (exp.value);
1861e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
1862e4b17023SJohn Marino
1863e4b17023SJohn Marino switch (code)
1864e4b17023SJohn Marino {
1865e4b17023SJohn Marino case ARRAY_TYPE:
1866e4b17023SJohn Marino {
1867e4b17023SJohn Marino bool not_lvalue = false;
1868e4b17023SJohn Marino bool lvalue_array_p;
1869e4b17023SJohn Marino
1870e4b17023SJohn Marino while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR
1871e4b17023SJohn Marino || CONVERT_EXPR_P (exp.value))
1872e4b17023SJohn Marino && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type)
1873e4b17023SJohn Marino {
1874e4b17023SJohn Marino if (TREE_CODE (exp.value) == NON_LVALUE_EXPR)
1875e4b17023SJohn Marino not_lvalue = true;
1876e4b17023SJohn Marino exp.value = TREE_OPERAND (exp.value, 0);
1877e4b17023SJohn Marino }
1878e4b17023SJohn Marino
1879e4b17023SJohn Marino if (TREE_NO_WARNING (orig_exp))
1880e4b17023SJohn Marino TREE_NO_WARNING (exp.value) = 1;
1881e4b17023SJohn Marino
1882e4b17023SJohn Marino lvalue_array_p = !not_lvalue && lvalue_p (exp.value);
1883e4b17023SJohn Marino if (!flag_isoc99 && !lvalue_array_p)
1884e4b17023SJohn Marino {
1885e4b17023SJohn Marino /* Before C99, non-lvalue arrays do not decay to pointers.
1886e4b17023SJohn Marino Normally, using such an array would be invalid; but it can
1887e4b17023SJohn Marino be used correctly inside sizeof or as a statement expression.
1888e4b17023SJohn Marino Thus, do not give an error here; an error will result later. */
1889e4b17023SJohn Marino return exp;
1890e4b17023SJohn Marino }
1891e4b17023SJohn Marino
1892e4b17023SJohn Marino exp.value = array_to_pointer_conversion (loc, exp.value);
1893e4b17023SJohn Marino }
1894e4b17023SJohn Marino break;
1895e4b17023SJohn Marino case FUNCTION_TYPE:
1896e4b17023SJohn Marino exp.value = function_to_pointer_conversion (loc, exp.value);
1897e4b17023SJohn Marino break;
1898e4b17023SJohn Marino default:
1899e4b17023SJohn Marino break;
1900e4b17023SJohn Marino }
1901e4b17023SJohn Marino
1902e4b17023SJohn Marino return exp;
1903e4b17023SJohn Marino }
1904e4b17023SJohn Marino
1905e4b17023SJohn Marino struct c_expr
default_function_array_read_conversion(location_t loc,struct c_expr exp)1906e4b17023SJohn Marino default_function_array_read_conversion (location_t loc, struct c_expr exp)
1907e4b17023SJohn Marino {
1908e4b17023SJohn Marino mark_exp_read (exp.value);
1909e4b17023SJohn Marino return default_function_array_conversion (loc, exp);
1910e4b17023SJohn Marino }
1911e4b17023SJohn Marino
1912e4b17023SJohn Marino /* EXP is an expression of integer type. Apply the integer promotions
1913e4b17023SJohn Marino to it and return the promoted value. */
1914e4b17023SJohn Marino
1915e4b17023SJohn Marino tree
perform_integral_promotions(tree exp)1916e4b17023SJohn Marino perform_integral_promotions (tree exp)
1917e4b17023SJohn Marino {
1918e4b17023SJohn Marino tree type = TREE_TYPE (exp);
1919e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
1920e4b17023SJohn Marino
1921e4b17023SJohn Marino gcc_assert (INTEGRAL_TYPE_P (type));
1922e4b17023SJohn Marino
1923e4b17023SJohn Marino /* Normally convert enums to int,
1924e4b17023SJohn Marino but convert wide enums to something wider. */
1925e4b17023SJohn Marino if (code == ENUMERAL_TYPE)
1926e4b17023SJohn Marino {
1927e4b17023SJohn Marino type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
1928e4b17023SJohn Marino TYPE_PRECISION (integer_type_node)),
1929e4b17023SJohn Marino ((TYPE_PRECISION (type)
1930e4b17023SJohn Marino >= TYPE_PRECISION (integer_type_node))
1931e4b17023SJohn Marino && TYPE_UNSIGNED (type)));
1932e4b17023SJohn Marino
1933e4b17023SJohn Marino return convert (type, exp);
1934e4b17023SJohn Marino }
1935e4b17023SJohn Marino
1936e4b17023SJohn Marino /* ??? This should no longer be needed now bit-fields have their
1937e4b17023SJohn Marino proper types. */
1938e4b17023SJohn Marino if (TREE_CODE (exp) == COMPONENT_REF
1939e4b17023SJohn Marino && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
1940e4b17023SJohn Marino /* If it's thinner than an int, promote it like a
1941e4b17023SJohn Marino c_promoting_integer_type_p, otherwise leave it alone. */
1942e4b17023SJohn Marino && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
1943e4b17023SJohn Marino TYPE_PRECISION (integer_type_node)))
1944e4b17023SJohn Marino return convert (integer_type_node, exp);
1945e4b17023SJohn Marino
1946e4b17023SJohn Marino if (c_promoting_integer_type_p (type))
1947e4b17023SJohn Marino {
1948e4b17023SJohn Marino /* Preserve unsignedness if not really getting any wider. */
1949e4b17023SJohn Marino if (TYPE_UNSIGNED (type)
1950e4b17023SJohn Marino && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
1951e4b17023SJohn Marino return convert (unsigned_type_node, exp);
1952e4b17023SJohn Marino
1953e4b17023SJohn Marino return convert (integer_type_node, exp);
1954e4b17023SJohn Marino }
1955e4b17023SJohn Marino
1956e4b17023SJohn Marino return exp;
1957e4b17023SJohn Marino }
1958e4b17023SJohn Marino
1959e4b17023SJohn Marino
1960e4b17023SJohn Marino /* Perform default promotions for C data used in expressions.
1961e4b17023SJohn Marino Enumeral types or short or char are converted to int.
1962e4b17023SJohn Marino In addition, manifest constants symbols are replaced by their values. */
1963e4b17023SJohn Marino
1964e4b17023SJohn Marino tree
default_conversion(tree exp)1965e4b17023SJohn Marino default_conversion (tree exp)
1966e4b17023SJohn Marino {
1967e4b17023SJohn Marino tree orig_exp;
1968e4b17023SJohn Marino tree type = TREE_TYPE (exp);
1969e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
1970e4b17023SJohn Marino tree promoted_type;
1971e4b17023SJohn Marino
1972e4b17023SJohn Marino mark_exp_read (exp);
1973e4b17023SJohn Marino
1974e4b17023SJohn Marino /* Functions and arrays have been converted during parsing. */
1975e4b17023SJohn Marino gcc_assert (code != FUNCTION_TYPE);
1976e4b17023SJohn Marino if (code == ARRAY_TYPE)
1977e4b17023SJohn Marino return exp;
1978e4b17023SJohn Marino
1979e4b17023SJohn Marino /* Constants can be used directly unless they're not loadable. */
1980e4b17023SJohn Marino if (TREE_CODE (exp) == CONST_DECL)
1981e4b17023SJohn Marino exp = DECL_INITIAL (exp);
1982e4b17023SJohn Marino
1983e4b17023SJohn Marino /* Strip no-op conversions. */
1984e4b17023SJohn Marino orig_exp = exp;
1985e4b17023SJohn Marino STRIP_TYPE_NOPS (exp);
1986e4b17023SJohn Marino
1987e4b17023SJohn Marino if (TREE_NO_WARNING (orig_exp))
1988e4b17023SJohn Marino TREE_NO_WARNING (exp) = 1;
1989e4b17023SJohn Marino
1990e4b17023SJohn Marino if (code == VOID_TYPE)
1991e4b17023SJohn Marino {
1992e4b17023SJohn Marino error ("void value not ignored as it ought to be");
1993e4b17023SJohn Marino return error_mark_node;
1994e4b17023SJohn Marino }
1995e4b17023SJohn Marino
1996e4b17023SJohn Marino exp = require_complete_type (exp);
1997e4b17023SJohn Marino if (exp == error_mark_node)
1998e4b17023SJohn Marino return error_mark_node;
1999e4b17023SJohn Marino
2000e4b17023SJohn Marino promoted_type = targetm.promoted_type (type);
2001e4b17023SJohn Marino if (promoted_type)
2002e4b17023SJohn Marino return convert (promoted_type, exp);
2003e4b17023SJohn Marino
2004e4b17023SJohn Marino if (INTEGRAL_TYPE_P (type))
2005e4b17023SJohn Marino return perform_integral_promotions (exp);
2006e4b17023SJohn Marino
2007e4b17023SJohn Marino return exp;
2008e4b17023SJohn Marino }
2009e4b17023SJohn Marino
2010e4b17023SJohn Marino /* Look up COMPONENT in a structure or union TYPE.
2011e4b17023SJohn Marino
2012e4b17023SJohn Marino If the component name is not found, returns NULL_TREE. Otherwise,
2013e4b17023SJohn Marino the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL
2014e4b17023SJohn Marino stepping down the chain to the component, which is in the last
2015e4b17023SJohn Marino TREE_VALUE of the list. Normally the list is of length one, but if
2016e4b17023SJohn Marino the component is embedded within (nested) anonymous structures or
2017e4b17023SJohn Marino unions, the list steps down the chain to the component. */
2018e4b17023SJohn Marino
2019e4b17023SJohn Marino static tree
lookup_field(tree type,tree component)2020e4b17023SJohn Marino lookup_field (tree type, tree component)
2021e4b17023SJohn Marino {
2022e4b17023SJohn Marino tree field;
2023e4b17023SJohn Marino
2024e4b17023SJohn Marino /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
2025e4b17023SJohn Marino to the field elements. Use a binary search on this array to quickly
2026e4b17023SJohn Marino find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC
2027e4b17023SJohn Marino will always be set for structures which have many elements. */
2028e4b17023SJohn Marino
2029e4b17023SJohn Marino if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s)
2030e4b17023SJohn Marino {
2031e4b17023SJohn Marino int bot, top, half;
2032e4b17023SJohn Marino tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0];
2033e4b17023SJohn Marino
2034e4b17023SJohn Marino field = TYPE_FIELDS (type);
2035e4b17023SJohn Marino bot = 0;
2036e4b17023SJohn Marino top = TYPE_LANG_SPECIFIC (type)->s->len;
2037e4b17023SJohn Marino while (top - bot > 1)
2038e4b17023SJohn Marino {
2039e4b17023SJohn Marino half = (top - bot + 1) >> 1;
2040e4b17023SJohn Marino field = field_array[bot+half];
2041e4b17023SJohn Marino
2042e4b17023SJohn Marino if (DECL_NAME (field) == NULL_TREE)
2043e4b17023SJohn Marino {
2044e4b17023SJohn Marino /* Step through all anon unions in linear fashion. */
2045e4b17023SJohn Marino while (DECL_NAME (field_array[bot]) == NULL_TREE)
2046e4b17023SJohn Marino {
2047e4b17023SJohn Marino field = field_array[bot++];
2048e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
2049e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
2050e4b17023SJohn Marino {
2051e4b17023SJohn Marino tree anon = lookup_field (TREE_TYPE (field), component);
2052e4b17023SJohn Marino
2053e4b17023SJohn Marino if (anon)
2054e4b17023SJohn Marino return tree_cons (NULL_TREE, field, anon);
2055e4b17023SJohn Marino
2056e4b17023SJohn Marino /* The Plan 9 compiler permits referring
2057e4b17023SJohn Marino directly to an anonymous struct/union field
2058e4b17023SJohn Marino using a typedef name. */
2059e4b17023SJohn Marino if (flag_plan9_extensions
2060e4b17023SJohn Marino && TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
2061e4b17023SJohn Marino && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
2062e4b17023SJohn Marino == TYPE_DECL)
2063e4b17023SJohn Marino && (DECL_NAME (TYPE_NAME (TREE_TYPE (field)))
2064e4b17023SJohn Marino == component))
2065e4b17023SJohn Marino break;
2066e4b17023SJohn Marino }
2067e4b17023SJohn Marino }
2068e4b17023SJohn Marino
2069e4b17023SJohn Marino /* Entire record is only anon unions. */
2070e4b17023SJohn Marino if (bot > top)
2071e4b17023SJohn Marino return NULL_TREE;
2072e4b17023SJohn Marino
2073e4b17023SJohn Marino /* Restart the binary search, with new lower bound. */
2074e4b17023SJohn Marino continue;
2075e4b17023SJohn Marino }
2076e4b17023SJohn Marino
2077e4b17023SJohn Marino if (DECL_NAME (field) == component)
2078e4b17023SJohn Marino break;
2079e4b17023SJohn Marino if (DECL_NAME (field) < component)
2080e4b17023SJohn Marino bot += half;
2081e4b17023SJohn Marino else
2082e4b17023SJohn Marino top = bot + half;
2083e4b17023SJohn Marino }
2084e4b17023SJohn Marino
2085e4b17023SJohn Marino if (DECL_NAME (field_array[bot]) == component)
2086e4b17023SJohn Marino field = field_array[bot];
2087e4b17023SJohn Marino else if (DECL_NAME (field) != component)
2088e4b17023SJohn Marino return NULL_TREE;
2089e4b17023SJohn Marino }
2090e4b17023SJohn Marino else
2091e4b17023SJohn Marino {
2092e4b17023SJohn Marino for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2093e4b17023SJohn Marino {
2094e4b17023SJohn Marino if (DECL_NAME (field) == NULL_TREE
2095e4b17023SJohn Marino && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
2096e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
2097e4b17023SJohn Marino {
2098e4b17023SJohn Marino tree anon = lookup_field (TREE_TYPE (field), component);
2099e4b17023SJohn Marino
2100e4b17023SJohn Marino if (anon)
2101e4b17023SJohn Marino return tree_cons (NULL_TREE, field, anon);
2102e4b17023SJohn Marino
2103e4b17023SJohn Marino /* The Plan 9 compiler permits referring directly to an
2104e4b17023SJohn Marino anonymous struct/union field using a typedef
2105e4b17023SJohn Marino name. */
2106e4b17023SJohn Marino if (flag_plan9_extensions
2107e4b17023SJohn Marino && TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
2108e4b17023SJohn Marino && TREE_CODE (TYPE_NAME (TREE_TYPE (field))) == TYPE_DECL
2109e4b17023SJohn Marino && (DECL_NAME (TYPE_NAME (TREE_TYPE (field)))
2110e4b17023SJohn Marino == component))
2111e4b17023SJohn Marino break;
2112e4b17023SJohn Marino }
2113e4b17023SJohn Marino
2114e4b17023SJohn Marino if (DECL_NAME (field) == component)
2115e4b17023SJohn Marino break;
2116e4b17023SJohn Marino }
2117e4b17023SJohn Marino
2118e4b17023SJohn Marino if (field == NULL_TREE)
2119e4b17023SJohn Marino return NULL_TREE;
2120e4b17023SJohn Marino }
2121e4b17023SJohn Marino
2122e4b17023SJohn Marino return tree_cons (NULL_TREE, field, NULL_TREE);
2123e4b17023SJohn Marino }
2124e4b17023SJohn Marino
2125e4b17023SJohn Marino /* Make an expression to refer to the COMPONENT field of structure or
2126e4b17023SJohn Marino union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the
2127e4b17023SJohn Marino location of the COMPONENT_REF. */
2128e4b17023SJohn Marino
2129e4b17023SJohn Marino tree
build_component_ref(location_t loc,tree datum,tree component)2130e4b17023SJohn Marino build_component_ref (location_t loc, tree datum, tree component)
2131e4b17023SJohn Marino {
2132e4b17023SJohn Marino tree type = TREE_TYPE (datum);
2133e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
2134e4b17023SJohn Marino tree field = NULL;
2135e4b17023SJohn Marino tree ref;
2136e4b17023SJohn Marino bool datum_lvalue = lvalue_p (datum);
2137e4b17023SJohn Marino
2138e4b17023SJohn Marino if (!objc_is_public (datum, component))
2139e4b17023SJohn Marino return error_mark_node;
2140e4b17023SJohn Marino
2141e4b17023SJohn Marino /* Detect Objective-C property syntax object.property. */
2142e4b17023SJohn Marino if (c_dialect_objc ()
2143e4b17023SJohn Marino && (ref = objc_maybe_build_component_ref (datum, component)))
2144e4b17023SJohn Marino return ref;
2145e4b17023SJohn Marino
2146e4b17023SJohn Marino /* See if there is a field or component with name COMPONENT. */
2147e4b17023SJohn Marino
2148e4b17023SJohn Marino if (code == RECORD_TYPE || code == UNION_TYPE)
2149e4b17023SJohn Marino {
2150e4b17023SJohn Marino if (!COMPLETE_TYPE_P (type))
2151e4b17023SJohn Marino {
2152e4b17023SJohn Marino c_incomplete_type_error (NULL_TREE, type);
2153e4b17023SJohn Marino return error_mark_node;
2154e4b17023SJohn Marino }
2155e4b17023SJohn Marino
2156e4b17023SJohn Marino field = lookup_field (type, component);
2157e4b17023SJohn Marino
2158e4b17023SJohn Marino if (!field)
2159e4b17023SJohn Marino {
2160e4b17023SJohn Marino error_at (loc, "%qT has no member named %qE", type, component);
2161e4b17023SJohn Marino return error_mark_node;
2162e4b17023SJohn Marino }
2163e4b17023SJohn Marino
2164e4b17023SJohn Marino /* Chain the COMPONENT_REFs if necessary down to the FIELD.
2165e4b17023SJohn Marino This might be better solved in future the way the C++ front
2166e4b17023SJohn Marino end does it - by giving the anonymous entities each a
2167e4b17023SJohn Marino separate name and type, and then have build_component_ref
2168e4b17023SJohn Marino recursively call itself. We can't do that here. */
2169e4b17023SJohn Marino do
2170e4b17023SJohn Marino {
2171e4b17023SJohn Marino tree subdatum = TREE_VALUE (field);
2172e4b17023SJohn Marino int quals;
2173e4b17023SJohn Marino tree subtype;
2174e4b17023SJohn Marino bool use_datum_quals;
2175e4b17023SJohn Marino
2176e4b17023SJohn Marino if (TREE_TYPE (subdatum) == error_mark_node)
2177e4b17023SJohn Marino return error_mark_node;
2178e4b17023SJohn Marino
2179e4b17023SJohn Marino /* If this is an rvalue, it does not have qualifiers in C
2180e4b17023SJohn Marino standard terms and we must avoid propagating such
2181e4b17023SJohn Marino qualifiers down to a non-lvalue array that is then
2182e4b17023SJohn Marino converted to a pointer. */
2183e4b17023SJohn Marino use_datum_quals = (datum_lvalue
2184e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (subdatum)) != ARRAY_TYPE);
2185e4b17023SJohn Marino
2186e4b17023SJohn Marino quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum)));
2187e4b17023SJohn Marino if (use_datum_quals)
2188e4b17023SJohn Marino quals |= TYPE_QUALS (TREE_TYPE (datum));
2189e4b17023SJohn Marino subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals);
2190e4b17023SJohn Marino
2191e4b17023SJohn Marino ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
2192e4b17023SJohn Marino NULL_TREE);
2193e4b17023SJohn Marino SET_EXPR_LOCATION (ref, loc);
2194e4b17023SJohn Marino if (TREE_READONLY (subdatum)
2195e4b17023SJohn Marino || (use_datum_quals && TREE_READONLY (datum)))
2196e4b17023SJohn Marino TREE_READONLY (ref) = 1;
2197e4b17023SJohn Marino if (TREE_THIS_VOLATILE (subdatum)
2198e4b17023SJohn Marino || (use_datum_quals && TREE_THIS_VOLATILE (datum)))
2199e4b17023SJohn Marino TREE_THIS_VOLATILE (ref) = 1;
2200e4b17023SJohn Marino
2201e4b17023SJohn Marino if (TREE_DEPRECATED (subdatum))
2202e4b17023SJohn Marino warn_deprecated_use (subdatum, NULL_TREE);
2203e4b17023SJohn Marino
2204e4b17023SJohn Marino datum = ref;
2205e4b17023SJohn Marino
2206e4b17023SJohn Marino field = TREE_CHAIN (field);
2207e4b17023SJohn Marino }
2208e4b17023SJohn Marino while (field);
2209e4b17023SJohn Marino
2210e4b17023SJohn Marino return ref;
2211e4b17023SJohn Marino }
2212e4b17023SJohn Marino else if (code != ERROR_MARK)
2213e4b17023SJohn Marino error_at (loc,
2214e4b17023SJohn Marino "request for member %qE in something not a structure or union",
2215e4b17023SJohn Marino component);
2216e4b17023SJohn Marino
2217e4b17023SJohn Marino return error_mark_node;
2218e4b17023SJohn Marino }
2219e4b17023SJohn Marino
2220e4b17023SJohn Marino /* Given an expression PTR for a pointer, return an expression
2221e4b17023SJohn Marino for the value pointed to.
2222e4b17023SJohn Marino ERRORSTRING is the name of the operator to appear in error messages.
2223e4b17023SJohn Marino
2224e4b17023SJohn Marino LOC is the location to use for the generated tree. */
2225e4b17023SJohn Marino
2226e4b17023SJohn Marino tree
build_indirect_ref(location_t loc,tree ptr,ref_operator errstring)2227e4b17023SJohn Marino build_indirect_ref (location_t loc, tree ptr, ref_operator errstring)
2228e4b17023SJohn Marino {
2229e4b17023SJohn Marino tree pointer = default_conversion (ptr);
2230e4b17023SJohn Marino tree type = TREE_TYPE (pointer);
2231e4b17023SJohn Marino tree ref;
2232e4b17023SJohn Marino
2233e4b17023SJohn Marino if (TREE_CODE (type) == POINTER_TYPE)
2234e4b17023SJohn Marino {
2235e4b17023SJohn Marino if (CONVERT_EXPR_P (pointer)
2236e4b17023SJohn Marino || TREE_CODE (pointer) == VIEW_CONVERT_EXPR)
2237e4b17023SJohn Marino {
2238e4b17023SJohn Marino /* If a warning is issued, mark it to avoid duplicates from
2239e4b17023SJohn Marino the backend. This only needs to be done at
2240e4b17023SJohn Marino warn_strict_aliasing > 2. */
2241e4b17023SJohn Marino if (warn_strict_aliasing > 2)
2242e4b17023SJohn Marino if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)),
2243e4b17023SJohn Marino type, TREE_OPERAND (pointer, 0)))
2244e4b17023SJohn Marino TREE_NO_WARNING (pointer) = 1;
2245e4b17023SJohn Marino }
2246e4b17023SJohn Marino
2247e4b17023SJohn Marino if (TREE_CODE (pointer) == ADDR_EXPR
2248e4b17023SJohn Marino && (TREE_TYPE (TREE_OPERAND (pointer, 0))
2249e4b17023SJohn Marino == TREE_TYPE (type)))
2250e4b17023SJohn Marino {
2251e4b17023SJohn Marino ref = TREE_OPERAND (pointer, 0);
2252e4b17023SJohn Marino protected_set_expr_location (ref, loc);
2253e4b17023SJohn Marino return ref;
2254e4b17023SJohn Marino }
2255e4b17023SJohn Marino else
2256e4b17023SJohn Marino {
2257e4b17023SJohn Marino tree t = TREE_TYPE (type);
2258e4b17023SJohn Marino
2259e4b17023SJohn Marino ref = build1 (INDIRECT_REF, t, pointer);
2260e4b17023SJohn Marino
2261e4b17023SJohn Marino if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
2262e4b17023SJohn Marino {
2263e4b17023SJohn Marino error_at (loc, "dereferencing pointer to incomplete type");
2264e4b17023SJohn Marino return error_mark_node;
2265e4b17023SJohn Marino }
2266e4b17023SJohn Marino if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0)
2267e4b17023SJohn Marino warning_at (loc, 0, "dereferencing %<void *%> pointer");
2268e4b17023SJohn Marino
2269e4b17023SJohn Marino /* We *must* set TREE_READONLY when dereferencing a pointer to const,
2270e4b17023SJohn Marino so that we get the proper error message if the result is used
2271e4b17023SJohn Marino to assign to. Also, &* is supposed to be a no-op.
2272e4b17023SJohn Marino And ANSI C seems to specify that the type of the result
2273e4b17023SJohn Marino should be the const type. */
2274e4b17023SJohn Marino /* A de-reference of a pointer to const is not a const. It is valid
2275e4b17023SJohn Marino to change it via some other pointer. */
2276e4b17023SJohn Marino TREE_READONLY (ref) = TYPE_READONLY (t);
2277e4b17023SJohn Marino TREE_SIDE_EFFECTS (ref)
2278e4b17023SJohn Marino = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
2279e4b17023SJohn Marino TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
2280e4b17023SJohn Marino protected_set_expr_location (ref, loc);
2281e4b17023SJohn Marino return ref;
2282e4b17023SJohn Marino }
2283e4b17023SJohn Marino }
2284e4b17023SJohn Marino else if (TREE_CODE (pointer) != ERROR_MARK)
2285e4b17023SJohn Marino invalid_indirection_error (loc, type, errstring);
2286e4b17023SJohn Marino
2287e4b17023SJohn Marino return error_mark_node;
2288e4b17023SJohn Marino }
2289e4b17023SJohn Marino
2290e4b17023SJohn Marino /* This handles expressions of the form "a[i]", which denotes
2291e4b17023SJohn Marino an array reference.
2292e4b17023SJohn Marino
2293e4b17023SJohn Marino This is logically equivalent in C to *(a+i), but we may do it differently.
2294e4b17023SJohn Marino If A is a variable or a member, we generate a primitive ARRAY_REF.
2295e4b17023SJohn Marino This avoids forcing the array out of registers, and can work on
2296e4b17023SJohn Marino arrays that are not lvalues (for example, members of structures returned
2297e4b17023SJohn Marino by functions).
2298e4b17023SJohn Marino
2299e4b17023SJohn Marino For vector types, allow vector[i] but not i[vector], and create
2300e4b17023SJohn Marino *(((type*)&vectortype) + i) for the expression.
2301e4b17023SJohn Marino
2302e4b17023SJohn Marino LOC is the location to use for the returned expression. */
2303e4b17023SJohn Marino
2304e4b17023SJohn Marino tree
build_array_ref(location_t loc,tree array,tree index)2305e4b17023SJohn Marino build_array_ref (location_t loc, tree array, tree index)
2306e4b17023SJohn Marino {
2307e4b17023SJohn Marino tree ret;
2308e4b17023SJohn Marino bool swapped = false;
2309e4b17023SJohn Marino if (TREE_TYPE (array) == error_mark_node
2310e4b17023SJohn Marino || TREE_TYPE (index) == error_mark_node)
2311e4b17023SJohn Marino return error_mark_node;
2312e4b17023SJohn Marino
2313e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
2314e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
2315e4b17023SJohn Marino /* Allow vector[index] but not index[vector]. */
2316e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (array)) != VECTOR_TYPE)
2317e4b17023SJohn Marino {
2318e4b17023SJohn Marino tree temp;
2319e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
2320e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
2321e4b17023SJohn Marino {
2322e4b17023SJohn Marino error_at (loc,
2323e4b17023SJohn Marino "subscripted value is neither array nor pointer nor vector");
2324e4b17023SJohn Marino
2325e4b17023SJohn Marino return error_mark_node;
2326e4b17023SJohn Marino }
2327e4b17023SJohn Marino temp = array;
2328e4b17023SJohn Marino array = index;
2329e4b17023SJohn Marino index = temp;
2330e4b17023SJohn Marino swapped = true;
2331e4b17023SJohn Marino }
2332e4b17023SJohn Marino
2333e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
2334e4b17023SJohn Marino {
2335e4b17023SJohn Marino error_at (loc, "array subscript is not an integer");
2336e4b17023SJohn Marino return error_mark_node;
2337e4b17023SJohn Marino }
2338e4b17023SJohn Marino
2339e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE)
2340e4b17023SJohn Marino {
2341e4b17023SJohn Marino error_at (loc, "subscripted value is pointer to function");
2342e4b17023SJohn Marino return error_mark_node;
2343e4b17023SJohn Marino }
2344e4b17023SJohn Marino
2345e4b17023SJohn Marino /* ??? Existing practice has been to warn only when the char
2346e4b17023SJohn Marino index is syntactically the index, not for char[array]. */
2347e4b17023SJohn Marino if (!swapped)
2348e4b17023SJohn Marino warn_array_subscript_with_type_char (index);
2349e4b17023SJohn Marino
2350e4b17023SJohn Marino /* Apply default promotions *after* noticing character types. */
2351e4b17023SJohn Marino index = default_conversion (index);
2352e4b17023SJohn Marino
2353e4b17023SJohn Marino gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
2354e4b17023SJohn Marino
2355e4b17023SJohn Marino /* For vector[index], convert the vector to a
2356e4b17023SJohn Marino pointer of the underlying type. */
2357e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
2358e4b17023SJohn Marino {
2359e4b17023SJohn Marino tree type = TREE_TYPE (array);
2360e4b17023SJohn Marino tree type1;
2361e4b17023SJohn Marino
2362e4b17023SJohn Marino if (TREE_CODE (index) == INTEGER_CST)
2363e4b17023SJohn Marino if (!host_integerp (index, 1)
2364e4b17023SJohn Marino || ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1)
2365e4b17023SJohn Marino >= TYPE_VECTOR_SUBPARTS (TREE_TYPE (array))))
2366e4b17023SJohn Marino warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
2367e4b17023SJohn Marino
2368e4b17023SJohn Marino c_common_mark_addressable_vec (array);
2369e4b17023SJohn Marino type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
2370e4b17023SJohn Marino type = build_pointer_type (type);
2371e4b17023SJohn Marino type1 = build_pointer_type (TREE_TYPE (array));
2372e4b17023SJohn Marino array = build1 (ADDR_EXPR, type1, array);
2373e4b17023SJohn Marino array = convert (type, array);
2374e4b17023SJohn Marino }
2375e4b17023SJohn Marino
2376e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
2377e4b17023SJohn Marino {
2378e4b17023SJohn Marino tree rval, type;
2379e4b17023SJohn Marino
2380e4b17023SJohn Marino /* An array that is indexed by a non-constant
2381e4b17023SJohn Marino cannot be stored in a register; we must be able to do
2382e4b17023SJohn Marino address arithmetic on its address.
2383e4b17023SJohn Marino Likewise an array of elements of variable size. */
2384e4b17023SJohn Marino if (TREE_CODE (index) != INTEGER_CST
2385e4b17023SJohn Marino || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
2386e4b17023SJohn Marino && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
2387e4b17023SJohn Marino {
2388e4b17023SJohn Marino if (!c_mark_addressable (array))
2389e4b17023SJohn Marino return error_mark_node;
2390e4b17023SJohn Marino }
2391e4b17023SJohn Marino /* An array that is indexed by a constant value which is not within
2392e4b17023SJohn Marino the array bounds cannot be stored in a register either; because we
2393e4b17023SJohn Marino would get a crash in store_bit_field/extract_bit_field when trying
2394e4b17023SJohn Marino to access a non-existent part of the register. */
2395e4b17023SJohn Marino if (TREE_CODE (index) == INTEGER_CST
2396e4b17023SJohn Marino && TYPE_DOMAIN (TREE_TYPE (array))
2397e4b17023SJohn Marino && !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array))))
2398e4b17023SJohn Marino {
2399e4b17023SJohn Marino if (!c_mark_addressable (array))
2400e4b17023SJohn Marino return error_mark_node;
2401e4b17023SJohn Marino }
2402e4b17023SJohn Marino
2403e4b17023SJohn Marino if (pedantic)
2404e4b17023SJohn Marino {
2405e4b17023SJohn Marino tree foo = array;
2406e4b17023SJohn Marino while (TREE_CODE (foo) == COMPONENT_REF)
2407e4b17023SJohn Marino foo = TREE_OPERAND (foo, 0);
2408e4b17023SJohn Marino if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
2409e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
2410e4b17023SJohn Marino "ISO C forbids subscripting %<register%> array");
2411e4b17023SJohn Marino else if (!flag_isoc99 && !lvalue_p (foo))
2412e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
2413e4b17023SJohn Marino "ISO C90 forbids subscripting non-lvalue array");
2414e4b17023SJohn Marino }
2415e4b17023SJohn Marino
2416e4b17023SJohn Marino type = TREE_TYPE (TREE_TYPE (array));
2417e4b17023SJohn Marino rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
2418e4b17023SJohn Marino /* Array ref is const/volatile if the array elements are
2419e4b17023SJohn Marino or if the array is. */
2420e4b17023SJohn Marino TREE_READONLY (rval)
2421e4b17023SJohn Marino |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
2422e4b17023SJohn Marino | TREE_READONLY (array));
2423e4b17023SJohn Marino TREE_SIDE_EFFECTS (rval)
2424e4b17023SJohn Marino |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
2425e4b17023SJohn Marino | TREE_SIDE_EFFECTS (array));
2426e4b17023SJohn Marino TREE_THIS_VOLATILE (rval)
2427e4b17023SJohn Marino |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
2428e4b17023SJohn Marino /* This was added by rms on 16 Nov 91.
2429e4b17023SJohn Marino It fixes vol struct foo *a; a->elts[1]
2430e4b17023SJohn Marino in an inline function.
2431e4b17023SJohn Marino Hope it doesn't break something else. */
2432e4b17023SJohn Marino | TREE_THIS_VOLATILE (array));
2433e4b17023SJohn Marino ret = require_complete_type (rval);
2434e4b17023SJohn Marino protected_set_expr_location (ret, loc);
2435e4b17023SJohn Marino return ret;
2436e4b17023SJohn Marino }
2437e4b17023SJohn Marino else
2438e4b17023SJohn Marino {
2439e4b17023SJohn Marino tree ar = default_conversion (array);
2440e4b17023SJohn Marino
2441e4b17023SJohn Marino if (ar == error_mark_node)
2442e4b17023SJohn Marino return ar;
2443e4b17023SJohn Marino
2444e4b17023SJohn Marino gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
2445e4b17023SJohn Marino gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
2446e4b17023SJohn Marino
2447e4b17023SJohn Marino return build_indirect_ref
2448e4b17023SJohn Marino (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0),
2449e4b17023SJohn Marino RO_ARRAY_INDEXING);
2450e4b17023SJohn Marino }
2451e4b17023SJohn Marino }
2452e4b17023SJohn Marino
2453e4b17023SJohn Marino /* Build an external reference to identifier ID. FUN indicates
2454e4b17023SJohn Marino whether this will be used for a function call. LOC is the source
2455e4b17023SJohn Marino location of the identifier. This sets *TYPE to the type of the
2456e4b17023SJohn Marino identifier, which is not the same as the type of the returned value
2457e4b17023SJohn Marino for CONST_DECLs defined as enum constants. If the type of the
2458e4b17023SJohn Marino identifier is not available, *TYPE is set to NULL. */
2459e4b17023SJohn Marino tree
build_external_ref(location_t loc,tree id,int fun,tree * type)2460e4b17023SJohn Marino build_external_ref (location_t loc, tree id, int fun, tree *type)
2461e4b17023SJohn Marino {
2462e4b17023SJohn Marino tree ref;
2463e4b17023SJohn Marino tree decl = lookup_name (id);
2464e4b17023SJohn Marino
2465e4b17023SJohn Marino /* In Objective-C, an instance variable (ivar) may be preferred to
2466e4b17023SJohn Marino whatever lookup_name() found. */
2467e4b17023SJohn Marino decl = objc_lookup_ivar (decl, id);
2468e4b17023SJohn Marino
2469e4b17023SJohn Marino *type = NULL;
2470e4b17023SJohn Marino if (decl && decl != error_mark_node)
2471e4b17023SJohn Marino {
2472e4b17023SJohn Marino ref = decl;
2473e4b17023SJohn Marino *type = TREE_TYPE (ref);
2474e4b17023SJohn Marino }
2475e4b17023SJohn Marino else if (fun)
2476e4b17023SJohn Marino /* Implicit function declaration. */
2477e4b17023SJohn Marino ref = implicitly_declare (loc, id);
2478e4b17023SJohn Marino else if (decl == error_mark_node)
2479e4b17023SJohn Marino /* Don't complain about something that's already been
2480e4b17023SJohn Marino complained about. */
2481e4b17023SJohn Marino return error_mark_node;
2482e4b17023SJohn Marino else
2483e4b17023SJohn Marino {
2484e4b17023SJohn Marino undeclared_variable (loc, id);
2485e4b17023SJohn Marino return error_mark_node;
2486e4b17023SJohn Marino }
2487e4b17023SJohn Marino
2488e4b17023SJohn Marino if (TREE_TYPE (ref) == error_mark_node)
2489e4b17023SJohn Marino return error_mark_node;
2490e4b17023SJohn Marino
2491e4b17023SJohn Marino if (TREE_DEPRECATED (ref))
2492e4b17023SJohn Marino warn_deprecated_use (ref, NULL_TREE);
2493e4b17023SJohn Marino
2494e4b17023SJohn Marino /* Recursive call does not count as usage. */
2495e4b17023SJohn Marino if (ref != current_function_decl)
2496e4b17023SJohn Marino {
2497e4b17023SJohn Marino TREE_USED (ref) = 1;
2498e4b17023SJohn Marino }
2499e4b17023SJohn Marino
2500e4b17023SJohn Marino if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof)
2501e4b17023SJohn Marino {
2502e4b17023SJohn Marino if (!in_sizeof && !in_typeof)
2503e4b17023SJohn Marino C_DECL_USED (ref) = 1;
2504e4b17023SJohn Marino else if (DECL_INITIAL (ref) == 0
2505e4b17023SJohn Marino && DECL_EXTERNAL (ref)
2506e4b17023SJohn Marino && !TREE_PUBLIC (ref))
2507e4b17023SJohn Marino record_maybe_used_decl (ref);
2508e4b17023SJohn Marino }
2509e4b17023SJohn Marino
2510e4b17023SJohn Marino if (TREE_CODE (ref) == CONST_DECL)
2511e4b17023SJohn Marino {
2512e4b17023SJohn Marino used_types_insert (TREE_TYPE (ref));
2513e4b17023SJohn Marino
2514e4b17023SJohn Marino if (warn_cxx_compat
2515e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (ref)) == ENUMERAL_TYPE
2516e4b17023SJohn Marino && C_TYPE_DEFINED_IN_STRUCT (TREE_TYPE (ref)))
2517e4b17023SJohn Marino {
2518e4b17023SJohn Marino warning_at (loc, OPT_Wc___compat,
2519e4b17023SJohn Marino ("enum constant defined in struct or union "
2520e4b17023SJohn Marino "is not visible in C++"));
2521e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (ref), "enum constant defined here");
2522e4b17023SJohn Marino }
2523e4b17023SJohn Marino
2524e4b17023SJohn Marino ref = DECL_INITIAL (ref);
2525e4b17023SJohn Marino TREE_CONSTANT (ref) = 1;
2526e4b17023SJohn Marino }
2527e4b17023SJohn Marino else if (current_function_decl != 0
2528e4b17023SJohn Marino && !DECL_FILE_SCOPE_P (current_function_decl)
2529e4b17023SJohn Marino && (TREE_CODE (ref) == VAR_DECL
2530e4b17023SJohn Marino || TREE_CODE (ref) == PARM_DECL
2531e4b17023SJohn Marino || TREE_CODE (ref) == FUNCTION_DECL))
2532e4b17023SJohn Marino {
2533e4b17023SJohn Marino tree context = decl_function_context (ref);
2534e4b17023SJohn Marino
2535e4b17023SJohn Marino if (context != 0 && context != current_function_decl)
2536e4b17023SJohn Marino DECL_NONLOCAL (ref) = 1;
2537e4b17023SJohn Marino }
2538e4b17023SJohn Marino /* C99 6.7.4p3: An inline definition of a function with external
2539e4b17023SJohn Marino linkage ... shall not contain a reference to an identifier with
2540e4b17023SJohn Marino internal linkage. */
2541e4b17023SJohn Marino else if (current_function_decl != 0
2542e4b17023SJohn Marino && DECL_DECLARED_INLINE_P (current_function_decl)
2543e4b17023SJohn Marino && DECL_EXTERNAL (current_function_decl)
2544e4b17023SJohn Marino && VAR_OR_FUNCTION_DECL_P (ref)
2545e4b17023SJohn Marino && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
2546e4b17023SJohn Marino && ! TREE_PUBLIC (ref)
2547e4b17023SJohn Marino && DECL_CONTEXT (ref) != current_function_decl)
2548e4b17023SJohn Marino record_inline_static (loc, current_function_decl, ref,
2549e4b17023SJohn Marino csi_internal);
2550e4b17023SJohn Marino
2551e4b17023SJohn Marino return ref;
2552e4b17023SJohn Marino }
2553e4b17023SJohn Marino
2554e4b17023SJohn Marino /* Record details of decls possibly used inside sizeof or typeof. */
2555e4b17023SJohn Marino struct maybe_used_decl
2556e4b17023SJohn Marino {
2557e4b17023SJohn Marino /* The decl. */
2558e4b17023SJohn Marino tree decl;
2559e4b17023SJohn Marino /* The level seen at (in_sizeof + in_typeof). */
2560e4b17023SJohn Marino int level;
2561e4b17023SJohn Marino /* The next one at this level or above, or NULL. */
2562e4b17023SJohn Marino struct maybe_used_decl *next;
2563e4b17023SJohn Marino };
2564e4b17023SJohn Marino
2565e4b17023SJohn Marino static struct maybe_used_decl *maybe_used_decls;
2566e4b17023SJohn Marino
2567e4b17023SJohn Marino /* Record that DECL, an undefined static function reference seen
2568e4b17023SJohn Marino inside sizeof or typeof, might be used if the operand of sizeof is
2569e4b17023SJohn Marino a VLA type or the operand of typeof is a variably modified
2570e4b17023SJohn Marino type. */
2571e4b17023SJohn Marino
2572e4b17023SJohn Marino static void
record_maybe_used_decl(tree decl)2573e4b17023SJohn Marino record_maybe_used_decl (tree decl)
2574e4b17023SJohn Marino {
2575e4b17023SJohn Marino struct maybe_used_decl *t = XOBNEW (&parser_obstack, struct maybe_used_decl);
2576e4b17023SJohn Marino t->decl = decl;
2577e4b17023SJohn Marino t->level = in_sizeof + in_typeof;
2578e4b17023SJohn Marino t->next = maybe_used_decls;
2579e4b17023SJohn Marino maybe_used_decls = t;
2580e4b17023SJohn Marino }
2581e4b17023SJohn Marino
2582e4b17023SJohn Marino /* Pop the stack of decls possibly used inside sizeof or typeof. If
2583e4b17023SJohn Marino USED is false, just discard them. If it is true, mark them used
2584e4b17023SJohn Marino (if no longer inside sizeof or typeof) or move them to the next
2585e4b17023SJohn Marino level up (if still inside sizeof or typeof). */
2586e4b17023SJohn Marino
2587e4b17023SJohn Marino void
pop_maybe_used(bool used)2588e4b17023SJohn Marino pop_maybe_used (bool used)
2589e4b17023SJohn Marino {
2590e4b17023SJohn Marino struct maybe_used_decl *p = maybe_used_decls;
2591e4b17023SJohn Marino int cur_level = in_sizeof + in_typeof;
2592e4b17023SJohn Marino while (p && p->level > cur_level)
2593e4b17023SJohn Marino {
2594e4b17023SJohn Marino if (used)
2595e4b17023SJohn Marino {
2596e4b17023SJohn Marino if (cur_level == 0)
2597e4b17023SJohn Marino C_DECL_USED (p->decl) = 1;
2598e4b17023SJohn Marino else
2599e4b17023SJohn Marino p->level = cur_level;
2600e4b17023SJohn Marino }
2601e4b17023SJohn Marino p = p->next;
2602e4b17023SJohn Marino }
2603e4b17023SJohn Marino if (!used || cur_level == 0)
2604e4b17023SJohn Marino maybe_used_decls = p;
2605e4b17023SJohn Marino }
2606e4b17023SJohn Marino
2607e4b17023SJohn Marino /* Return the result of sizeof applied to EXPR. */
2608e4b17023SJohn Marino
2609e4b17023SJohn Marino struct c_expr
c_expr_sizeof_expr(location_t loc,struct c_expr expr)2610e4b17023SJohn Marino c_expr_sizeof_expr (location_t loc, struct c_expr expr)
2611e4b17023SJohn Marino {
2612e4b17023SJohn Marino struct c_expr ret;
2613e4b17023SJohn Marino if (expr.value == error_mark_node)
2614e4b17023SJohn Marino {
2615e4b17023SJohn Marino ret.value = error_mark_node;
2616e4b17023SJohn Marino ret.original_code = ERROR_MARK;
2617e4b17023SJohn Marino ret.original_type = NULL;
2618e4b17023SJohn Marino pop_maybe_used (false);
2619e4b17023SJohn Marino }
2620e4b17023SJohn Marino else
2621e4b17023SJohn Marino {
2622e4b17023SJohn Marino bool expr_const_operands = true;
2623e4b17023SJohn Marino tree folded_expr = c_fully_fold (expr.value, require_constant_value,
2624e4b17023SJohn Marino &expr_const_operands);
2625e4b17023SJohn Marino ret.value = c_sizeof (loc, TREE_TYPE (folded_expr));
2626e4b17023SJohn Marino ret.original_code = ERROR_MARK;
2627e4b17023SJohn Marino ret.original_type = NULL;
2628e4b17023SJohn Marino if (c_vla_type_p (TREE_TYPE (folded_expr)))
2629e4b17023SJohn Marino {
2630e4b17023SJohn Marino /* sizeof is evaluated when given a vla (C99 6.5.3.4p2). */
2631e4b17023SJohn Marino ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
2632e4b17023SJohn Marino folded_expr, ret.value);
2633e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands;
2634e4b17023SJohn Marino SET_EXPR_LOCATION (ret.value, loc);
2635e4b17023SJohn Marino }
2636e4b17023SJohn Marino pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr)));
2637e4b17023SJohn Marino }
2638e4b17023SJohn Marino return ret;
2639e4b17023SJohn Marino }
2640e4b17023SJohn Marino
2641e4b17023SJohn Marino /* Return the result of sizeof applied to T, a structure for the type
2642e4b17023SJohn Marino name passed to sizeof (rather than the type itself). LOC is the
2643e4b17023SJohn Marino location of the original expression. */
2644e4b17023SJohn Marino
2645e4b17023SJohn Marino struct c_expr
c_expr_sizeof_type(location_t loc,struct c_type_name * t)2646e4b17023SJohn Marino c_expr_sizeof_type (location_t loc, struct c_type_name *t)
2647e4b17023SJohn Marino {
2648e4b17023SJohn Marino tree type;
2649e4b17023SJohn Marino struct c_expr ret;
2650e4b17023SJohn Marino tree type_expr = NULL_TREE;
2651e4b17023SJohn Marino bool type_expr_const = true;
2652e4b17023SJohn Marino type = groktypename (t, &type_expr, &type_expr_const);
2653e4b17023SJohn Marino ret.value = c_sizeof (loc, type);
2654e4b17023SJohn Marino ret.original_code = ERROR_MARK;
2655e4b17023SJohn Marino ret.original_type = NULL;
2656e4b17023SJohn Marino if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST)
2657e4b17023SJohn Marino && c_vla_type_p (type))
2658e4b17023SJohn Marino {
2659e4b17023SJohn Marino /* If the type is a [*] array, it is a VLA but is represented as
2660e4b17023SJohn Marino having a size of zero. In such a case we must ensure that
2661e4b17023SJohn Marino the result of sizeof does not get folded to a constant by
2662e4b17023SJohn Marino c_fully_fold, because if the size is evaluated the result is
2663e4b17023SJohn Marino not constant and so constraints on zero or negative size
2664e4b17023SJohn Marino arrays must not be applied when this sizeof call is inside
2665e4b17023SJohn Marino another array declarator. */
2666e4b17023SJohn Marino if (!type_expr)
2667e4b17023SJohn Marino type_expr = integer_zero_node;
2668e4b17023SJohn Marino ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
2669e4b17023SJohn Marino type_expr, ret.value);
2670e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !type_expr_const;
2671e4b17023SJohn Marino }
2672e4b17023SJohn Marino pop_maybe_used (type != error_mark_node
2673e4b17023SJohn Marino ? C_TYPE_VARIABLE_SIZE (type) : false);
2674e4b17023SJohn Marino return ret;
2675e4b17023SJohn Marino }
2676e4b17023SJohn Marino
2677e4b17023SJohn Marino /* Build a function call to function FUNCTION with parameters PARAMS.
2678e4b17023SJohn Marino The function call is at LOC.
2679e4b17023SJohn Marino PARAMS is a list--a chain of TREE_LIST nodes--in which the
2680e4b17023SJohn Marino TREE_VALUE of each node is a parameter-expression.
2681e4b17023SJohn Marino FUNCTION's data type may be a function type or a pointer-to-function. */
2682e4b17023SJohn Marino
2683e4b17023SJohn Marino tree
build_function_call(location_t loc,tree function,tree params)2684e4b17023SJohn Marino build_function_call (location_t loc, tree function, tree params)
2685e4b17023SJohn Marino {
2686e4b17023SJohn Marino VEC(tree,gc) *vec;
2687e4b17023SJohn Marino tree ret;
2688e4b17023SJohn Marino
2689e4b17023SJohn Marino vec = VEC_alloc (tree, gc, list_length (params));
2690e4b17023SJohn Marino for (; params; params = TREE_CHAIN (params))
2691e4b17023SJohn Marino VEC_quick_push (tree, vec, TREE_VALUE (params));
2692e4b17023SJohn Marino ret = build_function_call_vec (loc, function, vec, NULL);
2693e4b17023SJohn Marino VEC_free (tree, gc, vec);
2694e4b17023SJohn Marino return ret;
2695e4b17023SJohn Marino }
2696e4b17023SJohn Marino
2697e4b17023SJohn Marino /* Build a function call to function FUNCTION with parameters PARAMS.
2698e4b17023SJohn Marino ORIGTYPES, if not NULL, is a vector of types; each element is
2699e4b17023SJohn Marino either NULL or the original type of the corresponding element in
2700e4b17023SJohn Marino PARAMS. The original type may differ from TREE_TYPE of the
2701e4b17023SJohn Marino parameter for enums. FUNCTION's data type may be a function type
2702e4b17023SJohn Marino or pointer-to-function. This function changes the elements of
2703e4b17023SJohn Marino PARAMS. */
2704e4b17023SJohn Marino
2705e4b17023SJohn Marino tree
build_function_call_vec(location_t loc,tree function,VEC (tree,gc)* params,VEC (tree,gc)* origtypes)2706e4b17023SJohn Marino build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params,
2707e4b17023SJohn Marino VEC(tree,gc) *origtypes)
2708e4b17023SJohn Marino {
2709e4b17023SJohn Marino tree fntype, fundecl = 0;
2710e4b17023SJohn Marino tree name = NULL_TREE, result;
2711e4b17023SJohn Marino tree tem;
2712e4b17023SJohn Marino int nargs;
2713e4b17023SJohn Marino tree *argarray;
2714e4b17023SJohn Marino
2715e4b17023SJohn Marino
2716e4b17023SJohn Marino /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
2717e4b17023SJohn Marino STRIP_TYPE_NOPS (function);
2718e4b17023SJohn Marino
2719e4b17023SJohn Marino /* Convert anything with function type to a pointer-to-function. */
2720e4b17023SJohn Marino if (TREE_CODE (function) == FUNCTION_DECL)
2721e4b17023SJohn Marino {
2722e4b17023SJohn Marino /* Implement type-directed function overloading for builtins.
2723e4b17023SJohn Marino resolve_overloaded_builtin and targetm.resolve_overloaded_builtin
2724e4b17023SJohn Marino handle all the type checking. The result is a complete expression
2725e4b17023SJohn Marino that implements this function call. */
2726e4b17023SJohn Marino tem = resolve_overloaded_builtin (loc, function, params);
2727e4b17023SJohn Marino if (tem)
2728e4b17023SJohn Marino return tem;
2729e4b17023SJohn Marino
2730e4b17023SJohn Marino name = DECL_NAME (function);
2731e4b17023SJohn Marino
2732e4b17023SJohn Marino if (flag_tm)
2733e4b17023SJohn Marino tm_malloc_replacement (function);
2734e4b17023SJohn Marino fundecl = function;
2735e4b17023SJohn Marino /* Atomic functions have type checking/casting already done. They are
2736e4b17023SJohn Marino often rewritten and don't match the original parameter list. */
2737e4b17023SJohn Marino if (name && !strncmp (IDENTIFIER_POINTER (name), "__atomic_", 9))
2738e4b17023SJohn Marino origtypes = NULL;
2739e4b17023SJohn Marino }
2740e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
2741e4b17023SJohn Marino function = function_to_pointer_conversion (loc, function);
2742e4b17023SJohn Marino
2743e4b17023SJohn Marino /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
2744e4b17023SJohn Marino expressions, like those used for ObjC messenger dispatches. */
2745e4b17023SJohn Marino if (!VEC_empty (tree, params))
2746e4b17023SJohn Marino function = objc_rewrite_function_call (function,
2747e4b17023SJohn Marino VEC_index (tree, params, 0));
2748e4b17023SJohn Marino
2749e4b17023SJohn Marino function = c_fully_fold (function, false, NULL);
2750e4b17023SJohn Marino
2751e4b17023SJohn Marino fntype = TREE_TYPE (function);
2752e4b17023SJohn Marino
2753e4b17023SJohn Marino if (TREE_CODE (fntype) == ERROR_MARK)
2754e4b17023SJohn Marino return error_mark_node;
2755e4b17023SJohn Marino
2756e4b17023SJohn Marino if (!(TREE_CODE (fntype) == POINTER_TYPE
2757e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
2758e4b17023SJohn Marino {
2759e4b17023SJohn Marino error_at (loc, "called object %qE is not a function", function);
2760e4b17023SJohn Marino return error_mark_node;
2761e4b17023SJohn Marino }
2762e4b17023SJohn Marino
2763e4b17023SJohn Marino if (fundecl && TREE_THIS_VOLATILE (fundecl))
2764e4b17023SJohn Marino current_function_returns_abnormally = 1;
2765e4b17023SJohn Marino
2766e4b17023SJohn Marino /* fntype now gets the type of function pointed to. */
2767e4b17023SJohn Marino fntype = TREE_TYPE (fntype);
2768e4b17023SJohn Marino
2769e4b17023SJohn Marino /* Convert the parameters to the types declared in the
2770e4b17023SJohn Marino function prototype, or apply default promotions. */
2771e4b17023SJohn Marino
2772e4b17023SJohn Marino nargs = convert_arguments (TYPE_ARG_TYPES (fntype), params, origtypes,
2773e4b17023SJohn Marino function, fundecl);
2774e4b17023SJohn Marino if (nargs < 0)
2775e4b17023SJohn Marino return error_mark_node;
2776e4b17023SJohn Marino
2777e4b17023SJohn Marino /* Check that the function is called through a compatible prototype.
2778e4b17023SJohn Marino If it is not, replace the call by a trap, wrapped up in a compound
2779e4b17023SJohn Marino expression if necessary. This has the nice side-effect to prevent
2780e4b17023SJohn Marino the tree-inliner from generating invalid assignment trees which may
2781e4b17023SJohn Marino blow up in the RTL expander later. */
2782e4b17023SJohn Marino if (CONVERT_EXPR_P (function)
2783e4b17023SJohn Marino && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
2784e4b17023SJohn Marino && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
2785e4b17023SJohn Marino && !comptypes (fntype, TREE_TYPE (tem)))
2786e4b17023SJohn Marino {
2787e4b17023SJohn Marino tree return_type = TREE_TYPE (fntype);
2788e4b17023SJohn Marino tree trap = build_function_call (loc,
2789e4b17023SJohn Marino builtin_decl_explicit (BUILT_IN_TRAP),
2790e4b17023SJohn Marino NULL_TREE);
2791e4b17023SJohn Marino int i;
2792e4b17023SJohn Marino
2793e4b17023SJohn Marino /* This situation leads to run-time undefined behavior. We can't,
2794e4b17023SJohn Marino therefore, simply error unless we can prove that all possible
2795e4b17023SJohn Marino executions of the program must execute the code. */
2796e4b17023SJohn Marino if (warning_at (loc, 0, "function called through a non-compatible type"))
2797e4b17023SJohn Marino /* We can, however, treat "undefined" any way we please.
2798e4b17023SJohn Marino Call abort to encourage the user to fix the program. */
2799e4b17023SJohn Marino inform (loc, "if this code is reached, the program will abort");
2800e4b17023SJohn Marino /* Before the abort, allow the function arguments to exit or
2801e4b17023SJohn Marino call longjmp. */
2802e4b17023SJohn Marino for (i = 0; i < nargs; i++)
2803e4b17023SJohn Marino trap = build2 (COMPOUND_EXPR, void_type_node,
2804e4b17023SJohn Marino VEC_index (tree, params, i), trap);
2805e4b17023SJohn Marino
2806e4b17023SJohn Marino if (VOID_TYPE_P (return_type))
2807e4b17023SJohn Marino {
2808e4b17023SJohn Marino if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED)
2809e4b17023SJohn Marino pedwarn (loc, 0,
2810e4b17023SJohn Marino "function with qualified void return type called");
2811e4b17023SJohn Marino return trap;
2812e4b17023SJohn Marino }
2813e4b17023SJohn Marino else
2814e4b17023SJohn Marino {
2815e4b17023SJohn Marino tree rhs;
2816e4b17023SJohn Marino
2817e4b17023SJohn Marino if (AGGREGATE_TYPE_P (return_type))
2818e4b17023SJohn Marino rhs = build_compound_literal (loc, return_type,
2819e4b17023SJohn Marino build_constructor (return_type, 0),
2820e4b17023SJohn Marino false);
2821e4b17023SJohn Marino else
2822e4b17023SJohn Marino rhs = build_zero_cst (return_type);
2823e4b17023SJohn Marino
2824e4b17023SJohn Marino return require_complete_type (build2 (COMPOUND_EXPR, return_type,
2825e4b17023SJohn Marino trap, rhs));
2826e4b17023SJohn Marino }
2827e4b17023SJohn Marino }
2828e4b17023SJohn Marino
2829e4b17023SJohn Marino argarray = VEC_address (tree, params);
2830e4b17023SJohn Marino
2831e4b17023SJohn Marino /* Check that arguments to builtin functions match the expectations. */
2832e4b17023SJohn Marino if (fundecl
2833e4b17023SJohn Marino && DECL_BUILT_IN (fundecl)
2834e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
2835e4b17023SJohn Marino && !check_builtin_function_arguments (fundecl, nargs, argarray))
2836e4b17023SJohn Marino return error_mark_node;
2837e4b17023SJohn Marino
2838e4b17023SJohn Marino /* Check that the arguments to the function are valid. */
2839e4b17023SJohn Marino check_function_arguments (fntype, nargs, argarray);
2840e4b17023SJohn Marino
2841e4b17023SJohn Marino if (name != NULL_TREE
2842e4b17023SJohn Marino && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
2843e4b17023SJohn Marino {
2844e4b17023SJohn Marino if (require_constant_value)
2845e4b17023SJohn Marino result =
2846e4b17023SJohn Marino fold_build_call_array_initializer_loc (loc, TREE_TYPE (fntype),
2847e4b17023SJohn Marino function, nargs, argarray);
2848e4b17023SJohn Marino else
2849e4b17023SJohn Marino result = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
2850e4b17023SJohn Marino function, nargs, argarray);
2851e4b17023SJohn Marino if (TREE_CODE (result) == NOP_EXPR
2852e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (result, 0)) == INTEGER_CST)
2853e4b17023SJohn Marino STRIP_TYPE_NOPS (result);
2854e4b17023SJohn Marino }
2855e4b17023SJohn Marino else
2856e4b17023SJohn Marino result = build_call_array_loc (loc, TREE_TYPE (fntype),
2857e4b17023SJohn Marino function, nargs, argarray);
2858e4b17023SJohn Marino
2859e4b17023SJohn Marino if (VOID_TYPE_P (TREE_TYPE (result)))
2860e4b17023SJohn Marino {
2861e4b17023SJohn Marino if (TYPE_QUALS (TREE_TYPE (result)) != TYPE_UNQUALIFIED)
2862e4b17023SJohn Marino pedwarn (loc, 0,
2863e4b17023SJohn Marino "function with qualified void return type called");
2864e4b17023SJohn Marino return result;
2865e4b17023SJohn Marino }
2866e4b17023SJohn Marino return require_complete_type (result);
2867e4b17023SJohn Marino }
2868e4b17023SJohn Marino
2869e4b17023SJohn Marino /* Build a VEC_PERM_EXPR if V0, V1 and MASK are not error_mark_nodes
2870e4b17023SJohn Marino and have vector types, V0 has the same type as V1, and the number of
2871e4b17023SJohn Marino elements of V0, V1, MASK is the same.
2872e4b17023SJohn Marino
2873e4b17023SJohn Marino In case V1 is a NULL_TREE it is assumed that __builtin_shuffle was
2874e4b17023SJohn Marino called with two arguments. In this case implementation passes the
2875e4b17023SJohn Marino first argument twice in order to share the same tree code. This fact
2876e4b17023SJohn Marino could enable the mask-values being twice the vector length. This is
2877e4b17023SJohn Marino an implementation accident and this semantics is not guaranteed to
2878e4b17023SJohn Marino the user. */
2879e4b17023SJohn Marino tree
c_build_vec_perm_expr(location_t loc,tree v0,tree v1,tree mask)2880e4b17023SJohn Marino c_build_vec_perm_expr (location_t loc, tree v0, tree v1, tree mask)
2881e4b17023SJohn Marino {
2882e4b17023SJohn Marino tree ret;
2883e4b17023SJohn Marino bool wrap = true;
2884e4b17023SJohn Marino bool maybe_const = false;
2885e4b17023SJohn Marino bool two_arguments = false;
2886e4b17023SJohn Marino
2887e4b17023SJohn Marino if (v1 == NULL_TREE)
2888e4b17023SJohn Marino {
2889e4b17023SJohn Marino two_arguments = true;
2890e4b17023SJohn Marino v1 = v0;
2891e4b17023SJohn Marino }
2892e4b17023SJohn Marino
2893e4b17023SJohn Marino if (v0 == error_mark_node || v1 == error_mark_node
2894e4b17023SJohn Marino || mask == error_mark_node)
2895e4b17023SJohn Marino return error_mark_node;
2896e4b17023SJohn Marino
2897e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (mask)) != VECTOR_TYPE
2898e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (TREE_TYPE (mask))) != INTEGER_TYPE)
2899e4b17023SJohn Marino {
2900e4b17023SJohn Marino error_at (loc, "__builtin_shuffle last argument must "
2901e4b17023SJohn Marino "be an integer vector");
2902e4b17023SJohn Marino return error_mark_node;
2903e4b17023SJohn Marino }
2904e4b17023SJohn Marino
2905e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (v0)) != VECTOR_TYPE
2906e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (v1)) != VECTOR_TYPE)
2907e4b17023SJohn Marino {
2908e4b17023SJohn Marino error_at (loc, "__builtin_shuffle arguments must be vectors");
2909e4b17023SJohn Marino return error_mark_node;
2910e4b17023SJohn Marino }
2911e4b17023SJohn Marino
2912e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (TREE_TYPE (v0)) != TYPE_MAIN_VARIANT (TREE_TYPE (v1)))
2913e4b17023SJohn Marino {
2914e4b17023SJohn Marino error_at (loc, "__builtin_shuffle argument vectors must be of "
2915e4b17023SJohn Marino "the same type");
2916e4b17023SJohn Marino return error_mark_node;
2917e4b17023SJohn Marino }
2918e4b17023SJohn Marino
2919e4b17023SJohn Marino if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (v0))
2920e4b17023SJohn Marino != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask))
2921e4b17023SJohn Marino && TYPE_VECTOR_SUBPARTS (TREE_TYPE (v1))
2922e4b17023SJohn Marino != TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask)))
2923e4b17023SJohn Marino {
2924e4b17023SJohn Marino error_at (loc, "__builtin_shuffle number of elements of the "
2925e4b17023SJohn Marino "argument vector(s) and the mask vector should "
2926e4b17023SJohn Marino "be the same");
2927e4b17023SJohn Marino return error_mark_node;
2928e4b17023SJohn Marino }
2929e4b17023SJohn Marino
2930e4b17023SJohn Marino if (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (v0))))
2931e4b17023SJohn Marino != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (mask)))))
2932e4b17023SJohn Marino {
2933e4b17023SJohn Marino error_at (loc, "__builtin_shuffle argument vector(s) inner type "
2934e4b17023SJohn Marino "must have the same size as inner type of the mask");
2935e4b17023SJohn Marino return error_mark_node;
2936e4b17023SJohn Marino }
2937e4b17023SJohn Marino
2938e4b17023SJohn Marino /* Avoid C_MAYBE_CONST_EXPRs inside VEC_PERM_EXPR. */
2939e4b17023SJohn Marino v0 = c_fully_fold (v0, false, &maybe_const);
2940e4b17023SJohn Marino wrap &= maybe_const;
2941e4b17023SJohn Marino
2942e4b17023SJohn Marino if (two_arguments)
2943e4b17023SJohn Marino v1 = v0 = save_expr (v0);
2944e4b17023SJohn Marino else
2945e4b17023SJohn Marino {
2946e4b17023SJohn Marino v1 = c_fully_fold (v1, false, &maybe_const);
2947e4b17023SJohn Marino wrap &= maybe_const;
2948e4b17023SJohn Marino }
2949e4b17023SJohn Marino
2950e4b17023SJohn Marino mask = c_fully_fold (mask, false, &maybe_const);
2951e4b17023SJohn Marino wrap &= maybe_const;
2952e4b17023SJohn Marino
2953e4b17023SJohn Marino ret = build3_loc (loc, VEC_PERM_EXPR, TREE_TYPE (v0), v0, v1, mask);
2954e4b17023SJohn Marino
2955e4b17023SJohn Marino if (!wrap)
2956e4b17023SJohn Marino ret = c_wrap_maybe_const (ret, true);
2957e4b17023SJohn Marino
2958e4b17023SJohn Marino return ret;
2959e4b17023SJohn Marino }
2960e4b17023SJohn Marino
2961e4b17023SJohn Marino /* Convert the argument expressions in the vector VALUES
2962e4b17023SJohn Marino to the types in the list TYPELIST.
2963e4b17023SJohn Marino
2964e4b17023SJohn Marino If TYPELIST is exhausted, or when an element has NULL as its type,
2965e4b17023SJohn Marino perform the default conversions.
2966e4b17023SJohn Marino
2967e4b17023SJohn Marino ORIGTYPES is the original types of the expressions in VALUES. This
2968e4b17023SJohn Marino holds the type of enum values which have been converted to integral
2969e4b17023SJohn Marino types. It may be NULL.
2970e4b17023SJohn Marino
2971e4b17023SJohn Marino FUNCTION is a tree for the called function. It is used only for
2972e4b17023SJohn Marino error messages, where it is formatted with %qE.
2973e4b17023SJohn Marino
2974e4b17023SJohn Marino This is also where warnings about wrong number of args are generated.
2975e4b17023SJohn Marino
2976e4b17023SJohn Marino Returns the actual number of arguments processed (which may be less
2977e4b17023SJohn Marino than the length of VALUES in some error situations), or -1 on
2978e4b17023SJohn Marino failure. */
2979e4b17023SJohn Marino
2980e4b17023SJohn Marino static int
convert_arguments(tree typelist,VEC (tree,gc)* values,VEC (tree,gc)* origtypes,tree function,tree fundecl)2981e4b17023SJohn Marino convert_arguments (tree typelist, VEC(tree,gc) *values,
2982e4b17023SJohn Marino VEC(tree,gc) *origtypes, tree function, tree fundecl)
2983e4b17023SJohn Marino {
2984e4b17023SJohn Marino tree typetail, val;
2985e4b17023SJohn Marino unsigned int parmnum;
2986e4b17023SJohn Marino bool error_args = false;
2987e4b17023SJohn Marino const bool type_generic = fundecl
2988e4b17023SJohn Marino && lookup_attribute ("type generic", TYPE_ATTRIBUTES(TREE_TYPE (fundecl)));
2989e4b17023SJohn Marino bool type_generic_remove_excess_precision = false;
2990e4b17023SJohn Marino tree selector;
2991e4b17023SJohn Marino
2992e4b17023SJohn Marino /* Change pointer to function to the function itself for
2993e4b17023SJohn Marino diagnostics. */
2994e4b17023SJohn Marino if (TREE_CODE (function) == ADDR_EXPR
2995e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
2996e4b17023SJohn Marino function = TREE_OPERAND (function, 0);
2997e4b17023SJohn Marino
2998e4b17023SJohn Marino /* Handle an ObjC selector specially for diagnostics. */
2999e4b17023SJohn Marino selector = objc_message_selector ();
3000e4b17023SJohn Marino
3001e4b17023SJohn Marino /* For type-generic built-in functions, determine whether excess
3002e4b17023SJohn Marino precision should be removed (classification) or not
3003e4b17023SJohn Marino (comparison). */
3004e4b17023SJohn Marino if (type_generic
3005e4b17023SJohn Marino && DECL_BUILT_IN (fundecl)
3006e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL)
3007e4b17023SJohn Marino {
3008e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (fundecl))
3009e4b17023SJohn Marino {
3010e4b17023SJohn Marino case BUILT_IN_ISFINITE:
3011e4b17023SJohn Marino case BUILT_IN_ISINF:
3012e4b17023SJohn Marino case BUILT_IN_ISINF_SIGN:
3013e4b17023SJohn Marino case BUILT_IN_ISNAN:
3014e4b17023SJohn Marino case BUILT_IN_ISNORMAL:
3015e4b17023SJohn Marino case BUILT_IN_FPCLASSIFY:
3016e4b17023SJohn Marino type_generic_remove_excess_precision = true;
3017e4b17023SJohn Marino break;
3018e4b17023SJohn Marino
3019e4b17023SJohn Marino default:
3020e4b17023SJohn Marino type_generic_remove_excess_precision = false;
3021e4b17023SJohn Marino break;
3022e4b17023SJohn Marino }
3023e4b17023SJohn Marino }
3024e4b17023SJohn Marino
3025e4b17023SJohn Marino /* Scan the given expressions and types, producing individual
3026e4b17023SJohn Marino converted arguments. */
3027e4b17023SJohn Marino
3028e4b17023SJohn Marino for (typetail = typelist, parmnum = 0;
3029e4b17023SJohn Marino VEC_iterate (tree, values, parmnum, val);
3030e4b17023SJohn Marino ++parmnum)
3031e4b17023SJohn Marino {
3032e4b17023SJohn Marino tree type = typetail ? TREE_VALUE (typetail) : 0;
3033e4b17023SJohn Marino tree valtype = TREE_TYPE (val);
3034e4b17023SJohn Marino tree rname = function;
3035e4b17023SJohn Marino int argnum = parmnum + 1;
3036e4b17023SJohn Marino const char *invalid_func_diag;
3037e4b17023SJohn Marino bool excess_precision = false;
3038e4b17023SJohn Marino bool npc;
3039e4b17023SJohn Marino tree parmval;
3040e4b17023SJohn Marino
3041e4b17023SJohn Marino if (type == void_type_node)
3042e4b17023SJohn Marino {
3043e4b17023SJohn Marino if (selector)
3044e4b17023SJohn Marino error_at (input_location,
3045e4b17023SJohn Marino "too many arguments to method %qE", selector);
3046e4b17023SJohn Marino else
3047e4b17023SJohn Marino error_at (input_location,
3048e4b17023SJohn Marino "too many arguments to function %qE", function);
3049e4b17023SJohn Marino
3050e4b17023SJohn Marino if (fundecl && !DECL_BUILT_IN (fundecl))
3051e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (fundecl), "declared here");
3052e4b17023SJohn Marino return parmnum;
3053e4b17023SJohn Marino }
3054e4b17023SJohn Marino
3055e4b17023SJohn Marino if (selector && argnum > 2)
3056e4b17023SJohn Marino {
3057e4b17023SJohn Marino rname = selector;
3058e4b17023SJohn Marino argnum -= 2;
3059e4b17023SJohn Marino }
3060e4b17023SJohn Marino
3061e4b17023SJohn Marino npc = null_pointer_constant_p (val);
3062e4b17023SJohn Marino
3063e4b17023SJohn Marino /* If there is excess precision and a prototype, convert once to
3064e4b17023SJohn Marino the required type rather than converting via the semantic
3065e4b17023SJohn Marino type. Likewise without a prototype a float value represented
3066e4b17023SJohn Marino as long double should be converted once to double. But for
3067e4b17023SJohn Marino type-generic classification functions excess precision must
3068e4b17023SJohn Marino be removed here. */
3069e4b17023SJohn Marino if (TREE_CODE (val) == EXCESS_PRECISION_EXPR
3070e4b17023SJohn Marino && (type || !type_generic || !type_generic_remove_excess_precision))
3071e4b17023SJohn Marino {
3072e4b17023SJohn Marino val = TREE_OPERAND (val, 0);
3073e4b17023SJohn Marino excess_precision = true;
3074e4b17023SJohn Marino }
3075e4b17023SJohn Marino val = c_fully_fold (val, false, NULL);
3076e4b17023SJohn Marino STRIP_TYPE_NOPS (val);
3077e4b17023SJohn Marino
3078e4b17023SJohn Marino val = require_complete_type (val);
3079e4b17023SJohn Marino
3080e4b17023SJohn Marino if (type != 0)
3081e4b17023SJohn Marino {
3082e4b17023SJohn Marino /* Formal parm type is specified by a function prototype. */
3083e4b17023SJohn Marino
3084e4b17023SJohn Marino if (type == error_mark_node || !COMPLETE_TYPE_P (type))
3085e4b17023SJohn Marino {
3086e4b17023SJohn Marino error ("type of formal parameter %d is incomplete", parmnum + 1);
3087e4b17023SJohn Marino parmval = val;
3088e4b17023SJohn Marino }
3089e4b17023SJohn Marino else
3090e4b17023SJohn Marino {
3091e4b17023SJohn Marino tree origtype;
3092e4b17023SJohn Marino
3093e4b17023SJohn Marino /* Optionally warn about conversions that
3094e4b17023SJohn Marino differ from the default conversions. */
3095e4b17023SJohn Marino if (warn_traditional_conversion || warn_traditional)
3096e4b17023SJohn Marino {
3097e4b17023SJohn Marino unsigned int formal_prec = TYPE_PRECISION (type);
3098e4b17023SJohn Marino
3099e4b17023SJohn Marino if (INTEGRAL_TYPE_P (type)
3100e4b17023SJohn Marino && TREE_CODE (valtype) == REAL_TYPE)
3101e4b17023SJohn Marino warning (0, "passing argument %d of %qE as integer "
3102e4b17023SJohn Marino "rather than floating due to prototype",
3103e4b17023SJohn Marino argnum, rname);
3104e4b17023SJohn Marino if (INTEGRAL_TYPE_P (type)
3105e4b17023SJohn Marino && TREE_CODE (valtype) == COMPLEX_TYPE)
3106e4b17023SJohn Marino warning (0, "passing argument %d of %qE as integer "
3107e4b17023SJohn Marino "rather than complex due to prototype",
3108e4b17023SJohn Marino argnum, rname);
3109e4b17023SJohn Marino else if (TREE_CODE (type) == COMPLEX_TYPE
3110e4b17023SJohn Marino && TREE_CODE (valtype) == REAL_TYPE)
3111e4b17023SJohn Marino warning (0, "passing argument %d of %qE as complex "
3112e4b17023SJohn Marino "rather than floating due to prototype",
3113e4b17023SJohn Marino argnum, rname);
3114e4b17023SJohn Marino else if (TREE_CODE (type) == REAL_TYPE
3115e4b17023SJohn Marino && INTEGRAL_TYPE_P (valtype))
3116e4b17023SJohn Marino warning (0, "passing argument %d of %qE as floating "
3117e4b17023SJohn Marino "rather than integer due to prototype",
3118e4b17023SJohn Marino argnum, rname);
3119e4b17023SJohn Marino else if (TREE_CODE (type) == COMPLEX_TYPE
3120e4b17023SJohn Marino && INTEGRAL_TYPE_P (valtype))
3121e4b17023SJohn Marino warning (0, "passing argument %d of %qE as complex "
3122e4b17023SJohn Marino "rather than integer due to prototype",
3123e4b17023SJohn Marino argnum, rname);
3124e4b17023SJohn Marino else if (TREE_CODE (type) == REAL_TYPE
3125e4b17023SJohn Marino && TREE_CODE (valtype) == COMPLEX_TYPE)
3126e4b17023SJohn Marino warning (0, "passing argument %d of %qE as floating "
3127e4b17023SJohn Marino "rather than complex due to prototype",
3128e4b17023SJohn Marino argnum, rname);
3129e4b17023SJohn Marino /* ??? At some point, messages should be written about
3130e4b17023SJohn Marino conversions between complex types, but that's too messy
3131e4b17023SJohn Marino to do now. */
3132e4b17023SJohn Marino else if (TREE_CODE (type) == REAL_TYPE
3133e4b17023SJohn Marino && TREE_CODE (valtype) == REAL_TYPE)
3134e4b17023SJohn Marino {
3135e4b17023SJohn Marino /* Warn if any argument is passed as `float',
3136e4b17023SJohn Marino since without a prototype it would be `double'. */
3137e4b17023SJohn Marino if (formal_prec == TYPE_PRECISION (float_type_node)
3138e4b17023SJohn Marino && type != dfloat32_type_node)
3139e4b17023SJohn Marino warning (0, "passing argument %d of %qE as %<float%> "
3140e4b17023SJohn Marino "rather than %<double%> due to prototype",
3141e4b17023SJohn Marino argnum, rname);
3142e4b17023SJohn Marino
3143e4b17023SJohn Marino /* Warn if mismatch between argument and prototype
3144e4b17023SJohn Marino for decimal float types. Warn of conversions with
3145e4b17023SJohn Marino binary float types and of precision narrowing due to
3146e4b17023SJohn Marino prototype. */
3147e4b17023SJohn Marino else if (type != valtype
3148e4b17023SJohn Marino && (type == dfloat32_type_node
3149e4b17023SJohn Marino || type == dfloat64_type_node
3150e4b17023SJohn Marino || type == dfloat128_type_node
3151e4b17023SJohn Marino || valtype == dfloat32_type_node
3152e4b17023SJohn Marino || valtype == dfloat64_type_node
3153e4b17023SJohn Marino || valtype == dfloat128_type_node)
3154e4b17023SJohn Marino && (formal_prec
3155e4b17023SJohn Marino <= TYPE_PRECISION (valtype)
3156e4b17023SJohn Marino || (type == dfloat128_type_node
3157e4b17023SJohn Marino && (valtype
3158e4b17023SJohn Marino != dfloat64_type_node
3159e4b17023SJohn Marino && (valtype
3160e4b17023SJohn Marino != dfloat32_type_node)))
3161e4b17023SJohn Marino || (type == dfloat64_type_node
3162e4b17023SJohn Marino && (valtype
3163e4b17023SJohn Marino != dfloat32_type_node))))
3164e4b17023SJohn Marino warning (0, "passing argument %d of %qE as %qT "
3165e4b17023SJohn Marino "rather than %qT due to prototype",
3166e4b17023SJohn Marino argnum, rname, type, valtype);
3167e4b17023SJohn Marino
3168e4b17023SJohn Marino }
3169e4b17023SJohn Marino /* Detect integer changing in width or signedness.
3170e4b17023SJohn Marino These warnings are only activated with
3171e4b17023SJohn Marino -Wtraditional-conversion, not with -Wtraditional. */
3172e4b17023SJohn Marino else if (warn_traditional_conversion && INTEGRAL_TYPE_P (type)
3173e4b17023SJohn Marino && INTEGRAL_TYPE_P (valtype))
3174e4b17023SJohn Marino {
3175e4b17023SJohn Marino tree would_have_been = default_conversion (val);
3176e4b17023SJohn Marino tree type1 = TREE_TYPE (would_have_been);
3177e4b17023SJohn Marino
3178e4b17023SJohn Marino if (TREE_CODE (type) == ENUMERAL_TYPE
3179e4b17023SJohn Marino && (TYPE_MAIN_VARIANT (type)
3180e4b17023SJohn Marino == TYPE_MAIN_VARIANT (valtype)))
3181e4b17023SJohn Marino /* No warning if function asks for enum
3182e4b17023SJohn Marino and the actual arg is that enum type. */
3183e4b17023SJohn Marino ;
3184e4b17023SJohn Marino else if (formal_prec != TYPE_PRECISION (type1))
3185e4b17023SJohn Marino warning (OPT_Wtraditional_conversion,
3186e4b17023SJohn Marino "passing argument %d of %qE "
3187e4b17023SJohn Marino "with different width due to prototype",
3188e4b17023SJohn Marino argnum, rname);
3189e4b17023SJohn Marino else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
3190e4b17023SJohn Marino ;
3191e4b17023SJohn Marino /* Don't complain if the formal parameter type
3192e4b17023SJohn Marino is an enum, because we can't tell now whether
3193e4b17023SJohn Marino the value was an enum--even the same enum. */
3194e4b17023SJohn Marino else if (TREE_CODE (type) == ENUMERAL_TYPE)
3195e4b17023SJohn Marino ;
3196e4b17023SJohn Marino else if (TREE_CODE (val) == INTEGER_CST
3197e4b17023SJohn Marino && int_fits_type_p (val, type))
3198e4b17023SJohn Marino /* Change in signedness doesn't matter
3199e4b17023SJohn Marino if a constant value is unaffected. */
3200e4b17023SJohn Marino ;
3201e4b17023SJohn Marino /* If the value is extended from a narrower
3202e4b17023SJohn Marino unsigned type, it doesn't matter whether we
3203e4b17023SJohn Marino pass it as signed or unsigned; the value
3204e4b17023SJohn Marino certainly is the same either way. */
3205e4b17023SJohn Marino else if (TYPE_PRECISION (valtype) < TYPE_PRECISION (type)
3206e4b17023SJohn Marino && TYPE_UNSIGNED (valtype))
3207e4b17023SJohn Marino ;
3208e4b17023SJohn Marino else if (TYPE_UNSIGNED (type))
3209e4b17023SJohn Marino warning (OPT_Wtraditional_conversion,
3210e4b17023SJohn Marino "passing argument %d of %qE "
3211e4b17023SJohn Marino "as unsigned due to prototype",
3212e4b17023SJohn Marino argnum, rname);
3213e4b17023SJohn Marino else
3214e4b17023SJohn Marino warning (OPT_Wtraditional_conversion,
3215e4b17023SJohn Marino "passing argument %d of %qE "
3216e4b17023SJohn Marino "as signed due to prototype", argnum, rname);
3217e4b17023SJohn Marino }
3218e4b17023SJohn Marino }
3219e4b17023SJohn Marino
3220e4b17023SJohn Marino /* Possibly restore an EXCESS_PRECISION_EXPR for the
3221e4b17023SJohn Marino sake of better warnings from convert_and_check. */
3222e4b17023SJohn Marino if (excess_precision)
3223e4b17023SJohn Marino val = build1 (EXCESS_PRECISION_EXPR, valtype, val);
3224e4b17023SJohn Marino origtype = (origtypes == NULL
3225e4b17023SJohn Marino ? NULL_TREE
3226e4b17023SJohn Marino : VEC_index (tree, origtypes, parmnum));
3227e4b17023SJohn Marino parmval = convert_for_assignment (input_location, type, val,
3228e4b17023SJohn Marino origtype, ic_argpass, npc,
3229e4b17023SJohn Marino fundecl, function,
3230e4b17023SJohn Marino parmnum + 1);
3231e4b17023SJohn Marino
3232e4b17023SJohn Marino if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
3233e4b17023SJohn Marino && INTEGRAL_TYPE_P (type)
3234e4b17023SJohn Marino && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
3235e4b17023SJohn Marino parmval = default_conversion (parmval);
3236e4b17023SJohn Marino }
3237e4b17023SJohn Marino }
3238e4b17023SJohn Marino else if (TREE_CODE (valtype) == REAL_TYPE
3239e4b17023SJohn Marino && (TYPE_PRECISION (valtype)
3240e4b17023SJohn Marino < TYPE_PRECISION (double_type_node))
3241e4b17023SJohn Marino && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (valtype)))
3242e4b17023SJohn Marino {
3243e4b17023SJohn Marino if (type_generic)
3244e4b17023SJohn Marino parmval = val;
3245e4b17023SJohn Marino else
3246e4b17023SJohn Marino {
3247e4b17023SJohn Marino /* Convert `float' to `double'. */
3248e4b17023SJohn Marino if (warn_double_promotion && !c_inhibit_evaluation_warnings)
3249e4b17023SJohn Marino warning (OPT_Wdouble_promotion,
3250e4b17023SJohn Marino "implicit conversion from %qT to %qT when passing "
3251e4b17023SJohn Marino "argument to function",
3252e4b17023SJohn Marino valtype, double_type_node);
3253e4b17023SJohn Marino parmval = convert (double_type_node, val);
3254e4b17023SJohn Marino }
3255e4b17023SJohn Marino }
3256e4b17023SJohn Marino else if (excess_precision && !type_generic)
3257e4b17023SJohn Marino /* A "double" argument with excess precision being passed
3258e4b17023SJohn Marino without a prototype or in variable arguments. */
3259e4b17023SJohn Marino parmval = convert (valtype, val);
3260e4b17023SJohn Marino else if ((invalid_func_diag =
3261e4b17023SJohn Marino targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
3262e4b17023SJohn Marino {
3263e4b17023SJohn Marino error (invalid_func_diag);
3264e4b17023SJohn Marino return -1;
3265e4b17023SJohn Marino }
3266e4b17023SJohn Marino else
3267e4b17023SJohn Marino /* Convert `short' and `char' to full-size `int'. */
3268e4b17023SJohn Marino parmval = default_conversion (val);
3269e4b17023SJohn Marino
3270e4b17023SJohn Marino VEC_replace (tree, values, parmnum, parmval);
3271e4b17023SJohn Marino if (parmval == error_mark_node)
3272e4b17023SJohn Marino error_args = true;
3273e4b17023SJohn Marino
3274e4b17023SJohn Marino if (typetail)
3275e4b17023SJohn Marino typetail = TREE_CHAIN (typetail);
3276e4b17023SJohn Marino }
3277e4b17023SJohn Marino
3278e4b17023SJohn Marino gcc_assert (parmnum == VEC_length (tree, values));
3279e4b17023SJohn Marino
3280e4b17023SJohn Marino if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
3281e4b17023SJohn Marino {
3282e4b17023SJohn Marino error_at (input_location,
3283e4b17023SJohn Marino "too few arguments to function %qE", function);
3284e4b17023SJohn Marino if (fundecl && !DECL_BUILT_IN (fundecl))
3285e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (fundecl), "declared here");
3286e4b17023SJohn Marino return -1;
3287e4b17023SJohn Marino }
3288e4b17023SJohn Marino
3289e4b17023SJohn Marino return error_args ? -1 : (int) parmnum;
3290e4b17023SJohn Marino }
3291e4b17023SJohn Marino
3292e4b17023SJohn Marino /* This is the entry point used by the parser to build unary operators
3293e4b17023SJohn Marino in the input. CODE, a tree_code, specifies the unary operator, and
3294e4b17023SJohn Marino ARG is the operand. For unary plus, the C parser currently uses
3295e4b17023SJohn Marino CONVERT_EXPR for code.
3296e4b17023SJohn Marino
3297e4b17023SJohn Marino LOC is the location to use for the tree generated.
3298e4b17023SJohn Marino */
3299e4b17023SJohn Marino
3300e4b17023SJohn Marino struct c_expr
parser_build_unary_op(location_t loc,enum tree_code code,struct c_expr arg)3301e4b17023SJohn Marino parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
3302e4b17023SJohn Marino {
3303e4b17023SJohn Marino struct c_expr result;
3304e4b17023SJohn Marino
3305e4b17023SJohn Marino result.value = build_unary_op (loc, code, arg.value, 0);
3306e4b17023SJohn Marino result.original_code = code;
3307e4b17023SJohn Marino result.original_type = NULL;
3308e4b17023SJohn Marino
3309e4b17023SJohn Marino if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
3310e4b17023SJohn Marino overflow_warning (loc, result.value);
3311e4b17023SJohn Marino
3312e4b17023SJohn Marino return result;
3313e4b17023SJohn Marino }
3314e4b17023SJohn Marino
3315e4b17023SJohn Marino /* This is the entry point used by the parser to build binary operators
3316e4b17023SJohn Marino in the input. CODE, a tree_code, specifies the binary operator, and
3317e4b17023SJohn Marino ARG1 and ARG2 are the operands. In addition to constructing the
3318e4b17023SJohn Marino expression, we check for operands that were written with other binary
3319e4b17023SJohn Marino operators in a way that is likely to confuse the user.
3320e4b17023SJohn Marino
3321e4b17023SJohn Marino LOCATION is the location of the binary operator. */
3322e4b17023SJohn Marino
3323e4b17023SJohn Marino struct c_expr
parser_build_binary_op(location_t location,enum tree_code code,struct c_expr arg1,struct c_expr arg2)3324e4b17023SJohn Marino parser_build_binary_op (location_t location, enum tree_code code,
3325e4b17023SJohn Marino struct c_expr arg1, struct c_expr arg2)
3326e4b17023SJohn Marino {
3327e4b17023SJohn Marino struct c_expr result;
3328e4b17023SJohn Marino
3329e4b17023SJohn Marino enum tree_code code1 = arg1.original_code;
3330e4b17023SJohn Marino enum tree_code code2 = arg2.original_code;
3331e4b17023SJohn Marino tree type1 = (arg1.original_type
3332e4b17023SJohn Marino ? arg1.original_type
3333e4b17023SJohn Marino : TREE_TYPE (arg1.value));
3334e4b17023SJohn Marino tree type2 = (arg2.original_type
3335e4b17023SJohn Marino ? arg2.original_type
3336e4b17023SJohn Marino : TREE_TYPE (arg2.value));
3337e4b17023SJohn Marino
3338e4b17023SJohn Marino result.value = build_binary_op (location, code,
3339e4b17023SJohn Marino arg1.value, arg2.value, 1);
3340e4b17023SJohn Marino result.original_code = code;
3341e4b17023SJohn Marino result.original_type = NULL;
3342e4b17023SJohn Marino
3343e4b17023SJohn Marino if (TREE_CODE (result.value) == ERROR_MARK)
3344e4b17023SJohn Marino return result;
3345e4b17023SJohn Marino
3346e4b17023SJohn Marino if (location != UNKNOWN_LOCATION)
3347e4b17023SJohn Marino protected_set_expr_location (result.value, location);
3348e4b17023SJohn Marino
3349e4b17023SJohn Marino /* Check for cases such as x+y<<z which users are likely
3350e4b17023SJohn Marino to misinterpret. */
3351e4b17023SJohn Marino if (warn_parentheses)
3352e4b17023SJohn Marino warn_about_parentheses (code, code1, arg1.value, code2, arg2.value);
3353e4b17023SJohn Marino
3354e4b17023SJohn Marino if (warn_logical_op)
3355e4b17023SJohn Marino warn_logical_operator (input_location, code, TREE_TYPE (result.value),
3356e4b17023SJohn Marino code1, arg1.value, code2, arg2.value);
3357e4b17023SJohn Marino
3358e4b17023SJohn Marino /* Warn about comparisons against string literals, with the exception
3359e4b17023SJohn Marino of testing for equality or inequality of a string literal with NULL. */
3360e4b17023SJohn Marino if (code == EQ_EXPR || code == NE_EXPR)
3361e4b17023SJohn Marino {
3362e4b17023SJohn Marino if ((code1 == STRING_CST && !integer_zerop (arg2.value))
3363e4b17023SJohn Marino || (code2 == STRING_CST && !integer_zerop (arg1.value)))
3364e4b17023SJohn Marino warning_at (location, OPT_Waddress,
3365e4b17023SJohn Marino "comparison with string literal results in unspecified behavior");
3366e4b17023SJohn Marino }
3367e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_comparison
3368e4b17023SJohn Marino && (code1 == STRING_CST || code2 == STRING_CST))
3369e4b17023SJohn Marino warning_at (location, OPT_Waddress,
3370e4b17023SJohn Marino "comparison with string literal results in unspecified behavior");
3371e4b17023SJohn Marino
3372e4b17023SJohn Marino if (TREE_OVERFLOW_P (result.value)
3373e4b17023SJohn Marino && !TREE_OVERFLOW_P (arg1.value)
3374e4b17023SJohn Marino && !TREE_OVERFLOW_P (arg2.value))
3375e4b17023SJohn Marino overflow_warning (location, result.value);
3376e4b17023SJohn Marino
3377e4b17023SJohn Marino /* Warn about comparisons of different enum types. */
3378e4b17023SJohn Marino if (warn_enum_compare
3379e4b17023SJohn Marino && TREE_CODE_CLASS (code) == tcc_comparison
3380e4b17023SJohn Marino && TREE_CODE (type1) == ENUMERAL_TYPE
3381e4b17023SJohn Marino && TREE_CODE (type2) == ENUMERAL_TYPE
3382e4b17023SJohn Marino && TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
3383e4b17023SJohn Marino warning_at (location, OPT_Wenum_compare,
3384e4b17023SJohn Marino "comparison between %qT and %qT",
3385e4b17023SJohn Marino type1, type2);
3386e4b17023SJohn Marino
3387e4b17023SJohn Marino return result;
3388e4b17023SJohn Marino }
3389e4b17023SJohn Marino
3390e4b17023SJohn Marino /* Return a tree for the difference of pointers OP0 and OP1.
3391e4b17023SJohn Marino The resulting tree has type int. */
3392e4b17023SJohn Marino
3393e4b17023SJohn Marino static tree
pointer_diff(location_t loc,tree op0,tree op1)3394e4b17023SJohn Marino pointer_diff (location_t loc, tree op0, tree op1)
3395e4b17023SJohn Marino {
3396e4b17023SJohn Marino tree restype = ptrdiff_type_node;
3397e4b17023SJohn Marino tree result, inttype;
3398e4b17023SJohn Marino
3399e4b17023SJohn Marino addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
3400e4b17023SJohn Marino addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
3401e4b17023SJohn Marino tree target_type = TREE_TYPE (TREE_TYPE (op0));
3402e4b17023SJohn Marino tree con0, con1, lit0, lit1;
3403e4b17023SJohn Marino tree orig_op1 = op1;
3404e4b17023SJohn Marino
3405e4b17023SJohn Marino /* If the operands point into different address spaces, we need to
3406e4b17023SJohn Marino explicitly convert them to pointers into the common address space
3407e4b17023SJohn Marino before we can subtract the numerical address values. */
3408e4b17023SJohn Marino if (as0 != as1)
3409e4b17023SJohn Marino {
3410e4b17023SJohn Marino addr_space_t as_common;
3411e4b17023SJohn Marino tree common_type;
3412e4b17023SJohn Marino
3413e4b17023SJohn Marino /* Determine the common superset address space. This is guaranteed
3414e4b17023SJohn Marino to exist because the caller verified that comp_target_types
3415e4b17023SJohn Marino returned non-zero. */
3416e4b17023SJohn Marino if (!addr_space_superset (as0, as1, &as_common))
3417e4b17023SJohn Marino gcc_unreachable ();
3418e4b17023SJohn Marino
3419e4b17023SJohn Marino common_type = common_pointer_type (TREE_TYPE (op0), TREE_TYPE (op1));
3420e4b17023SJohn Marino op0 = convert (common_type, op0);
3421e4b17023SJohn Marino op1 = convert (common_type, op1);
3422e4b17023SJohn Marino }
3423e4b17023SJohn Marino
3424e4b17023SJohn Marino /* Determine integer type to perform computations in. This will usually
3425e4b17023SJohn Marino be the same as the result type (ptrdiff_t), but may need to be a wider
3426e4b17023SJohn Marino type if pointers for the address space are wider than ptrdiff_t. */
3427e4b17023SJohn Marino if (TYPE_PRECISION (restype) < TYPE_PRECISION (TREE_TYPE (op0)))
3428e4b17023SJohn Marino inttype = lang_hooks.types.type_for_size
3429e4b17023SJohn Marino (TYPE_PRECISION (TREE_TYPE (op0)), 0);
3430e4b17023SJohn Marino else
3431e4b17023SJohn Marino inttype = restype;
3432e4b17023SJohn Marino
3433e4b17023SJohn Marino
3434e4b17023SJohn Marino if (TREE_CODE (target_type) == VOID_TYPE)
3435e4b17023SJohn Marino pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
3436e4b17023SJohn Marino "pointer of type %<void *%> used in subtraction");
3437e4b17023SJohn Marino if (TREE_CODE (target_type) == FUNCTION_TYPE)
3438e4b17023SJohn Marino pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
3439e4b17023SJohn Marino "pointer to a function used in subtraction");
3440e4b17023SJohn Marino
3441e4b17023SJohn Marino /* If the conversion to ptrdiff_type does anything like widening or
3442e4b17023SJohn Marino converting a partial to an integral mode, we get a convert_expression
3443e4b17023SJohn Marino that is in the way to do any simplifications.
3444e4b17023SJohn Marino (fold-const.c doesn't know that the extra bits won't be needed.
3445e4b17023SJohn Marino split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
3446e4b17023SJohn Marino different mode in place.)
3447e4b17023SJohn Marino So first try to find a common term here 'by hand'; we want to cover
3448e4b17023SJohn Marino at least the cases that occur in legal static initializers. */
3449e4b17023SJohn Marino if (CONVERT_EXPR_P (op0)
3450e4b17023SJohn Marino && (TYPE_PRECISION (TREE_TYPE (op0))
3451e4b17023SJohn Marino == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
3452e4b17023SJohn Marino con0 = TREE_OPERAND (op0, 0);
3453e4b17023SJohn Marino else
3454e4b17023SJohn Marino con0 = op0;
3455e4b17023SJohn Marino if (CONVERT_EXPR_P (op1)
3456e4b17023SJohn Marino && (TYPE_PRECISION (TREE_TYPE (op1))
3457e4b17023SJohn Marino == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
3458e4b17023SJohn Marino con1 = TREE_OPERAND (op1, 0);
3459e4b17023SJohn Marino else
3460e4b17023SJohn Marino con1 = op1;
3461e4b17023SJohn Marino
3462e4b17023SJohn Marino if (TREE_CODE (con0) == PLUS_EXPR)
3463e4b17023SJohn Marino {
3464e4b17023SJohn Marino lit0 = TREE_OPERAND (con0, 1);
3465e4b17023SJohn Marino con0 = TREE_OPERAND (con0, 0);
3466e4b17023SJohn Marino }
3467e4b17023SJohn Marino else
3468e4b17023SJohn Marino lit0 = integer_zero_node;
3469e4b17023SJohn Marino
3470e4b17023SJohn Marino if (TREE_CODE (con1) == PLUS_EXPR)
3471e4b17023SJohn Marino {
3472e4b17023SJohn Marino lit1 = TREE_OPERAND (con1, 1);
3473e4b17023SJohn Marino con1 = TREE_OPERAND (con1, 0);
3474e4b17023SJohn Marino }
3475e4b17023SJohn Marino else
3476e4b17023SJohn Marino lit1 = integer_zero_node;
3477e4b17023SJohn Marino
3478e4b17023SJohn Marino if (operand_equal_p (con0, con1, 0))
3479e4b17023SJohn Marino {
3480e4b17023SJohn Marino op0 = lit0;
3481e4b17023SJohn Marino op1 = lit1;
3482e4b17023SJohn Marino }
3483e4b17023SJohn Marino
3484e4b17023SJohn Marino
3485e4b17023SJohn Marino /* First do the subtraction as integers;
3486e4b17023SJohn Marino then drop through to build the divide operator.
3487e4b17023SJohn Marino Do not do default conversions on the minus operator
3488e4b17023SJohn Marino in case restype is a short type. */
3489e4b17023SJohn Marino
3490e4b17023SJohn Marino op0 = build_binary_op (loc,
3491e4b17023SJohn Marino MINUS_EXPR, convert (inttype, op0),
3492e4b17023SJohn Marino convert (inttype, op1), 0);
3493e4b17023SJohn Marino /* This generates an error if op1 is pointer to incomplete type. */
3494e4b17023SJohn Marino if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
3495e4b17023SJohn Marino error_at (loc, "arithmetic on pointer to an incomplete type");
3496e4b17023SJohn Marino
3497e4b17023SJohn Marino /* This generates an error if op0 is pointer to incomplete type. */
3498e4b17023SJohn Marino op1 = c_size_in_bytes (target_type);
3499e4b17023SJohn Marino
3500e4b17023SJohn Marino /* Divide by the size, in easiest possible way. */
3501e4b17023SJohn Marino result = fold_build2_loc (loc, EXACT_DIV_EXPR, inttype,
3502e4b17023SJohn Marino op0, convert (inttype, op1));
3503e4b17023SJohn Marino
3504e4b17023SJohn Marino /* Convert to final result type if necessary. */
3505e4b17023SJohn Marino return convert (restype, result);
3506e4b17023SJohn Marino }
3507e4b17023SJohn Marino
3508e4b17023SJohn Marino /* Construct and perhaps optimize a tree representation
3509e4b17023SJohn Marino for a unary operation. CODE, a tree_code, specifies the operation
3510e4b17023SJohn Marino and XARG is the operand.
3511e4b17023SJohn Marino For any CODE other than ADDR_EXPR, FLAG nonzero suppresses
3512e4b17023SJohn Marino the default promotions (such as from short to int).
3513e4b17023SJohn Marino For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
3514e4b17023SJohn Marino allows non-lvalues; this is only used to handle conversion of non-lvalue
3515e4b17023SJohn Marino arrays to pointers in C99.
3516e4b17023SJohn Marino
3517e4b17023SJohn Marino LOCATION is the location of the operator. */
3518e4b17023SJohn Marino
3519e4b17023SJohn Marino tree
build_unary_op(location_t location,enum tree_code code,tree xarg,int flag)3520e4b17023SJohn Marino build_unary_op (location_t location,
3521e4b17023SJohn Marino enum tree_code code, tree xarg, int flag)
3522e4b17023SJohn Marino {
3523e4b17023SJohn Marino /* No default_conversion here. It causes trouble for ADDR_EXPR. */
3524e4b17023SJohn Marino tree arg = xarg;
3525e4b17023SJohn Marino tree argtype = 0;
3526e4b17023SJohn Marino enum tree_code typecode;
3527e4b17023SJohn Marino tree val;
3528e4b17023SJohn Marino tree ret = error_mark_node;
3529e4b17023SJohn Marino tree eptype = NULL_TREE;
3530e4b17023SJohn Marino int noconvert = flag;
3531e4b17023SJohn Marino const char *invalid_op_diag;
3532e4b17023SJohn Marino bool int_operands;
3533e4b17023SJohn Marino
3534e4b17023SJohn Marino int_operands = EXPR_INT_CONST_OPERANDS (xarg);
3535e4b17023SJohn Marino if (int_operands)
3536e4b17023SJohn Marino arg = remove_c_maybe_const_expr (arg);
3537e4b17023SJohn Marino
3538e4b17023SJohn Marino if (code != ADDR_EXPR)
3539e4b17023SJohn Marino arg = require_complete_type (arg);
3540e4b17023SJohn Marino
3541e4b17023SJohn Marino typecode = TREE_CODE (TREE_TYPE (arg));
3542e4b17023SJohn Marino if (typecode == ERROR_MARK)
3543e4b17023SJohn Marino return error_mark_node;
3544e4b17023SJohn Marino if (typecode == ENUMERAL_TYPE || typecode == BOOLEAN_TYPE)
3545e4b17023SJohn Marino typecode = INTEGER_TYPE;
3546e4b17023SJohn Marino
3547e4b17023SJohn Marino if ((invalid_op_diag
3548e4b17023SJohn Marino = targetm.invalid_unary_op (code, TREE_TYPE (xarg))))
3549e4b17023SJohn Marino {
3550e4b17023SJohn Marino error_at (location, invalid_op_diag);
3551e4b17023SJohn Marino return error_mark_node;
3552e4b17023SJohn Marino }
3553e4b17023SJohn Marino
3554e4b17023SJohn Marino if (TREE_CODE (arg) == EXCESS_PRECISION_EXPR)
3555e4b17023SJohn Marino {
3556e4b17023SJohn Marino eptype = TREE_TYPE (arg);
3557e4b17023SJohn Marino arg = TREE_OPERAND (arg, 0);
3558e4b17023SJohn Marino }
3559e4b17023SJohn Marino
3560e4b17023SJohn Marino switch (code)
3561e4b17023SJohn Marino {
3562e4b17023SJohn Marino case CONVERT_EXPR:
3563e4b17023SJohn Marino /* This is used for unary plus, because a CONVERT_EXPR
3564e4b17023SJohn Marino is enough to prevent anybody from looking inside for
3565e4b17023SJohn Marino associativity, but won't generate any code. */
3566e4b17023SJohn Marino if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
3567e4b17023SJohn Marino || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
3568e4b17023SJohn Marino || typecode == VECTOR_TYPE))
3569e4b17023SJohn Marino {
3570e4b17023SJohn Marino error_at (location, "wrong type argument to unary plus");
3571e4b17023SJohn Marino return error_mark_node;
3572e4b17023SJohn Marino }
3573e4b17023SJohn Marino else if (!noconvert)
3574e4b17023SJohn Marino arg = default_conversion (arg);
3575e4b17023SJohn Marino arg = non_lvalue_loc (location, arg);
3576e4b17023SJohn Marino break;
3577e4b17023SJohn Marino
3578e4b17023SJohn Marino case NEGATE_EXPR:
3579e4b17023SJohn Marino if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
3580e4b17023SJohn Marino || typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
3581e4b17023SJohn Marino || typecode == VECTOR_TYPE))
3582e4b17023SJohn Marino {
3583e4b17023SJohn Marino error_at (location, "wrong type argument to unary minus");
3584e4b17023SJohn Marino return error_mark_node;
3585e4b17023SJohn Marino }
3586e4b17023SJohn Marino else if (!noconvert)
3587e4b17023SJohn Marino arg = default_conversion (arg);
3588e4b17023SJohn Marino break;
3589e4b17023SJohn Marino
3590e4b17023SJohn Marino case BIT_NOT_EXPR:
3591e4b17023SJohn Marino /* ~ works on integer types and non float vectors. */
3592e4b17023SJohn Marino if (typecode == INTEGER_TYPE
3593e4b17023SJohn Marino || (typecode == VECTOR_TYPE
3594e4b17023SJohn Marino && !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg))))
3595e4b17023SJohn Marino {
3596e4b17023SJohn Marino if (!noconvert)
3597e4b17023SJohn Marino arg = default_conversion (arg);
3598e4b17023SJohn Marino }
3599e4b17023SJohn Marino else if (typecode == COMPLEX_TYPE)
3600e4b17023SJohn Marino {
3601e4b17023SJohn Marino code = CONJ_EXPR;
3602e4b17023SJohn Marino pedwarn (location, OPT_pedantic,
3603e4b17023SJohn Marino "ISO C does not support %<~%> for complex conjugation");
3604e4b17023SJohn Marino if (!noconvert)
3605e4b17023SJohn Marino arg = default_conversion (arg);
3606e4b17023SJohn Marino }
3607e4b17023SJohn Marino else
3608e4b17023SJohn Marino {
3609e4b17023SJohn Marino error_at (location, "wrong type argument to bit-complement");
3610e4b17023SJohn Marino return error_mark_node;
3611e4b17023SJohn Marino }
3612e4b17023SJohn Marino break;
3613e4b17023SJohn Marino
3614e4b17023SJohn Marino case ABS_EXPR:
3615e4b17023SJohn Marino if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
3616e4b17023SJohn Marino {
3617e4b17023SJohn Marino error_at (location, "wrong type argument to abs");
3618e4b17023SJohn Marino return error_mark_node;
3619e4b17023SJohn Marino }
3620e4b17023SJohn Marino else if (!noconvert)
3621e4b17023SJohn Marino arg = default_conversion (arg);
3622e4b17023SJohn Marino break;
3623e4b17023SJohn Marino
3624e4b17023SJohn Marino case CONJ_EXPR:
3625e4b17023SJohn Marino /* Conjugating a real value is a no-op, but allow it anyway. */
3626e4b17023SJohn Marino if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
3627e4b17023SJohn Marino || typecode == COMPLEX_TYPE))
3628e4b17023SJohn Marino {
3629e4b17023SJohn Marino error_at (location, "wrong type argument to conjugation");
3630e4b17023SJohn Marino return error_mark_node;
3631e4b17023SJohn Marino }
3632e4b17023SJohn Marino else if (!noconvert)
3633e4b17023SJohn Marino arg = default_conversion (arg);
3634e4b17023SJohn Marino break;
3635e4b17023SJohn Marino
3636e4b17023SJohn Marino case TRUTH_NOT_EXPR:
3637e4b17023SJohn Marino if (typecode != INTEGER_TYPE && typecode != FIXED_POINT_TYPE
3638e4b17023SJohn Marino && typecode != REAL_TYPE && typecode != POINTER_TYPE
3639e4b17023SJohn Marino && typecode != COMPLEX_TYPE)
3640e4b17023SJohn Marino {
3641e4b17023SJohn Marino error_at (location,
3642e4b17023SJohn Marino "wrong type argument to unary exclamation mark");
3643e4b17023SJohn Marino return error_mark_node;
3644e4b17023SJohn Marino }
36455ce9237cSJohn Marino if (int_operands)
36465ce9237cSJohn Marino {
36475ce9237cSJohn Marino arg = c_objc_common_truthvalue_conversion (location, xarg);
36485ce9237cSJohn Marino arg = remove_c_maybe_const_expr (arg);
36495ce9237cSJohn Marino }
36505ce9237cSJohn Marino else
3651e4b17023SJohn Marino arg = c_objc_common_truthvalue_conversion (location, arg);
3652e4b17023SJohn Marino ret = invert_truthvalue_loc (location, arg);
3653e4b17023SJohn Marino /* If the TRUTH_NOT_EXPR has been folded, reset the location. */
3654e4b17023SJohn Marino if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret))
3655e4b17023SJohn Marino location = EXPR_LOCATION (ret);
3656e4b17023SJohn Marino goto return_build_unary_op;
3657e4b17023SJohn Marino
3658e4b17023SJohn Marino case REALPART_EXPR:
3659e4b17023SJohn Marino case IMAGPART_EXPR:
3660e4b17023SJohn Marino ret = build_real_imag_expr (location, code, arg);
3661e4b17023SJohn Marino if (ret == error_mark_node)
3662e4b17023SJohn Marino return error_mark_node;
3663e4b17023SJohn Marino if (eptype && TREE_CODE (eptype) == COMPLEX_TYPE)
3664e4b17023SJohn Marino eptype = TREE_TYPE (eptype);
3665e4b17023SJohn Marino goto return_build_unary_op;
3666e4b17023SJohn Marino
3667e4b17023SJohn Marino case PREINCREMENT_EXPR:
3668e4b17023SJohn Marino case POSTINCREMENT_EXPR:
3669e4b17023SJohn Marino case PREDECREMENT_EXPR:
3670e4b17023SJohn Marino case POSTDECREMENT_EXPR:
3671e4b17023SJohn Marino
3672e4b17023SJohn Marino if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR)
3673e4b17023SJohn Marino {
3674e4b17023SJohn Marino tree inner = build_unary_op (location, code,
3675e4b17023SJohn Marino C_MAYBE_CONST_EXPR_EXPR (arg), flag);
3676e4b17023SJohn Marino if (inner == error_mark_node)
3677e4b17023SJohn Marino return error_mark_node;
3678e4b17023SJohn Marino ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner),
3679e4b17023SJohn Marino C_MAYBE_CONST_EXPR_PRE (arg), inner);
3680e4b17023SJohn Marino gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg));
3681e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (ret) = 1;
3682e4b17023SJohn Marino goto return_build_unary_op;
3683e4b17023SJohn Marino }
3684e4b17023SJohn Marino
3685e4b17023SJohn Marino /* Complain about anything that is not a true lvalue. In
3686e4b17023SJohn Marino Objective-C, skip this check for property_refs. */
3687e4b17023SJohn Marino if (!objc_is_property_ref (arg)
3688e4b17023SJohn Marino && !lvalue_or_else (location,
3689e4b17023SJohn Marino arg, ((code == PREINCREMENT_EXPR
3690e4b17023SJohn Marino || code == POSTINCREMENT_EXPR)
3691e4b17023SJohn Marino ? lv_increment
3692e4b17023SJohn Marino : lv_decrement)))
3693e4b17023SJohn Marino return error_mark_node;
3694e4b17023SJohn Marino
3695e4b17023SJohn Marino if (warn_cxx_compat && TREE_CODE (TREE_TYPE (arg)) == ENUMERAL_TYPE)
3696e4b17023SJohn Marino {
3697e4b17023SJohn Marino if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3698e4b17023SJohn Marino warning_at (location, OPT_Wc___compat,
3699e4b17023SJohn Marino "increment of enumeration value is invalid in C++");
3700e4b17023SJohn Marino else
3701e4b17023SJohn Marino warning_at (location, OPT_Wc___compat,
3702e4b17023SJohn Marino "decrement of enumeration value is invalid in C++");
3703e4b17023SJohn Marino }
3704e4b17023SJohn Marino
3705e4b17023SJohn Marino /* Ensure the argument is fully folded inside any SAVE_EXPR. */
3706e4b17023SJohn Marino arg = c_fully_fold (arg, false, NULL);
3707e4b17023SJohn Marino
3708e4b17023SJohn Marino /* Increment or decrement the real part of the value,
3709e4b17023SJohn Marino and don't change the imaginary part. */
3710e4b17023SJohn Marino if (typecode == COMPLEX_TYPE)
3711e4b17023SJohn Marino {
3712e4b17023SJohn Marino tree real, imag;
3713e4b17023SJohn Marino
3714e4b17023SJohn Marino pedwarn (location, OPT_pedantic,
3715e4b17023SJohn Marino "ISO C does not support %<++%> and %<--%> on complex types");
3716e4b17023SJohn Marino
3717e4b17023SJohn Marino arg = stabilize_reference (arg);
3718e4b17023SJohn Marino real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1);
3719e4b17023SJohn Marino imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1);
3720e4b17023SJohn Marino real = build_unary_op (EXPR_LOCATION (arg), code, real, 1);
3721e4b17023SJohn Marino if (real == error_mark_node || imag == error_mark_node)
3722e4b17023SJohn Marino return error_mark_node;
3723e4b17023SJohn Marino ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg),
3724e4b17023SJohn Marino real, imag);
3725e4b17023SJohn Marino goto return_build_unary_op;
3726e4b17023SJohn Marino }
3727e4b17023SJohn Marino
3728e4b17023SJohn Marino /* Report invalid types. */
3729e4b17023SJohn Marino
3730e4b17023SJohn Marino if (typecode != POINTER_TYPE && typecode != FIXED_POINT_TYPE
3731e4b17023SJohn Marino && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
3732e4b17023SJohn Marino {
3733e4b17023SJohn Marino if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3734e4b17023SJohn Marino error_at (location, "wrong type argument to increment");
3735e4b17023SJohn Marino else
3736e4b17023SJohn Marino error_at (location, "wrong type argument to decrement");
3737e4b17023SJohn Marino
3738e4b17023SJohn Marino return error_mark_node;
3739e4b17023SJohn Marino }
3740e4b17023SJohn Marino
3741e4b17023SJohn Marino {
3742e4b17023SJohn Marino tree inc;
3743e4b17023SJohn Marino
3744e4b17023SJohn Marino argtype = TREE_TYPE (arg);
3745e4b17023SJohn Marino
3746e4b17023SJohn Marino /* Compute the increment. */
3747e4b17023SJohn Marino
3748e4b17023SJohn Marino if (typecode == POINTER_TYPE)
3749e4b17023SJohn Marino {
3750e4b17023SJohn Marino /* If pointer target is an undefined struct,
3751e4b17023SJohn Marino we just cannot know how to do the arithmetic. */
3752e4b17023SJohn Marino if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (argtype)))
3753e4b17023SJohn Marino {
3754e4b17023SJohn Marino if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3755e4b17023SJohn Marino error_at (location,
3756e4b17023SJohn Marino "increment of pointer to unknown structure");
3757e4b17023SJohn Marino else
3758e4b17023SJohn Marino error_at (location,
3759e4b17023SJohn Marino "decrement of pointer to unknown structure");
3760e4b17023SJohn Marino }
3761e4b17023SJohn Marino else if (TREE_CODE (TREE_TYPE (argtype)) == FUNCTION_TYPE
3762e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (argtype)) == VOID_TYPE)
3763e4b17023SJohn Marino {
3764e4b17023SJohn Marino if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3765e4b17023SJohn Marino pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
3766e4b17023SJohn Marino "wrong type argument to increment");
3767e4b17023SJohn Marino else
3768e4b17023SJohn Marino pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
3769e4b17023SJohn Marino "wrong type argument to decrement");
3770e4b17023SJohn Marino }
3771e4b17023SJohn Marino
3772e4b17023SJohn Marino inc = c_size_in_bytes (TREE_TYPE (argtype));
3773e4b17023SJohn Marino inc = convert_to_ptrofftype_loc (location, inc);
3774e4b17023SJohn Marino }
3775e4b17023SJohn Marino else if (FRACT_MODE_P (TYPE_MODE (argtype)))
3776e4b17023SJohn Marino {
3777e4b17023SJohn Marino /* For signed fract types, we invert ++ to -- or
3778e4b17023SJohn Marino -- to ++, and change inc from 1 to -1, because
3779e4b17023SJohn Marino it is not possible to represent 1 in signed fract constants.
3780e4b17023SJohn Marino For unsigned fract types, the result always overflows and
3781e4b17023SJohn Marino we get an undefined (original) or the maximum value. */
3782e4b17023SJohn Marino if (code == PREINCREMENT_EXPR)
3783e4b17023SJohn Marino code = PREDECREMENT_EXPR;
3784e4b17023SJohn Marino else if (code == PREDECREMENT_EXPR)
3785e4b17023SJohn Marino code = PREINCREMENT_EXPR;
3786e4b17023SJohn Marino else if (code == POSTINCREMENT_EXPR)
3787e4b17023SJohn Marino code = POSTDECREMENT_EXPR;
3788e4b17023SJohn Marino else /* code == POSTDECREMENT_EXPR */
3789e4b17023SJohn Marino code = POSTINCREMENT_EXPR;
3790e4b17023SJohn Marino
3791e4b17023SJohn Marino inc = integer_minus_one_node;
3792e4b17023SJohn Marino inc = convert (argtype, inc);
3793e4b17023SJohn Marino }
3794e4b17023SJohn Marino else
3795e4b17023SJohn Marino {
3796e4b17023SJohn Marino inc = integer_one_node;
3797e4b17023SJohn Marino inc = convert (argtype, inc);
3798e4b17023SJohn Marino }
3799e4b17023SJohn Marino
3800e4b17023SJohn Marino /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
3801e4b17023SJohn Marino need to ask Objective-C to build the increment or decrement
3802e4b17023SJohn Marino expression for it. */
3803e4b17023SJohn Marino if (objc_is_property_ref (arg))
3804e4b17023SJohn Marino return objc_build_incr_expr_for_property_ref (location, code,
3805e4b17023SJohn Marino arg, inc);
3806e4b17023SJohn Marino
3807e4b17023SJohn Marino /* Report a read-only lvalue. */
3808e4b17023SJohn Marino if (TYPE_READONLY (argtype))
3809e4b17023SJohn Marino {
3810e4b17023SJohn Marino readonly_error (arg,
3811e4b17023SJohn Marino ((code == PREINCREMENT_EXPR
3812e4b17023SJohn Marino || code == POSTINCREMENT_EXPR)
3813e4b17023SJohn Marino ? lv_increment : lv_decrement));
3814e4b17023SJohn Marino return error_mark_node;
3815e4b17023SJohn Marino }
3816e4b17023SJohn Marino else if (TREE_READONLY (arg))
3817e4b17023SJohn Marino readonly_warning (arg,
3818e4b17023SJohn Marino ((code == PREINCREMENT_EXPR
3819e4b17023SJohn Marino || code == POSTINCREMENT_EXPR)
3820e4b17023SJohn Marino ? lv_increment : lv_decrement));
3821e4b17023SJohn Marino
3822e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
3823e4b17023SJohn Marino val = boolean_increment (code, arg);
3824e4b17023SJohn Marino else
3825e4b17023SJohn Marino val = build2 (code, TREE_TYPE (arg), arg, inc);
3826e4b17023SJohn Marino TREE_SIDE_EFFECTS (val) = 1;
3827e4b17023SJohn Marino if (TREE_CODE (val) != code)
3828e4b17023SJohn Marino TREE_NO_WARNING (val) = 1;
3829e4b17023SJohn Marino ret = val;
3830e4b17023SJohn Marino goto return_build_unary_op;
3831e4b17023SJohn Marino }
3832e4b17023SJohn Marino
3833e4b17023SJohn Marino case ADDR_EXPR:
3834e4b17023SJohn Marino /* Note that this operation never does default_conversion. */
3835e4b17023SJohn Marino
3836e4b17023SJohn Marino /* The operand of unary '&' must be an lvalue (which excludes
3837e4b17023SJohn Marino expressions of type void), or, in C99, the result of a [] or
3838e4b17023SJohn Marino unary '*' operator. */
3839e4b17023SJohn Marino if (VOID_TYPE_P (TREE_TYPE (arg))
3840e4b17023SJohn Marino && TYPE_QUALS (TREE_TYPE (arg)) == TYPE_UNQUALIFIED
3841e4b17023SJohn Marino && (TREE_CODE (arg) != INDIRECT_REF
3842e4b17023SJohn Marino || !flag_isoc99))
3843e4b17023SJohn Marino pedwarn (location, 0, "taking address of expression of type %<void%>");
3844e4b17023SJohn Marino
3845e4b17023SJohn Marino /* Let &* cancel out to simplify resulting code. */
3846e4b17023SJohn Marino if (TREE_CODE (arg) == INDIRECT_REF)
3847e4b17023SJohn Marino {
3848e4b17023SJohn Marino /* Don't let this be an lvalue. */
3849e4b17023SJohn Marino if (lvalue_p (TREE_OPERAND (arg, 0)))
3850e4b17023SJohn Marino return non_lvalue_loc (location, TREE_OPERAND (arg, 0));
3851e4b17023SJohn Marino ret = TREE_OPERAND (arg, 0);
3852e4b17023SJohn Marino goto return_build_unary_op;
3853e4b17023SJohn Marino }
3854e4b17023SJohn Marino
3855e4b17023SJohn Marino /* For &x[y], return x+y */
3856e4b17023SJohn Marino if (TREE_CODE (arg) == ARRAY_REF)
3857e4b17023SJohn Marino {
3858e4b17023SJohn Marino tree op0 = TREE_OPERAND (arg, 0);
3859e4b17023SJohn Marino if (!c_mark_addressable (op0))
3860e4b17023SJohn Marino return error_mark_node;
3861e4b17023SJohn Marino }
3862e4b17023SJohn Marino
3863e4b17023SJohn Marino /* Anything not already handled and not a true memory reference
3864e4b17023SJohn Marino or a non-lvalue array is an error. */
3865e4b17023SJohn Marino else if (typecode != FUNCTION_TYPE && !flag
3866e4b17023SJohn Marino && !lvalue_or_else (location, arg, lv_addressof))
3867e4b17023SJohn Marino return error_mark_node;
3868e4b17023SJohn Marino
3869e4b17023SJohn Marino /* Move address operations inside C_MAYBE_CONST_EXPR to simplify
3870e4b17023SJohn Marino folding later. */
3871e4b17023SJohn Marino if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR)
3872e4b17023SJohn Marino {
3873e4b17023SJohn Marino tree inner = build_unary_op (location, code,
3874e4b17023SJohn Marino C_MAYBE_CONST_EXPR_EXPR (arg), flag);
3875e4b17023SJohn Marino ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner),
3876e4b17023SJohn Marino C_MAYBE_CONST_EXPR_PRE (arg), inner);
3877e4b17023SJohn Marino gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg));
3878e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (ret)
3879e4b17023SJohn Marino = C_MAYBE_CONST_EXPR_NON_CONST (arg);
3880e4b17023SJohn Marino goto return_build_unary_op;
3881e4b17023SJohn Marino }
3882e4b17023SJohn Marino
3883e4b17023SJohn Marino /* Ordinary case; arg is a COMPONENT_REF or a decl. */
3884e4b17023SJohn Marino argtype = TREE_TYPE (arg);
3885e4b17023SJohn Marino
3886e4b17023SJohn Marino /* If the lvalue is const or volatile, merge that into the type
3887e4b17023SJohn Marino to which the address will point. This is only needed
3888e4b17023SJohn Marino for function types. */
3889e4b17023SJohn Marino if ((DECL_P (arg) || REFERENCE_CLASS_P (arg))
3890e4b17023SJohn Marino && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
3891e4b17023SJohn Marino && TREE_CODE (argtype) == FUNCTION_TYPE)
3892e4b17023SJohn Marino {
3893e4b17023SJohn Marino int orig_quals = TYPE_QUALS (strip_array_types (argtype));
3894e4b17023SJohn Marino int quals = orig_quals;
3895e4b17023SJohn Marino
3896e4b17023SJohn Marino if (TREE_READONLY (arg))
3897e4b17023SJohn Marino quals |= TYPE_QUAL_CONST;
3898e4b17023SJohn Marino if (TREE_THIS_VOLATILE (arg))
3899e4b17023SJohn Marino quals |= TYPE_QUAL_VOLATILE;
3900e4b17023SJohn Marino
3901e4b17023SJohn Marino argtype = c_build_qualified_type (argtype, quals);
3902e4b17023SJohn Marino }
3903e4b17023SJohn Marino
3904e4b17023SJohn Marino if (!c_mark_addressable (arg))
3905e4b17023SJohn Marino return error_mark_node;
3906e4b17023SJohn Marino
3907e4b17023SJohn Marino gcc_assert (TREE_CODE (arg) != COMPONENT_REF
3908e4b17023SJohn Marino || !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)));
3909e4b17023SJohn Marino
3910e4b17023SJohn Marino argtype = build_pointer_type (argtype);
3911e4b17023SJohn Marino
3912e4b17023SJohn Marino /* ??? Cope with user tricks that amount to offsetof. Delete this
3913e4b17023SJohn Marino when we have proper support for integer constant expressions. */
3914e4b17023SJohn Marino val = get_base_address (arg);
3915e4b17023SJohn Marino if (val && TREE_CODE (val) == INDIRECT_REF
3916e4b17023SJohn Marino && TREE_CONSTANT (TREE_OPERAND (val, 0)))
3917e4b17023SJohn Marino {
3918e4b17023SJohn Marino ret = fold_convert_loc (location, argtype, fold_offsetof_1 (arg));
3919e4b17023SJohn Marino goto return_build_unary_op;
3920e4b17023SJohn Marino }
3921e4b17023SJohn Marino
3922e4b17023SJohn Marino val = build1 (ADDR_EXPR, argtype, arg);
3923e4b17023SJohn Marino
3924e4b17023SJohn Marino ret = val;
3925e4b17023SJohn Marino goto return_build_unary_op;
3926e4b17023SJohn Marino
3927e4b17023SJohn Marino default:
3928e4b17023SJohn Marino gcc_unreachable ();
3929e4b17023SJohn Marino }
3930e4b17023SJohn Marino
3931e4b17023SJohn Marino if (argtype == 0)
3932e4b17023SJohn Marino argtype = TREE_TYPE (arg);
3933e4b17023SJohn Marino if (TREE_CODE (arg) == INTEGER_CST)
3934e4b17023SJohn Marino ret = (require_constant_value
3935e4b17023SJohn Marino ? fold_build1_initializer_loc (location, code, argtype, arg)
3936e4b17023SJohn Marino : fold_build1_loc (location, code, argtype, arg));
3937e4b17023SJohn Marino else
3938e4b17023SJohn Marino ret = build1 (code, argtype, arg);
3939e4b17023SJohn Marino return_build_unary_op:
3940e4b17023SJohn Marino gcc_assert (ret != error_mark_node);
3941e4b17023SJohn Marino if (TREE_CODE (ret) == INTEGER_CST && !TREE_OVERFLOW (ret)
3942e4b17023SJohn Marino && !(TREE_CODE (xarg) == INTEGER_CST && !TREE_OVERFLOW (xarg)))
3943e4b17023SJohn Marino ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
3944e4b17023SJohn Marino else if (TREE_CODE (ret) != INTEGER_CST && int_operands)
3945e4b17023SJohn Marino ret = note_integer_operands (ret);
3946e4b17023SJohn Marino if (eptype)
3947e4b17023SJohn Marino ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
3948e4b17023SJohn Marino protected_set_expr_location (ret, location);
3949e4b17023SJohn Marino return ret;
3950e4b17023SJohn Marino }
3951e4b17023SJohn Marino
3952e4b17023SJohn Marino /* Return nonzero if REF is an lvalue valid for this language.
3953e4b17023SJohn Marino Lvalues can be assigned, unless their type has TYPE_READONLY.
3954e4b17023SJohn Marino Lvalues can have their address taken, unless they have C_DECL_REGISTER. */
3955e4b17023SJohn Marino
3956e4b17023SJohn Marino bool
lvalue_p(const_tree ref)3957e4b17023SJohn Marino lvalue_p (const_tree ref)
3958e4b17023SJohn Marino {
3959e4b17023SJohn Marino const enum tree_code code = TREE_CODE (ref);
3960e4b17023SJohn Marino
3961e4b17023SJohn Marino switch (code)
3962e4b17023SJohn Marino {
3963e4b17023SJohn Marino case REALPART_EXPR:
3964e4b17023SJohn Marino case IMAGPART_EXPR:
3965e4b17023SJohn Marino case COMPONENT_REF:
3966e4b17023SJohn Marino return lvalue_p (TREE_OPERAND (ref, 0));
3967e4b17023SJohn Marino
3968e4b17023SJohn Marino case C_MAYBE_CONST_EXPR:
3969e4b17023SJohn Marino return lvalue_p (TREE_OPERAND (ref, 1));
3970e4b17023SJohn Marino
3971e4b17023SJohn Marino case COMPOUND_LITERAL_EXPR:
3972e4b17023SJohn Marino case STRING_CST:
3973e4b17023SJohn Marino return 1;
3974e4b17023SJohn Marino
3975e4b17023SJohn Marino case INDIRECT_REF:
3976e4b17023SJohn Marino case ARRAY_REF:
3977e4b17023SJohn Marino case VAR_DECL:
3978e4b17023SJohn Marino case PARM_DECL:
3979e4b17023SJohn Marino case RESULT_DECL:
3980e4b17023SJohn Marino case ERROR_MARK:
3981e4b17023SJohn Marino return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
3982e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
3983e4b17023SJohn Marino
3984e4b17023SJohn Marino case BIND_EXPR:
3985e4b17023SJohn Marino return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
3986e4b17023SJohn Marino
3987e4b17023SJohn Marino default:
3988e4b17023SJohn Marino return 0;
3989e4b17023SJohn Marino }
3990e4b17023SJohn Marino }
3991e4b17023SJohn Marino
3992e4b17023SJohn Marino /* Give a warning for storing in something that is read-only in GCC
3993e4b17023SJohn Marino terms but not const in ISO C terms. */
3994e4b17023SJohn Marino
3995e4b17023SJohn Marino static void
readonly_warning(tree arg,enum lvalue_use use)3996e4b17023SJohn Marino readonly_warning (tree arg, enum lvalue_use use)
3997e4b17023SJohn Marino {
3998e4b17023SJohn Marino switch (use)
3999e4b17023SJohn Marino {
4000e4b17023SJohn Marino case lv_assign:
4001e4b17023SJohn Marino warning (0, "assignment of read-only location %qE", arg);
4002e4b17023SJohn Marino break;
4003e4b17023SJohn Marino case lv_increment:
4004e4b17023SJohn Marino warning (0, "increment of read-only location %qE", arg);
4005e4b17023SJohn Marino break;
4006e4b17023SJohn Marino case lv_decrement:
4007e4b17023SJohn Marino warning (0, "decrement of read-only location %qE", arg);
4008e4b17023SJohn Marino break;
4009e4b17023SJohn Marino default:
4010e4b17023SJohn Marino gcc_unreachable ();
4011e4b17023SJohn Marino }
4012e4b17023SJohn Marino return;
4013e4b17023SJohn Marino }
4014e4b17023SJohn Marino
4015e4b17023SJohn Marino
4016e4b17023SJohn Marino /* Return nonzero if REF is an lvalue valid for this language;
4017e4b17023SJohn Marino otherwise, print an error message and return zero. USE says
4018e4b17023SJohn Marino how the lvalue is being used and so selects the error message.
4019e4b17023SJohn Marino LOCATION is the location at which any error should be reported. */
4020e4b17023SJohn Marino
4021e4b17023SJohn Marino static int
lvalue_or_else(location_t loc,const_tree ref,enum lvalue_use use)4022e4b17023SJohn Marino lvalue_or_else (location_t loc, const_tree ref, enum lvalue_use use)
4023e4b17023SJohn Marino {
4024e4b17023SJohn Marino int win = lvalue_p (ref);
4025e4b17023SJohn Marino
4026e4b17023SJohn Marino if (!win)
4027e4b17023SJohn Marino lvalue_error (loc, use);
4028e4b17023SJohn Marino
4029e4b17023SJohn Marino return win;
4030e4b17023SJohn Marino }
4031e4b17023SJohn Marino
4032e4b17023SJohn Marino /* Mark EXP saying that we need to be able to take the
4033e4b17023SJohn Marino address of it; it should not be allocated in a register.
4034e4b17023SJohn Marino Returns true if successful. */
4035e4b17023SJohn Marino
4036e4b17023SJohn Marino bool
c_mark_addressable(tree exp)4037e4b17023SJohn Marino c_mark_addressable (tree exp)
4038e4b17023SJohn Marino {
4039e4b17023SJohn Marino tree x = exp;
4040e4b17023SJohn Marino
4041e4b17023SJohn Marino while (1)
4042e4b17023SJohn Marino switch (TREE_CODE (x))
4043e4b17023SJohn Marino {
4044e4b17023SJohn Marino case COMPONENT_REF:
4045e4b17023SJohn Marino if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
4046e4b17023SJohn Marino {
4047e4b17023SJohn Marino error
4048e4b17023SJohn Marino ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1));
4049e4b17023SJohn Marino return false;
4050e4b17023SJohn Marino }
4051e4b17023SJohn Marino
4052e4b17023SJohn Marino /* ... fall through ... */
4053e4b17023SJohn Marino
4054e4b17023SJohn Marino case ADDR_EXPR:
4055e4b17023SJohn Marino case ARRAY_REF:
4056e4b17023SJohn Marino case REALPART_EXPR:
4057e4b17023SJohn Marino case IMAGPART_EXPR:
4058e4b17023SJohn Marino x = TREE_OPERAND (x, 0);
4059e4b17023SJohn Marino break;
4060e4b17023SJohn Marino
4061e4b17023SJohn Marino case COMPOUND_LITERAL_EXPR:
4062e4b17023SJohn Marino case CONSTRUCTOR:
4063e4b17023SJohn Marino TREE_ADDRESSABLE (x) = 1;
4064e4b17023SJohn Marino return true;
4065e4b17023SJohn Marino
4066e4b17023SJohn Marino case VAR_DECL:
4067e4b17023SJohn Marino case CONST_DECL:
4068e4b17023SJohn Marino case PARM_DECL:
4069e4b17023SJohn Marino case RESULT_DECL:
4070e4b17023SJohn Marino if (C_DECL_REGISTER (x)
4071e4b17023SJohn Marino && DECL_NONLOCAL (x))
4072e4b17023SJohn Marino {
4073e4b17023SJohn Marino if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
4074e4b17023SJohn Marino {
4075e4b17023SJohn Marino error
4076e4b17023SJohn Marino ("global register variable %qD used in nested function", x);
4077e4b17023SJohn Marino return false;
4078e4b17023SJohn Marino }
4079e4b17023SJohn Marino pedwarn (input_location, 0, "register variable %qD used in nested function", x);
4080e4b17023SJohn Marino }
4081e4b17023SJohn Marino else if (C_DECL_REGISTER (x))
4082e4b17023SJohn Marino {
4083e4b17023SJohn Marino if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
4084e4b17023SJohn Marino error ("address of global register variable %qD requested", x);
4085e4b17023SJohn Marino else
4086e4b17023SJohn Marino error ("address of register variable %qD requested", x);
4087e4b17023SJohn Marino return false;
4088e4b17023SJohn Marino }
4089e4b17023SJohn Marino
4090e4b17023SJohn Marino /* drops in */
4091e4b17023SJohn Marino case FUNCTION_DECL:
4092e4b17023SJohn Marino TREE_ADDRESSABLE (x) = 1;
4093e4b17023SJohn Marino /* drops out */
4094e4b17023SJohn Marino default:
4095e4b17023SJohn Marino return true;
4096e4b17023SJohn Marino }
4097e4b17023SJohn Marino }
4098e4b17023SJohn Marino
4099e4b17023SJohn Marino /* Convert EXPR to TYPE, warning about conversion problems with
4100e4b17023SJohn Marino constants. SEMANTIC_TYPE is the type this conversion would use
4101e4b17023SJohn Marino without excess precision. If SEMANTIC_TYPE is NULL, this function
4102e4b17023SJohn Marino is equivalent to convert_and_check. This function is a wrapper that
4103e4b17023SJohn Marino handles conversions that may be different than
4104e4b17023SJohn Marino the usual ones because of excess precision. */
4105e4b17023SJohn Marino
4106e4b17023SJohn Marino static tree
ep_convert_and_check(tree type,tree expr,tree semantic_type)4107e4b17023SJohn Marino ep_convert_and_check (tree type, tree expr, tree semantic_type)
4108e4b17023SJohn Marino {
4109e4b17023SJohn Marino if (TREE_TYPE (expr) == type)
4110e4b17023SJohn Marino return expr;
4111e4b17023SJohn Marino
4112e4b17023SJohn Marino if (!semantic_type)
4113e4b17023SJohn Marino return convert_and_check (type, expr);
4114e4b17023SJohn Marino
4115e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
4116e4b17023SJohn Marino && TREE_TYPE (expr) != semantic_type)
4117e4b17023SJohn Marino {
4118e4b17023SJohn Marino /* For integers, we need to check the real conversion, not
4119e4b17023SJohn Marino the conversion to the excess precision type. */
4120e4b17023SJohn Marino expr = convert_and_check (semantic_type, expr);
4121e4b17023SJohn Marino }
4122e4b17023SJohn Marino /* Result type is the excess precision type, which should be
4123e4b17023SJohn Marino large enough, so do not check. */
4124e4b17023SJohn Marino return convert (type, expr);
4125e4b17023SJohn Marino }
4126e4b17023SJohn Marino
4127e4b17023SJohn Marino /* Build and return a conditional expression IFEXP ? OP1 : OP2. If
4128e4b17023SJohn Marino IFEXP_BCP then the condition is a call to __builtin_constant_p, and
4129e4b17023SJohn Marino if folded to an integer constant then the unselected half may
4130e4b17023SJohn Marino contain arbitrary operations not normally permitted in constant
4131e4b17023SJohn Marino expressions. Set the location of the expression to LOC. */
4132e4b17023SJohn Marino
4133e4b17023SJohn Marino tree
build_conditional_expr(location_t colon_loc,tree ifexp,bool ifexp_bcp,tree op1,tree op1_original_type,tree op2,tree op2_original_type)4134e4b17023SJohn Marino build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
4135e4b17023SJohn Marino tree op1, tree op1_original_type, tree op2,
4136e4b17023SJohn Marino tree op2_original_type)
4137e4b17023SJohn Marino {
4138e4b17023SJohn Marino tree type1;
4139e4b17023SJohn Marino tree type2;
4140e4b17023SJohn Marino enum tree_code code1;
4141e4b17023SJohn Marino enum tree_code code2;
4142e4b17023SJohn Marino tree result_type = NULL;
4143e4b17023SJohn Marino tree semantic_result_type = NULL;
4144e4b17023SJohn Marino tree orig_op1 = op1, orig_op2 = op2;
4145e4b17023SJohn Marino bool int_const, op1_int_operands, op2_int_operands, int_operands;
4146e4b17023SJohn Marino bool ifexp_int_operands;
4147e4b17023SJohn Marino tree ret;
4148e4b17023SJohn Marino
4149e4b17023SJohn Marino op1_int_operands = EXPR_INT_CONST_OPERANDS (orig_op1);
4150e4b17023SJohn Marino if (op1_int_operands)
4151e4b17023SJohn Marino op1 = remove_c_maybe_const_expr (op1);
4152e4b17023SJohn Marino op2_int_operands = EXPR_INT_CONST_OPERANDS (orig_op2);
4153e4b17023SJohn Marino if (op2_int_operands)
4154e4b17023SJohn Marino op2 = remove_c_maybe_const_expr (op2);
4155e4b17023SJohn Marino ifexp_int_operands = EXPR_INT_CONST_OPERANDS (ifexp);
4156e4b17023SJohn Marino if (ifexp_int_operands)
4157e4b17023SJohn Marino ifexp = remove_c_maybe_const_expr (ifexp);
4158e4b17023SJohn Marino
4159e4b17023SJohn Marino /* Promote both alternatives. */
4160e4b17023SJohn Marino
4161e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
4162e4b17023SJohn Marino op1 = default_conversion (op1);
4163e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
4164e4b17023SJohn Marino op2 = default_conversion (op2);
4165e4b17023SJohn Marino
4166e4b17023SJohn Marino if (TREE_CODE (ifexp) == ERROR_MARK
4167e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
4168e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
4169e4b17023SJohn Marino return error_mark_node;
4170e4b17023SJohn Marino
4171e4b17023SJohn Marino type1 = TREE_TYPE (op1);
4172e4b17023SJohn Marino code1 = TREE_CODE (type1);
4173e4b17023SJohn Marino type2 = TREE_TYPE (op2);
4174e4b17023SJohn Marino code2 = TREE_CODE (type2);
4175e4b17023SJohn Marino
4176e4b17023SJohn Marino /* C90 does not permit non-lvalue arrays in conditional expressions.
4177e4b17023SJohn Marino In C99 they will be pointers by now. */
4178e4b17023SJohn Marino if (code1 == ARRAY_TYPE || code2 == ARRAY_TYPE)
4179e4b17023SJohn Marino {
4180e4b17023SJohn Marino error_at (colon_loc, "non-lvalue array in conditional expression");
4181e4b17023SJohn Marino return error_mark_node;
4182e4b17023SJohn Marino }
4183e4b17023SJohn Marino
4184e4b17023SJohn Marino if ((TREE_CODE (op1) == EXCESS_PRECISION_EXPR
4185e4b17023SJohn Marino || TREE_CODE (op2) == EXCESS_PRECISION_EXPR)
4186e4b17023SJohn Marino && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
4187e4b17023SJohn Marino || code1 == COMPLEX_TYPE)
4188e4b17023SJohn Marino && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
4189e4b17023SJohn Marino || code2 == COMPLEX_TYPE))
4190e4b17023SJohn Marino {
4191e4b17023SJohn Marino semantic_result_type = c_common_type (type1, type2);
4192e4b17023SJohn Marino if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
4193e4b17023SJohn Marino {
4194e4b17023SJohn Marino op1 = TREE_OPERAND (op1, 0);
4195e4b17023SJohn Marino type1 = TREE_TYPE (op1);
4196e4b17023SJohn Marino gcc_assert (TREE_CODE (type1) == code1);
4197e4b17023SJohn Marino }
4198e4b17023SJohn Marino if (TREE_CODE (op2) == EXCESS_PRECISION_EXPR)
4199e4b17023SJohn Marino {
4200e4b17023SJohn Marino op2 = TREE_OPERAND (op2, 0);
4201e4b17023SJohn Marino type2 = TREE_TYPE (op2);
4202e4b17023SJohn Marino gcc_assert (TREE_CODE (type2) == code2);
4203e4b17023SJohn Marino }
4204e4b17023SJohn Marino }
4205e4b17023SJohn Marino
4206e4b17023SJohn Marino if (warn_cxx_compat)
4207e4b17023SJohn Marino {
4208e4b17023SJohn Marino tree t1 = op1_original_type ? op1_original_type : TREE_TYPE (orig_op1);
4209e4b17023SJohn Marino tree t2 = op2_original_type ? op2_original_type : TREE_TYPE (orig_op2);
4210e4b17023SJohn Marino
4211e4b17023SJohn Marino if (TREE_CODE (t1) == ENUMERAL_TYPE
4212e4b17023SJohn Marino && TREE_CODE (t2) == ENUMERAL_TYPE
4213e4b17023SJohn Marino && TYPE_MAIN_VARIANT (t1) != TYPE_MAIN_VARIANT (t2))
4214e4b17023SJohn Marino warning_at (colon_loc, OPT_Wc___compat,
4215e4b17023SJohn Marino ("different enum types in conditional is "
4216e4b17023SJohn Marino "invalid in C++: %qT vs %qT"),
4217e4b17023SJohn Marino t1, t2);
4218e4b17023SJohn Marino }
4219e4b17023SJohn Marino
4220e4b17023SJohn Marino /* Quickly detect the usual case where op1 and op2 have the same type
4221e4b17023SJohn Marino after promotion. */
4222e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
4223e4b17023SJohn Marino {
4224e4b17023SJohn Marino if (type1 == type2)
4225e4b17023SJohn Marino result_type = type1;
4226e4b17023SJohn Marino else
4227e4b17023SJohn Marino result_type = TYPE_MAIN_VARIANT (type1);
4228e4b17023SJohn Marino }
4229e4b17023SJohn Marino else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE
4230e4b17023SJohn Marino || code1 == COMPLEX_TYPE)
4231e4b17023SJohn Marino && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
4232e4b17023SJohn Marino || code2 == COMPLEX_TYPE))
4233e4b17023SJohn Marino {
4234e4b17023SJohn Marino result_type = c_common_type (type1, type2);
4235e4b17023SJohn Marino do_warn_double_promotion (result_type, type1, type2,
4236e4b17023SJohn Marino "implicit conversion from %qT to %qT to "
4237e4b17023SJohn Marino "match other result of conditional",
4238e4b17023SJohn Marino colon_loc);
4239e4b17023SJohn Marino
4240e4b17023SJohn Marino /* If -Wsign-compare, warn here if type1 and type2 have
4241e4b17023SJohn Marino different signedness. We'll promote the signed to unsigned
4242e4b17023SJohn Marino and later code won't know it used to be different.
4243e4b17023SJohn Marino Do this check on the original types, so that explicit casts
4244e4b17023SJohn Marino will be considered, but default promotions won't. */
4245e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
4246e4b17023SJohn Marino {
4247e4b17023SJohn Marino int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1));
4248e4b17023SJohn Marino int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2));
4249e4b17023SJohn Marino
4250e4b17023SJohn Marino if (unsigned_op1 ^ unsigned_op2)
4251e4b17023SJohn Marino {
4252e4b17023SJohn Marino bool ovf;
4253e4b17023SJohn Marino
4254e4b17023SJohn Marino /* Do not warn if the result type is signed, since the
4255e4b17023SJohn Marino signed type will only be chosen if it can represent
4256e4b17023SJohn Marino all the values of the unsigned type. */
4257e4b17023SJohn Marino if (!TYPE_UNSIGNED (result_type))
4258e4b17023SJohn Marino /* OK */;
4259e4b17023SJohn Marino else
4260e4b17023SJohn Marino {
4261e4b17023SJohn Marino bool op1_maybe_const = true;
4262e4b17023SJohn Marino bool op2_maybe_const = true;
4263e4b17023SJohn Marino
4264e4b17023SJohn Marino /* Do not warn if the signed quantity is an
4265e4b17023SJohn Marino unsuffixed integer literal (or some static
4266e4b17023SJohn Marino constant expression involving such literals) and
4267e4b17023SJohn Marino it is non-negative. This warning requires the
4268e4b17023SJohn Marino operands to be folded for best results, so do
4269e4b17023SJohn Marino that folding in this case even without
4270e4b17023SJohn Marino warn_sign_compare to avoid warning options
4271e4b17023SJohn Marino possibly affecting code generation. */
4272e4b17023SJohn Marino c_inhibit_evaluation_warnings
4273e4b17023SJohn Marino += (ifexp == truthvalue_false_node);
4274e4b17023SJohn Marino op1 = c_fully_fold (op1, require_constant_value,
4275e4b17023SJohn Marino &op1_maybe_const);
4276e4b17023SJohn Marino c_inhibit_evaluation_warnings
4277e4b17023SJohn Marino -= (ifexp == truthvalue_false_node);
4278e4b17023SJohn Marino
4279e4b17023SJohn Marino c_inhibit_evaluation_warnings
4280e4b17023SJohn Marino += (ifexp == truthvalue_true_node);
4281e4b17023SJohn Marino op2 = c_fully_fold (op2, require_constant_value,
4282e4b17023SJohn Marino &op2_maybe_const);
4283e4b17023SJohn Marino c_inhibit_evaluation_warnings
4284e4b17023SJohn Marino -= (ifexp == truthvalue_true_node);
4285e4b17023SJohn Marino
4286e4b17023SJohn Marino if (warn_sign_compare)
4287e4b17023SJohn Marino {
4288e4b17023SJohn Marino if ((unsigned_op2
4289e4b17023SJohn Marino && tree_expr_nonnegative_warnv_p (op1, &ovf))
4290e4b17023SJohn Marino || (unsigned_op1
4291e4b17023SJohn Marino && tree_expr_nonnegative_warnv_p (op2, &ovf)))
4292e4b17023SJohn Marino /* OK */;
4293e4b17023SJohn Marino else
4294e4b17023SJohn Marino warning_at (colon_loc, OPT_Wsign_compare,
4295e4b17023SJohn Marino ("signed and unsigned type in "
4296e4b17023SJohn Marino "conditional expression"));
4297e4b17023SJohn Marino }
4298e4b17023SJohn Marino if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
4299e4b17023SJohn Marino op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
4300e4b17023SJohn Marino if (!op2_maybe_const || TREE_CODE (op2) != INTEGER_CST)
4301e4b17023SJohn Marino op2 = c_wrap_maybe_const (op2, !op2_maybe_const);
4302e4b17023SJohn Marino }
4303e4b17023SJohn Marino }
4304e4b17023SJohn Marino }
4305e4b17023SJohn Marino }
4306e4b17023SJohn Marino else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
4307e4b17023SJohn Marino {
4308e4b17023SJohn Marino if (code1 != VOID_TYPE || code2 != VOID_TYPE)
4309e4b17023SJohn Marino pedwarn (colon_loc, OPT_pedantic,
4310e4b17023SJohn Marino "ISO C forbids conditional expr with only one void side");
4311e4b17023SJohn Marino result_type = void_type_node;
4312e4b17023SJohn Marino }
4313e4b17023SJohn Marino else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
4314e4b17023SJohn Marino {
4315e4b17023SJohn Marino addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (type1));
4316e4b17023SJohn Marino addr_space_t as2 = TYPE_ADDR_SPACE (TREE_TYPE (type2));
4317e4b17023SJohn Marino addr_space_t as_common;
4318e4b17023SJohn Marino
4319e4b17023SJohn Marino if (comp_target_types (colon_loc, type1, type2))
4320e4b17023SJohn Marino result_type = common_pointer_type (type1, type2);
4321e4b17023SJohn Marino else if (null_pointer_constant_p (orig_op1))
4322e4b17023SJohn Marino result_type = type2;
4323e4b17023SJohn Marino else if (null_pointer_constant_p (orig_op2))
4324e4b17023SJohn Marino result_type = type1;
4325e4b17023SJohn Marino else if (!addr_space_superset (as1, as2, &as_common))
4326e4b17023SJohn Marino {
4327e4b17023SJohn Marino error_at (colon_loc, "pointers to disjoint address spaces "
4328e4b17023SJohn Marino "used in conditional expression");
4329e4b17023SJohn Marino return error_mark_node;
4330e4b17023SJohn Marino }
4331e4b17023SJohn Marino else if (VOID_TYPE_P (TREE_TYPE (type1)))
4332e4b17023SJohn Marino {
4333e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
4334e4b17023SJohn Marino pedwarn (colon_loc, OPT_pedantic,
4335e4b17023SJohn Marino "ISO C forbids conditional expr between "
4336e4b17023SJohn Marino "%<void *%> and function pointer");
4337e4b17023SJohn Marino result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
4338e4b17023SJohn Marino TREE_TYPE (type2)));
4339e4b17023SJohn Marino }
4340e4b17023SJohn Marino else if (VOID_TYPE_P (TREE_TYPE (type2)))
4341e4b17023SJohn Marino {
4342e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
4343e4b17023SJohn Marino pedwarn (colon_loc, OPT_pedantic,
4344e4b17023SJohn Marino "ISO C forbids conditional expr between "
4345e4b17023SJohn Marino "%<void *%> and function pointer");
4346e4b17023SJohn Marino result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
4347e4b17023SJohn Marino TREE_TYPE (type1)));
4348e4b17023SJohn Marino }
4349e4b17023SJohn Marino /* Objective-C pointer comparisons are a bit more lenient. */
4350e4b17023SJohn Marino else if (objc_have_common_type (type1, type2, -3, NULL_TREE))
4351e4b17023SJohn Marino result_type = objc_common_type (type1, type2);
4352e4b17023SJohn Marino else
4353e4b17023SJohn Marino {
4354e4b17023SJohn Marino int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
4355e4b17023SJohn Marino
4356e4b17023SJohn Marino pedwarn (colon_loc, 0,
4357e4b17023SJohn Marino "pointer type mismatch in conditional expression");
4358e4b17023SJohn Marino result_type = build_pointer_type
4359e4b17023SJohn Marino (build_qualified_type (void_type_node, qual));
4360e4b17023SJohn Marino }
4361e4b17023SJohn Marino }
4362e4b17023SJohn Marino else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
4363e4b17023SJohn Marino {
4364e4b17023SJohn Marino if (!null_pointer_constant_p (orig_op2))
4365e4b17023SJohn Marino pedwarn (colon_loc, 0,
4366e4b17023SJohn Marino "pointer/integer type mismatch in conditional expression");
4367e4b17023SJohn Marino else
4368e4b17023SJohn Marino {
4369e4b17023SJohn Marino op2 = null_pointer_node;
4370e4b17023SJohn Marino }
4371e4b17023SJohn Marino result_type = type1;
4372e4b17023SJohn Marino }
4373e4b17023SJohn Marino else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
4374e4b17023SJohn Marino {
4375e4b17023SJohn Marino if (!null_pointer_constant_p (orig_op1))
4376e4b17023SJohn Marino pedwarn (colon_loc, 0,
4377e4b17023SJohn Marino "pointer/integer type mismatch in conditional expression");
4378e4b17023SJohn Marino else
4379e4b17023SJohn Marino {
4380e4b17023SJohn Marino op1 = null_pointer_node;
4381e4b17023SJohn Marino }
4382e4b17023SJohn Marino result_type = type2;
4383e4b17023SJohn Marino }
4384e4b17023SJohn Marino
4385e4b17023SJohn Marino if (!result_type)
4386e4b17023SJohn Marino {
4387e4b17023SJohn Marino if (flag_cond_mismatch)
4388e4b17023SJohn Marino result_type = void_type_node;
4389e4b17023SJohn Marino else
4390e4b17023SJohn Marino {
4391e4b17023SJohn Marino error_at (colon_loc, "type mismatch in conditional expression");
4392e4b17023SJohn Marino return error_mark_node;
4393e4b17023SJohn Marino }
4394e4b17023SJohn Marino }
4395e4b17023SJohn Marino
4396e4b17023SJohn Marino /* Merge const and volatile flags of the incoming types. */
4397e4b17023SJohn Marino result_type
4398e4b17023SJohn Marino = build_type_variant (result_type,
4399e4b17023SJohn Marino TYPE_READONLY (type1) || TYPE_READONLY (type2),
4400e4b17023SJohn Marino TYPE_VOLATILE (type1) || TYPE_VOLATILE (type2));
4401e4b17023SJohn Marino
4402e4b17023SJohn Marino op1 = ep_convert_and_check (result_type, op1, semantic_result_type);
4403e4b17023SJohn Marino op2 = ep_convert_and_check (result_type, op2, semantic_result_type);
4404e4b17023SJohn Marino
4405e4b17023SJohn Marino if (ifexp_bcp && ifexp == truthvalue_true_node)
4406e4b17023SJohn Marino {
4407e4b17023SJohn Marino op2_int_operands = true;
4408e4b17023SJohn Marino op1 = c_fully_fold (op1, require_constant_value, NULL);
4409e4b17023SJohn Marino }
4410e4b17023SJohn Marino if (ifexp_bcp && ifexp == truthvalue_false_node)
4411e4b17023SJohn Marino {
4412e4b17023SJohn Marino op1_int_operands = true;
4413e4b17023SJohn Marino op2 = c_fully_fold (op2, require_constant_value, NULL);
4414e4b17023SJohn Marino }
4415e4b17023SJohn Marino int_const = int_operands = (ifexp_int_operands
4416e4b17023SJohn Marino && op1_int_operands
4417e4b17023SJohn Marino && op2_int_operands);
4418e4b17023SJohn Marino if (int_operands)
4419e4b17023SJohn Marino {
4420e4b17023SJohn Marino int_const = ((ifexp == truthvalue_true_node
4421e4b17023SJohn Marino && TREE_CODE (orig_op1) == INTEGER_CST
4422e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op1))
4423e4b17023SJohn Marino || (ifexp == truthvalue_false_node
4424e4b17023SJohn Marino && TREE_CODE (orig_op2) == INTEGER_CST
4425e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op2)));
4426e4b17023SJohn Marino }
4427e4b17023SJohn Marino if (int_const || (ifexp_bcp && TREE_CODE (ifexp) == INTEGER_CST))
4428e4b17023SJohn Marino ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2);
4429e4b17023SJohn Marino else
4430e4b17023SJohn Marino {
4431e4b17023SJohn Marino if (int_operands)
4432e4b17023SJohn Marino {
4433e4b17023SJohn Marino op1 = remove_c_maybe_const_expr (op1);
4434e4b17023SJohn Marino op2 = remove_c_maybe_const_expr (op2);
4435e4b17023SJohn Marino }
4436e4b17023SJohn Marino ret = build3 (COND_EXPR, result_type, ifexp, op1, op2);
4437e4b17023SJohn Marino if (int_operands)
4438e4b17023SJohn Marino ret = note_integer_operands (ret);
4439e4b17023SJohn Marino }
4440e4b17023SJohn Marino if (semantic_result_type)
4441e4b17023SJohn Marino ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret);
4442e4b17023SJohn Marino
4443e4b17023SJohn Marino protected_set_expr_location (ret, colon_loc);
4444e4b17023SJohn Marino return ret;
4445e4b17023SJohn Marino }
4446e4b17023SJohn Marino
4447e4b17023SJohn Marino /* Return a compound expression that performs two expressions and
4448e4b17023SJohn Marino returns the value of the second of them.
4449e4b17023SJohn Marino
4450e4b17023SJohn Marino LOC is the location of the COMPOUND_EXPR. */
4451e4b17023SJohn Marino
4452e4b17023SJohn Marino tree
build_compound_expr(location_t loc,tree expr1,tree expr2)4453e4b17023SJohn Marino build_compound_expr (location_t loc, tree expr1, tree expr2)
4454e4b17023SJohn Marino {
4455e4b17023SJohn Marino bool expr1_int_operands, expr2_int_operands;
4456e4b17023SJohn Marino tree eptype = NULL_TREE;
4457e4b17023SJohn Marino tree ret;
4458e4b17023SJohn Marino
4459e4b17023SJohn Marino expr1_int_operands = EXPR_INT_CONST_OPERANDS (expr1);
4460e4b17023SJohn Marino if (expr1_int_operands)
4461e4b17023SJohn Marino expr1 = remove_c_maybe_const_expr (expr1);
4462e4b17023SJohn Marino expr2_int_operands = EXPR_INT_CONST_OPERANDS (expr2);
4463e4b17023SJohn Marino if (expr2_int_operands)
4464e4b17023SJohn Marino expr2 = remove_c_maybe_const_expr (expr2);
4465e4b17023SJohn Marino
4466e4b17023SJohn Marino if (TREE_CODE (expr1) == EXCESS_PRECISION_EXPR)
4467e4b17023SJohn Marino expr1 = TREE_OPERAND (expr1, 0);
4468e4b17023SJohn Marino if (TREE_CODE (expr2) == EXCESS_PRECISION_EXPR)
4469e4b17023SJohn Marino {
4470e4b17023SJohn Marino eptype = TREE_TYPE (expr2);
4471e4b17023SJohn Marino expr2 = TREE_OPERAND (expr2, 0);
4472e4b17023SJohn Marino }
4473e4b17023SJohn Marino
4474e4b17023SJohn Marino if (!TREE_SIDE_EFFECTS (expr1))
4475e4b17023SJohn Marino {
4476e4b17023SJohn Marino /* The left-hand operand of a comma expression is like an expression
4477e4b17023SJohn Marino statement: with -Wunused, we should warn if it doesn't have
4478e4b17023SJohn Marino any side-effects, unless it was explicitly cast to (void). */
4479e4b17023SJohn Marino if (warn_unused_value)
4480e4b17023SJohn Marino {
4481e4b17023SJohn Marino if (VOID_TYPE_P (TREE_TYPE (expr1))
4482e4b17023SJohn Marino && CONVERT_EXPR_P (expr1))
4483e4b17023SJohn Marino ; /* (void) a, b */
4484e4b17023SJohn Marino else if (VOID_TYPE_P (TREE_TYPE (expr1))
4485e4b17023SJohn Marino && TREE_CODE (expr1) == COMPOUND_EXPR
4486e4b17023SJohn Marino && CONVERT_EXPR_P (TREE_OPERAND (expr1, 1)))
4487e4b17023SJohn Marino ; /* (void) a, (void) b, c */
4488e4b17023SJohn Marino else
4489e4b17023SJohn Marino warning_at (loc, OPT_Wunused_value,
4490e4b17023SJohn Marino "left-hand operand of comma expression has no effect");
4491e4b17023SJohn Marino }
4492e4b17023SJohn Marino }
4493e4b17023SJohn Marino
4494e4b17023SJohn Marino /* With -Wunused, we should also warn if the left-hand operand does have
4495e4b17023SJohn Marino side-effects, but computes a value which is not used. For example, in
4496e4b17023SJohn Marino `foo() + bar(), baz()' the result of the `+' operator is not used,
4497e4b17023SJohn Marino so we should issue a warning. */
4498e4b17023SJohn Marino else if (warn_unused_value)
4499e4b17023SJohn Marino warn_if_unused_value (expr1, loc);
4500e4b17023SJohn Marino
4501e4b17023SJohn Marino if (expr2 == error_mark_node)
4502e4b17023SJohn Marino return error_mark_node;
4503e4b17023SJohn Marino
4504e4b17023SJohn Marino ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
4505e4b17023SJohn Marino
4506e4b17023SJohn Marino if (flag_isoc99
4507e4b17023SJohn Marino && expr1_int_operands
4508e4b17023SJohn Marino && expr2_int_operands)
4509e4b17023SJohn Marino ret = note_integer_operands (ret);
4510e4b17023SJohn Marino
4511e4b17023SJohn Marino if (eptype)
4512e4b17023SJohn Marino ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
4513e4b17023SJohn Marino
4514e4b17023SJohn Marino protected_set_expr_location (ret, loc);
4515e4b17023SJohn Marino return ret;
4516e4b17023SJohn Marino }
4517e4b17023SJohn Marino
4518e4b17023SJohn Marino /* Issue -Wcast-qual warnings when appropriate. TYPE is the type to
4519e4b17023SJohn Marino which we are casting. OTYPE is the type of the expression being
4520e4b17023SJohn Marino cast. Both TYPE and OTYPE are pointer types. LOC is the location
4521e4b17023SJohn Marino of the cast. -Wcast-qual appeared on the command line. Named
4522e4b17023SJohn Marino address space qualifiers are not handled here, because they result
4523e4b17023SJohn Marino in different warnings. */
4524e4b17023SJohn Marino
4525e4b17023SJohn Marino static void
handle_warn_cast_qual(location_t loc,tree type,tree otype)4526e4b17023SJohn Marino handle_warn_cast_qual (location_t loc, tree type, tree otype)
4527e4b17023SJohn Marino {
4528e4b17023SJohn Marino tree in_type = type;
4529e4b17023SJohn Marino tree in_otype = otype;
4530e4b17023SJohn Marino int added = 0;
4531e4b17023SJohn Marino int discarded = 0;
4532e4b17023SJohn Marino bool is_const;
4533e4b17023SJohn Marino
4534e4b17023SJohn Marino /* Check that the qualifiers on IN_TYPE are a superset of the
4535e4b17023SJohn Marino qualifiers of IN_OTYPE. The outermost level of POINTER_TYPE
4536e4b17023SJohn Marino nodes is uninteresting and we stop as soon as we hit a
4537e4b17023SJohn Marino non-POINTER_TYPE node on either type. */
4538e4b17023SJohn Marino do
4539e4b17023SJohn Marino {
4540e4b17023SJohn Marino in_otype = TREE_TYPE (in_otype);
4541e4b17023SJohn Marino in_type = TREE_TYPE (in_type);
4542e4b17023SJohn Marino
4543e4b17023SJohn Marino /* GNU C allows cv-qualified function types. 'const' means the
4544e4b17023SJohn Marino function is very pure, 'volatile' means it can't return. We
4545e4b17023SJohn Marino need to warn when such qualifiers are added, not when they're
4546e4b17023SJohn Marino taken away. */
4547e4b17023SJohn Marino if (TREE_CODE (in_otype) == FUNCTION_TYPE
4548e4b17023SJohn Marino && TREE_CODE (in_type) == FUNCTION_TYPE)
4549e4b17023SJohn Marino added |= (TYPE_QUALS_NO_ADDR_SPACE (in_type)
4550e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (in_otype));
4551e4b17023SJohn Marino else
4552e4b17023SJohn Marino discarded |= (TYPE_QUALS_NO_ADDR_SPACE (in_otype)
4553e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (in_type));
4554e4b17023SJohn Marino }
4555e4b17023SJohn Marino while (TREE_CODE (in_type) == POINTER_TYPE
4556e4b17023SJohn Marino && TREE_CODE (in_otype) == POINTER_TYPE);
4557e4b17023SJohn Marino
4558e4b17023SJohn Marino if (added)
4559e4b17023SJohn Marino warning_at (loc, OPT_Wcast_qual,
4560e4b17023SJohn Marino "cast adds %q#v qualifier to function type", added);
4561e4b17023SJohn Marino
4562e4b17023SJohn Marino if (discarded)
4563e4b17023SJohn Marino /* There are qualifiers present in IN_OTYPE that are not present
4564e4b17023SJohn Marino in IN_TYPE. */
4565e4b17023SJohn Marino warning_at (loc, OPT_Wcast_qual,
4566e4b17023SJohn Marino "cast discards %q#v qualifier from pointer target type",
4567e4b17023SJohn Marino discarded);
4568e4b17023SJohn Marino
4569e4b17023SJohn Marino if (added || discarded)
4570e4b17023SJohn Marino return;
4571e4b17023SJohn Marino
4572e4b17023SJohn Marino /* A cast from **T to const **T is unsafe, because it can cause a
4573e4b17023SJohn Marino const value to be changed with no additional warning. We only
4574e4b17023SJohn Marino issue this warning if T is the same on both sides, and we only
4575e4b17023SJohn Marino issue the warning if there are the same number of pointers on
4576e4b17023SJohn Marino both sides, as otherwise the cast is clearly unsafe anyhow. A
4577e4b17023SJohn Marino cast is unsafe when a qualifier is added at one level and const
4578e4b17023SJohn Marino is not present at all outer levels.
4579e4b17023SJohn Marino
4580e4b17023SJohn Marino To issue this warning, we check at each level whether the cast
4581e4b17023SJohn Marino adds new qualifiers not already seen. We don't need to special
4582e4b17023SJohn Marino case function types, as they won't have the same
4583e4b17023SJohn Marino TYPE_MAIN_VARIANT. */
4584e4b17023SJohn Marino
4585e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (in_type) != TYPE_MAIN_VARIANT (in_otype))
4586e4b17023SJohn Marino return;
4587e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE)
4588e4b17023SJohn Marino return;
4589e4b17023SJohn Marino
4590e4b17023SJohn Marino in_type = type;
4591e4b17023SJohn Marino in_otype = otype;
4592e4b17023SJohn Marino is_const = TYPE_READONLY (TREE_TYPE (in_type));
4593e4b17023SJohn Marino do
4594e4b17023SJohn Marino {
4595e4b17023SJohn Marino in_type = TREE_TYPE (in_type);
4596e4b17023SJohn Marino in_otype = TREE_TYPE (in_otype);
4597e4b17023SJohn Marino if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0
4598e4b17023SJohn Marino && !is_const)
4599e4b17023SJohn Marino {
4600e4b17023SJohn Marino warning_at (loc, OPT_Wcast_qual,
4601e4b17023SJohn Marino "to be safe all intermediate pointers in cast from "
4602e4b17023SJohn Marino "%qT to %qT must be %<const%> qualified",
4603e4b17023SJohn Marino otype, type);
4604e4b17023SJohn Marino break;
4605e4b17023SJohn Marino }
4606e4b17023SJohn Marino if (is_const)
4607e4b17023SJohn Marino is_const = TYPE_READONLY (in_type);
4608e4b17023SJohn Marino }
4609e4b17023SJohn Marino while (TREE_CODE (in_type) == POINTER_TYPE);
4610e4b17023SJohn Marino }
4611e4b17023SJohn Marino
4612e4b17023SJohn Marino /* Build an expression representing a cast to type TYPE of expression EXPR.
4613e4b17023SJohn Marino LOC is the location of the cast-- typically the open paren of the cast. */
4614e4b17023SJohn Marino
4615e4b17023SJohn Marino tree
build_c_cast(location_t loc,tree type,tree expr)4616e4b17023SJohn Marino build_c_cast (location_t loc, tree type, tree expr)
4617e4b17023SJohn Marino {
4618e4b17023SJohn Marino tree value;
4619e4b17023SJohn Marino
4620e4b17023SJohn Marino if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
4621e4b17023SJohn Marino expr = TREE_OPERAND (expr, 0);
4622e4b17023SJohn Marino
4623e4b17023SJohn Marino value = expr;
4624e4b17023SJohn Marino
4625e4b17023SJohn Marino if (type == error_mark_node || expr == error_mark_node)
4626e4b17023SJohn Marino return error_mark_node;
4627e4b17023SJohn Marino
4628e4b17023SJohn Marino /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing
4629e4b17023SJohn Marino only in <protocol> qualifications. But when constructing cast expressions,
4630e4b17023SJohn Marino the protocols do matter and must be kept around. */
4631e4b17023SJohn Marino if (objc_is_object_ptr (type) && objc_is_object_ptr (TREE_TYPE (expr)))
4632e4b17023SJohn Marino return build1 (NOP_EXPR, type, expr);
4633e4b17023SJohn Marino
4634e4b17023SJohn Marino type = TYPE_MAIN_VARIANT (type);
4635e4b17023SJohn Marino
4636e4b17023SJohn Marino if (TREE_CODE (type) == ARRAY_TYPE)
4637e4b17023SJohn Marino {
4638e4b17023SJohn Marino error_at (loc, "cast specifies array type");
4639e4b17023SJohn Marino return error_mark_node;
4640e4b17023SJohn Marino }
4641e4b17023SJohn Marino
4642e4b17023SJohn Marino if (TREE_CODE (type) == FUNCTION_TYPE)
4643e4b17023SJohn Marino {
4644e4b17023SJohn Marino error_at (loc, "cast specifies function type");
4645e4b17023SJohn Marino return error_mark_node;
4646e4b17023SJohn Marino }
4647e4b17023SJohn Marino
4648e4b17023SJohn Marino if (!VOID_TYPE_P (type))
4649e4b17023SJohn Marino {
4650e4b17023SJohn Marino value = require_complete_type (value);
4651e4b17023SJohn Marino if (value == error_mark_node)
4652e4b17023SJohn Marino return error_mark_node;
4653e4b17023SJohn Marino }
4654e4b17023SJohn Marino
4655e4b17023SJohn Marino if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
4656e4b17023SJohn Marino {
4657e4b17023SJohn Marino if (TREE_CODE (type) == RECORD_TYPE
4658e4b17023SJohn Marino || TREE_CODE (type) == UNION_TYPE)
4659e4b17023SJohn Marino pedwarn (loc, OPT_pedantic,
4660e4b17023SJohn Marino "ISO C forbids casting nonscalar to the same type");
4661e4b17023SJohn Marino }
4662e4b17023SJohn Marino else if (TREE_CODE (type) == UNION_TYPE)
4663e4b17023SJohn Marino {
4664e4b17023SJohn Marino tree field;
4665e4b17023SJohn Marino
4666e4b17023SJohn Marino for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
4667e4b17023SJohn Marino if (TREE_TYPE (field) != error_mark_node
4668e4b17023SJohn Marino && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
4669e4b17023SJohn Marino TYPE_MAIN_VARIANT (TREE_TYPE (value))))
4670e4b17023SJohn Marino break;
4671e4b17023SJohn Marino
4672e4b17023SJohn Marino if (field)
4673e4b17023SJohn Marino {
4674e4b17023SJohn Marino tree t;
4675e4b17023SJohn Marino bool maybe_const = true;
4676e4b17023SJohn Marino
4677e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C forbids casts to union type");
4678e4b17023SJohn Marino t = c_fully_fold (value, false, &maybe_const);
4679e4b17023SJohn Marino t = build_constructor_single (type, field, t);
4680e4b17023SJohn Marino if (!maybe_const)
4681e4b17023SJohn Marino t = c_wrap_maybe_const (t, true);
4682e4b17023SJohn Marino t = digest_init (loc, type, t,
4683e4b17023SJohn Marino NULL_TREE, false, true, 0);
4684e4b17023SJohn Marino TREE_CONSTANT (t) = TREE_CONSTANT (value);
4685e4b17023SJohn Marino return t;
4686e4b17023SJohn Marino }
4687e4b17023SJohn Marino error_at (loc, "cast to union type from type not present in union");
4688e4b17023SJohn Marino return error_mark_node;
4689e4b17023SJohn Marino }
4690e4b17023SJohn Marino else
4691e4b17023SJohn Marino {
4692e4b17023SJohn Marino tree otype, ovalue;
4693e4b17023SJohn Marino
4694e4b17023SJohn Marino if (type == void_type_node)
4695e4b17023SJohn Marino {
4696e4b17023SJohn Marino tree t = build1 (CONVERT_EXPR, type, value);
4697e4b17023SJohn Marino SET_EXPR_LOCATION (t, loc);
4698e4b17023SJohn Marino return t;
4699e4b17023SJohn Marino }
4700e4b17023SJohn Marino
4701e4b17023SJohn Marino otype = TREE_TYPE (value);
4702e4b17023SJohn Marino
4703e4b17023SJohn Marino /* Optionally warn about potentially worrisome casts. */
4704e4b17023SJohn Marino if (warn_cast_qual
4705e4b17023SJohn Marino && TREE_CODE (type) == POINTER_TYPE
4706e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE)
4707e4b17023SJohn Marino handle_warn_cast_qual (loc, type, otype);
4708e4b17023SJohn Marino
4709e4b17023SJohn Marino /* Warn about conversions between pointers to disjoint
4710e4b17023SJohn Marino address spaces. */
4711e4b17023SJohn Marino if (TREE_CODE (type) == POINTER_TYPE
4712e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE
4713e4b17023SJohn Marino && !null_pointer_constant_p (value))
4714e4b17023SJohn Marino {
4715e4b17023SJohn Marino addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
4716e4b17023SJohn Marino addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (otype));
4717e4b17023SJohn Marino addr_space_t as_common;
4718e4b17023SJohn Marino
4719e4b17023SJohn Marino if (!addr_space_superset (as_to, as_from, &as_common))
4720e4b17023SJohn Marino {
4721e4b17023SJohn Marino if (ADDR_SPACE_GENERIC_P (as_from))
4722e4b17023SJohn Marino warning_at (loc, 0, "cast to %s address space pointer "
4723e4b17023SJohn Marino "from disjoint generic address space pointer",
4724e4b17023SJohn Marino c_addr_space_name (as_to));
4725e4b17023SJohn Marino
4726e4b17023SJohn Marino else if (ADDR_SPACE_GENERIC_P (as_to))
4727e4b17023SJohn Marino warning_at (loc, 0, "cast to generic address space pointer "
4728e4b17023SJohn Marino "from disjoint %s address space pointer",
4729e4b17023SJohn Marino c_addr_space_name (as_from));
4730e4b17023SJohn Marino
4731e4b17023SJohn Marino else
4732e4b17023SJohn Marino warning_at (loc, 0, "cast to %s address space pointer "
4733e4b17023SJohn Marino "from disjoint %s address space pointer",
4734e4b17023SJohn Marino c_addr_space_name (as_to),
4735e4b17023SJohn Marino c_addr_space_name (as_from));
4736e4b17023SJohn Marino }
4737e4b17023SJohn Marino }
4738e4b17023SJohn Marino
4739e4b17023SJohn Marino /* Warn about possible alignment problems. */
4740e4b17023SJohn Marino if (STRICT_ALIGNMENT
4741e4b17023SJohn Marino && TREE_CODE (type) == POINTER_TYPE
4742e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE
4743e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
4744e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
4745e4b17023SJohn Marino /* Don't warn about opaque types, where the actual alignment
4746e4b17023SJohn Marino restriction is unknown. */
4747e4b17023SJohn Marino && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
4748e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
4749e4b17023SJohn Marino && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
4750e4b17023SJohn Marino && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
4751e4b17023SJohn Marino warning_at (loc, OPT_Wcast_align,
4752e4b17023SJohn Marino "cast increases required alignment of target type");
4753e4b17023SJohn Marino
4754e4b17023SJohn Marino if (TREE_CODE (type) == INTEGER_TYPE
4755e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE
4756e4b17023SJohn Marino && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
4757e4b17023SJohn Marino /* Unlike conversion of integers to pointers, where the
4758e4b17023SJohn Marino warning is disabled for converting constants because
4759e4b17023SJohn Marino of cases such as SIG_*, warn about converting constant
4760e4b17023SJohn Marino pointers to integers. In some cases it may cause unwanted
4761e4b17023SJohn Marino sign extension, and a warning is appropriate. */
4762e4b17023SJohn Marino warning_at (loc, OPT_Wpointer_to_int_cast,
4763e4b17023SJohn Marino "cast from pointer to integer of different size");
4764e4b17023SJohn Marino
4765e4b17023SJohn Marino if (TREE_CODE (value) == CALL_EXPR
4766e4b17023SJohn Marino && TREE_CODE (type) != TREE_CODE (otype))
4767e4b17023SJohn Marino warning_at (loc, OPT_Wbad_function_cast,
4768e4b17023SJohn Marino "cast from function call of type %qT "
4769e4b17023SJohn Marino "to non-matching type %qT", otype, type);
4770e4b17023SJohn Marino
4771e4b17023SJohn Marino if (TREE_CODE (type) == POINTER_TYPE
4772e4b17023SJohn Marino && TREE_CODE (otype) == INTEGER_TYPE
4773e4b17023SJohn Marino && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
4774e4b17023SJohn Marino /* Don't warn about converting any constant. */
4775e4b17023SJohn Marino && !TREE_CONSTANT (value))
4776e4b17023SJohn Marino warning_at (loc,
4777e4b17023SJohn Marino OPT_Wint_to_pointer_cast, "cast to pointer from integer "
4778e4b17023SJohn Marino "of different size");
4779e4b17023SJohn Marino
4780e4b17023SJohn Marino if (warn_strict_aliasing <= 2)
4781e4b17023SJohn Marino strict_aliasing_warning (otype, type, expr);
4782e4b17023SJohn Marino
4783e4b17023SJohn Marino /* If pedantic, warn for conversions between function and object
4784e4b17023SJohn Marino pointer types, except for converting a null pointer constant
4785e4b17023SJohn Marino to function pointer type. */
4786e4b17023SJohn Marino if (pedantic
4787e4b17023SJohn Marino && TREE_CODE (type) == POINTER_TYPE
4788e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE
4789e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
4790e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
4791e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C forbids "
4792e4b17023SJohn Marino "conversion of function pointer to object pointer type");
4793e4b17023SJohn Marino
4794e4b17023SJohn Marino if (pedantic
4795e4b17023SJohn Marino && TREE_CODE (type) == POINTER_TYPE
4796e4b17023SJohn Marino && TREE_CODE (otype) == POINTER_TYPE
4797e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
4798e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
4799e4b17023SJohn Marino && !null_pointer_constant_p (value))
4800e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C forbids "
4801e4b17023SJohn Marino "conversion of object pointer to function pointer type");
4802e4b17023SJohn Marino
4803e4b17023SJohn Marino ovalue = value;
4804e4b17023SJohn Marino value = convert (type, value);
4805e4b17023SJohn Marino
4806e4b17023SJohn Marino /* Ignore any integer overflow caused by the cast. */
4807e4b17023SJohn Marino if (TREE_CODE (value) == INTEGER_CST && !FLOAT_TYPE_P (otype))
4808e4b17023SJohn Marino {
4809e4b17023SJohn Marino if (CONSTANT_CLASS_P (ovalue) && TREE_OVERFLOW (ovalue))
4810e4b17023SJohn Marino {
4811e4b17023SJohn Marino if (!TREE_OVERFLOW (value))
4812e4b17023SJohn Marino {
4813e4b17023SJohn Marino /* Avoid clobbering a shared constant. */
4814e4b17023SJohn Marino value = copy_node (value);
4815e4b17023SJohn Marino TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
4816e4b17023SJohn Marino }
4817e4b17023SJohn Marino }
4818e4b17023SJohn Marino else if (TREE_OVERFLOW (value))
4819e4b17023SJohn Marino /* Reset VALUE's overflow flags, ensuring constant sharing. */
4820e4b17023SJohn Marino value = build_int_cst_wide (TREE_TYPE (value),
4821e4b17023SJohn Marino TREE_INT_CST_LOW (value),
4822e4b17023SJohn Marino TREE_INT_CST_HIGH (value));
4823e4b17023SJohn Marino }
4824e4b17023SJohn Marino }
4825e4b17023SJohn Marino
4826e4b17023SJohn Marino /* Don't let a cast be an lvalue. */
4827e4b17023SJohn Marino if (value == expr)
4828e4b17023SJohn Marino value = non_lvalue_loc (loc, value);
4829e4b17023SJohn Marino
4830e4b17023SJohn Marino /* Don't allow the results of casting to floating-point or complex
4831e4b17023SJohn Marino types be confused with actual constants, or casts involving
4832e4b17023SJohn Marino integer and pointer types other than direct integer-to-integer
4833e4b17023SJohn Marino and integer-to-pointer be confused with integer constant
4834e4b17023SJohn Marino expressions and null pointer constants. */
4835e4b17023SJohn Marino if (TREE_CODE (value) == REAL_CST
4836e4b17023SJohn Marino || TREE_CODE (value) == COMPLEX_CST
4837e4b17023SJohn Marino || (TREE_CODE (value) == INTEGER_CST
4838e4b17023SJohn Marino && !((TREE_CODE (expr) == INTEGER_CST
4839e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (expr)))
4840e4b17023SJohn Marino || TREE_CODE (expr) == REAL_CST
4841e4b17023SJohn Marino || TREE_CODE (expr) == COMPLEX_CST)))
4842e4b17023SJohn Marino value = build1 (NOP_EXPR, type, value);
4843e4b17023SJohn Marino
4844e4b17023SJohn Marino if (CAN_HAVE_LOCATION_P (value))
4845e4b17023SJohn Marino SET_EXPR_LOCATION (value, loc);
4846e4b17023SJohn Marino return value;
4847e4b17023SJohn Marino }
4848e4b17023SJohn Marino
4849e4b17023SJohn Marino /* Interpret a cast of expression EXPR to type TYPE. LOC is the
4850e4b17023SJohn Marino location of the open paren of the cast, or the position of the cast
4851e4b17023SJohn Marino expr. */
4852e4b17023SJohn Marino tree
c_cast_expr(location_t loc,struct c_type_name * type_name,tree expr)4853e4b17023SJohn Marino c_cast_expr (location_t loc, struct c_type_name *type_name, tree expr)
4854e4b17023SJohn Marino {
4855e4b17023SJohn Marino tree type;
4856e4b17023SJohn Marino tree type_expr = NULL_TREE;
4857e4b17023SJohn Marino bool type_expr_const = true;
4858e4b17023SJohn Marino tree ret;
4859e4b17023SJohn Marino int saved_wsp = warn_strict_prototypes;
4860e4b17023SJohn Marino
4861e4b17023SJohn Marino /* This avoids warnings about unprototyped casts on
4862e4b17023SJohn Marino integers. E.g. "#define SIG_DFL (void(*)())0". */
4863e4b17023SJohn Marino if (TREE_CODE (expr) == INTEGER_CST)
4864e4b17023SJohn Marino warn_strict_prototypes = 0;
4865e4b17023SJohn Marino type = groktypename (type_name, &type_expr, &type_expr_const);
4866e4b17023SJohn Marino warn_strict_prototypes = saved_wsp;
4867e4b17023SJohn Marino
4868e4b17023SJohn Marino ret = build_c_cast (loc, type, expr);
4869e4b17023SJohn Marino if (type_expr)
4870e4b17023SJohn Marino {
48715ce9237cSJohn Marino bool inner_expr_const = true;
48725ce9237cSJohn Marino ret = c_fully_fold (ret, require_constant_value, &inner_expr_const);
4873e4b17023SJohn Marino ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret), type_expr, ret);
48745ce9237cSJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (ret) = !(type_expr_const
48755ce9237cSJohn Marino && inner_expr_const);
4876e4b17023SJohn Marino SET_EXPR_LOCATION (ret, loc);
4877e4b17023SJohn Marino }
4878e4b17023SJohn Marino
4879e4b17023SJohn Marino if (CAN_HAVE_LOCATION_P (ret) && !EXPR_HAS_LOCATION (ret))
4880e4b17023SJohn Marino SET_EXPR_LOCATION (ret, loc);
4881e4b17023SJohn Marino
4882e4b17023SJohn Marino /* C++ does not permits types to be defined in a cast, but it
4883e4b17023SJohn Marino allows references to incomplete types. */
4884e4b17023SJohn Marino if (warn_cxx_compat && type_name->specs->typespec_kind == ctsk_tagdef)
4885e4b17023SJohn Marino warning_at (loc, OPT_Wc___compat,
4886e4b17023SJohn Marino "defining a type in a cast is invalid in C++");
4887e4b17023SJohn Marino
4888e4b17023SJohn Marino return ret;
4889e4b17023SJohn Marino }
4890e4b17023SJohn Marino
4891e4b17023SJohn Marino /* Build an assignment expression of lvalue LHS from value RHS.
4892e4b17023SJohn Marino If LHS_ORIGTYPE is not NULL, it is the original type of LHS, which
4893e4b17023SJohn Marino may differ from TREE_TYPE (LHS) for an enum bitfield.
4894e4b17023SJohn Marino MODIFYCODE is the code for a binary operator that we use
4895e4b17023SJohn Marino to combine the old value of LHS with RHS to get the new value.
4896e4b17023SJohn Marino Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
4897e4b17023SJohn Marino If RHS_ORIGTYPE is not NULL_TREE, it is the original type of RHS,
4898e4b17023SJohn Marino which may differ from TREE_TYPE (RHS) for an enum value.
4899e4b17023SJohn Marino
4900e4b17023SJohn Marino LOCATION is the location of the MODIFYCODE operator.
4901e4b17023SJohn Marino RHS_LOC is the location of the RHS. */
4902e4b17023SJohn Marino
4903e4b17023SJohn Marino tree
build_modify_expr(location_t location,tree lhs,tree lhs_origtype,enum tree_code modifycode,location_t rhs_loc,tree rhs,tree rhs_origtype)4904e4b17023SJohn Marino build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
4905e4b17023SJohn Marino enum tree_code modifycode,
4906e4b17023SJohn Marino location_t rhs_loc, tree rhs, tree rhs_origtype)
4907e4b17023SJohn Marino {
4908e4b17023SJohn Marino tree result;
4909e4b17023SJohn Marino tree newrhs;
4910e4b17023SJohn Marino tree rhs_semantic_type = NULL_TREE;
4911e4b17023SJohn Marino tree lhstype = TREE_TYPE (lhs);
4912e4b17023SJohn Marino tree olhstype = lhstype;
4913e4b17023SJohn Marino bool npc;
4914e4b17023SJohn Marino
4915e4b17023SJohn Marino /* Types that aren't fully specified cannot be used in assignments. */
4916e4b17023SJohn Marino lhs = require_complete_type (lhs);
4917e4b17023SJohn Marino
4918e4b17023SJohn Marino /* Avoid duplicate error messages from operands that had errors. */
4919e4b17023SJohn Marino if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
4920e4b17023SJohn Marino return error_mark_node;
4921e4b17023SJohn Marino
4922e4b17023SJohn Marino /* For ObjC properties, defer this check. */
4923e4b17023SJohn Marino if (!objc_is_property_ref (lhs) && !lvalue_or_else (location, lhs, lv_assign))
4924e4b17023SJohn Marino return error_mark_node;
4925e4b17023SJohn Marino
4926e4b17023SJohn Marino if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
4927e4b17023SJohn Marino {
4928e4b17023SJohn Marino rhs_semantic_type = TREE_TYPE (rhs);
4929e4b17023SJohn Marino rhs = TREE_OPERAND (rhs, 0);
4930e4b17023SJohn Marino }
4931e4b17023SJohn Marino
4932e4b17023SJohn Marino newrhs = rhs;
4933e4b17023SJohn Marino
4934e4b17023SJohn Marino if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
4935e4b17023SJohn Marino {
4936e4b17023SJohn Marino tree inner = build_modify_expr (location, C_MAYBE_CONST_EXPR_EXPR (lhs),
4937e4b17023SJohn Marino lhs_origtype, modifycode, rhs_loc, rhs,
4938e4b17023SJohn Marino rhs_origtype);
4939e4b17023SJohn Marino if (inner == error_mark_node)
4940e4b17023SJohn Marino return error_mark_node;
4941e4b17023SJohn Marino result = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner),
4942e4b17023SJohn Marino C_MAYBE_CONST_EXPR_PRE (lhs), inner);
4943e4b17023SJohn Marino gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (lhs));
4944e4b17023SJohn Marino C_MAYBE_CONST_EXPR_NON_CONST (result) = 1;
4945e4b17023SJohn Marino protected_set_expr_location (result, location);
4946e4b17023SJohn Marino return result;
4947e4b17023SJohn Marino }
4948e4b17023SJohn Marino
4949e4b17023SJohn Marino /* If a binary op has been requested, combine the old LHS value with the RHS
4950e4b17023SJohn Marino producing the value we should actually store into the LHS. */
4951e4b17023SJohn Marino
4952e4b17023SJohn Marino if (modifycode != NOP_EXPR)
4953e4b17023SJohn Marino {
4954e4b17023SJohn Marino lhs = c_fully_fold (lhs, false, NULL);
4955e4b17023SJohn Marino lhs = stabilize_reference (lhs);
4956e4b17023SJohn Marino newrhs = build_binary_op (location,
4957e4b17023SJohn Marino modifycode, lhs, rhs, 1);
4958e4b17023SJohn Marino
4959e4b17023SJohn Marino /* The original type of the right hand side is no longer
4960e4b17023SJohn Marino meaningful. */
4961e4b17023SJohn Marino rhs_origtype = NULL_TREE;
4962e4b17023SJohn Marino }
4963e4b17023SJohn Marino
4964e4b17023SJohn Marino if (c_dialect_objc ())
4965e4b17023SJohn Marino {
4966e4b17023SJohn Marino /* Check if we are modifying an Objective-C property reference;
4967e4b17023SJohn Marino if so, we need to generate setter calls. */
4968e4b17023SJohn Marino result = objc_maybe_build_modify_expr (lhs, newrhs);
4969e4b17023SJohn Marino if (result)
4970e4b17023SJohn Marino return result;
4971e4b17023SJohn Marino
4972e4b17023SJohn Marino /* Else, do the check that we postponed for Objective-C. */
4973e4b17023SJohn Marino if (!lvalue_or_else (location, lhs, lv_assign))
4974e4b17023SJohn Marino return error_mark_node;
4975e4b17023SJohn Marino }
4976e4b17023SJohn Marino
4977e4b17023SJohn Marino /* Give an error for storing in something that is 'const'. */
4978e4b17023SJohn Marino
4979e4b17023SJohn Marino if (TYPE_READONLY (lhstype)
4980e4b17023SJohn Marino || ((TREE_CODE (lhstype) == RECORD_TYPE
4981e4b17023SJohn Marino || TREE_CODE (lhstype) == UNION_TYPE)
4982e4b17023SJohn Marino && C_TYPE_FIELDS_READONLY (lhstype)))
4983e4b17023SJohn Marino {
4984e4b17023SJohn Marino readonly_error (lhs, lv_assign);
4985e4b17023SJohn Marino return error_mark_node;
4986e4b17023SJohn Marino }
4987e4b17023SJohn Marino else if (TREE_READONLY (lhs))
4988e4b17023SJohn Marino readonly_warning (lhs, lv_assign);
4989e4b17023SJohn Marino
4990e4b17023SJohn Marino /* If storing into a structure or union member,
4991e4b17023SJohn Marino it has probably been given type `int'.
4992e4b17023SJohn Marino Compute the type that would go with
4993e4b17023SJohn Marino the actual amount of storage the member occupies. */
4994e4b17023SJohn Marino
4995e4b17023SJohn Marino if (TREE_CODE (lhs) == COMPONENT_REF
4996e4b17023SJohn Marino && (TREE_CODE (lhstype) == INTEGER_TYPE
4997e4b17023SJohn Marino || TREE_CODE (lhstype) == BOOLEAN_TYPE
4998e4b17023SJohn Marino || TREE_CODE (lhstype) == REAL_TYPE
4999e4b17023SJohn Marino || TREE_CODE (lhstype) == ENUMERAL_TYPE))
5000e4b17023SJohn Marino lhstype = TREE_TYPE (get_unwidened (lhs, 0));
5001e4b17023SJohn Marino
5002e4b17023SJohn Marino /* If storing in a field that is in actuality a short or narrower than one,
5003e4b17023SJohn Marino we must store in the field in its actual type. */
5004e4b17023SJohn Marino
5005e4b17023SJohn Marino if (lhstype != TREE_TYPE (lhs))
5006e4b17023SJohn Marino {
5007e4b17023SJohn Marino lhs = copy_node (lhs);
5008e4b17023SJohn Marino TREE_TYPE (lhs) = lhstype;
5009e4b17023SJohn Marino }
5010e4b17023SJohn Marino
5011e4b17023SJohn Marino /* Issue -Wc++-compat warnings about an assignment to an enum type
5012e4b17023SJohn Marino when LHS does not have its original type. This happens for,
5013e4b17023SJohn Marino e.g., an enum bitfield in a struct. */
5014e4b17023SJohn Marino if (warn_cxx_compat
5015e4b17023SJohn Marino && lhs_origtype != NULL_TREE
5016e4b17023SJohn Marino && lhs_origtype != lhstype
5017e4b17023SJohn Marino && TREE_CODE (lhs_origtype) == ENUMERAL_TYPE)
5018e4b17023SJohn Marino {
5019e4b17023SJohn Marino tree checktype = (rhs_origtype != NULL_TREE
5020e4b17023SJohn Marino ? rhs_origtype
5021e4b17023SJohn Marino : TREE_TYPE (rhs));
5022e4b17023SJohn Marino if (checktype != error_mark_node
5023e4b17023SJohn Marino && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (lhs_origtype))
5024e4b17023SJohn Marino warning_at (location, OPT_Wc___compat,
5025e4b17023SJohn Marino "enum conversion in assignment is invalid in C++");
5026e4b17023SJohn Marino }
5027e4b17023SJohn Marino
5028e4b17023SJohn Marino /* Convert new value to destination type. Fold it first, then
5029e4b17023SJohn Marino restore any excess precision information, for the sake of
5030e4b17023SJohn Marino conversion warnings. */
5031e4b17023SJohn Marino
5032e4b17023SJohn Marino npc = null_pointer_constant_p (newrhs);
5033e4b17023SJohn Marino newrhs = c_fully_fold (newrhs, false, NULL);
5034e4b17023SJohn Marino if (rhs_semantic_type)
5035e4b17023SJohn Marino newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs);
5036e4b17023SJohn Marino newrhs = convert_for_assignment (location, lhstype, newrhs, rhs_origtype,
5037e4b17023SJohn Marino ic_assign, npc, NULL_TREE, NULL_TREE, 0);
5038e4b17023SJohn Marino if (TREE_CODE (newrhs) == ERROR_MARK)
5039e4b17023SJohn Marino return error_mark_node;
5040e4b17023SJohn Marino
5041e4b17023SJohn Marino /* Emit ObjC write barrier, if necessary. */
5042e4b17023SJohn Marino if (c_dialect_objc () && flag_objc_gc)
5043e4b17023SJohn Marino {
5044e4b17023SJohn Marino result = objc_generate_write_barrier (lhs, modifycode, newrhs);
5045e4b17023SJohn Marino if (result)
5046e4b17023SJohn Marino {
5047e4b17023SJohn Marino protected_set_expr_location (result, location);
5048e4b17023SJohn Marino return result;
5049e4b17023SJohn Marino }
5050e4b17023SJohn Marino }
5051e4b17023SJohn Marino
5052e4b17023SJohn Marino /* Scan operands. */
5053e4b17023SJohn Marino
5054e4b17023SJohn Marino result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs);
5055e4b17023SJohn Marino TREE_SIDE_EFFECTS (result) = 1;
5056e4b17023SJohn Marino protected_set_expr_location (result, location);
5057e4b17023SJohn Marino
5058e4b17023SJohn Marino /* If we got the LHS in a different type for storing in,
5059e4b17023SJohn Marino convert the result back to the nominal type of LHS
5060e4b17023SJohn Marino so that the value we return always has the same type
5061e4b17023SJohn Marino as the LHS argument. */
5062e4b17023SJohn Marino
5063e4b17023SJohn Marino if (olhstype == TREE_TYPE (result))
5064e4b17023SJohn Marino return result;
5065e4b17023SJohn Marino
5066e4b17023SJohn Marino result = convert_for_assignment (location, olhstype, result, rhs_origtype,
5067e4b17023SJohn Marino ic_assign, false, NULL_TREE, NULL_TREE, 0);
5068e4b17023SJohn Marino protected_set_expr_location (result, location);
5069e4b17023SJohn Marino return result;
5070e4b17023SJohn Marino }
5071e4b17023SJohn Marino
5072e4b17023SJohn Marino /* Return whether STRUCT_TYPE has an anonymous field with type TYPE.
5073e4b17023SJohn Marino This is used to implement -fplan9-extensions. */
5074e4b17023SJohn Marino
5075e4b17023SJohn Marino static bool
find_anonymous_field_with_type(tree struct_type,tree type)5076e4b17023SJohn Marino find_anonymous_field_with_type (tree struct_type, tree type)
5077e4b17023SJohn Marino {
5078e4b17023SJohn Marino tree field;
5079e4b17023SJohn Marino bool found;
5080e4b17023SJohn Marino
5081e4b17023SJohn Marino gcc_assert (TREE_CODE (struct_type) == RECORD_TYPE
5082e4b17023SJohn Marino || TREE_CODE (struct_type) == UNION_TYPE);
5083e4b17023SJohn Marino found = false;
5084e4b17023SJohn Marino for (field = TYPE_FIELDS (struct_type);
5085e4b17023SJohn Marino field != NULL_TREE;
5086e4b17023SJohn Marino field = TREE_CHAIN (field))
5087e4b17023SJohn Marino {
5088e4b17023SJohn Marino if (DECL_NAME (field) == NULL
5089e4b17023SJohn Marino && comptypes (type, TYPE_MAIN_VARIANT (TREE_TYPE (field))))
5090e4b17023SJohn Marino {
5091e4b17023SJohn Marino if (found)
5092e4b17023SJohn Marino return false;
5093e4b17023SJohn Marino found = true;
5094e4b17023SJohn Marino }
5095e4b17023SJohn Marino else if (DECL_NAME (field) == NULL
5096e4b17023SJohn Marino && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
5097e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
5098e4b17023SJohn Marino && find_anonymous_field_with_type (TREE_TYPE (field), type))
5099e4b17023SJohn Marino {
5100e4b17023SJohn Marino if (found)
5101e4b17023SJohn Marino return false;
5102e4b17023SJohn Marino found = true;
5103e4b17023SJohn Marino }
5104e4b17023SJohn Marino }
5105e4b17023SJohn Marino return found;
5106e4b17023SJohn Marino }
5107e4b17023SJohn Marino
5108e4b17023SJohn Marino /* RHS is an expression whose type is pointer to struct. If there is
5109e4b17023SJohn Marino an anonymous field in RHS with type TYPE, then return a pointer to
5110e4b17023SJohn Marino that field in RHS. This is used with -fplan9-extensions. This
5111e4b17023SJohn Marino returns NULL if no conversion could be found. */
5112e4b17023SJohn Marino
5113e4b17023SJohn Marino static tree
convert_to_anonymous_field(location_t location,tree type,tree rhs)5114e4b17023SJohn Marino convert_to_anonymous_field (location_t location, tree type, tree rhs)
5115e4b17023SJohn Marino {
5116e4b17023SJohn Marino tree rhs_struct_type, lhs_main_type;
5117e4b17023SJohn Marino tree field, found_field;
5118e4b17023SJohn Marino bool found_sub_field;
5119e4b17023SJohn Marino tree ret;
5120e4b17023SJohn Marino
5121e4b17023SJohn Marino gcc_assert (POINTER_TYPE_P (TREE_TYPE (rhs)));
5122e4b17023SJohn Marino rhs_struct_type = TREE_TYPE (TREE_TYPE (rhs));
5123e4b17023SJohn Marino gcc_assert (TREE_CODE (rhs_struct_type) == RECORD_TYPE
5124e4b17023SJohn Marino || TREE_CODE (rhs_struct_type) == UNION_TYPE);
5125e4b17023SJohn Marino
5126e4b17023SJohn Marino gcc_assert (POINTER_TYPE_P (type));
5127e4b17023SJohn Marino lhs_main_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
5128e4b17023SJohn Marino
5129e4b17023SJohn Marino found_field = NULL_TREE;
5130e4b17023SJohn Marino found_sub_field = false;
5131e4b17023SJohn Marino for (field = TYPE_FIELDS (rhs_struct_type);
5132e4b17023SJohn Marino field != NULL_TREE;
5133e4b17023SJohn Marino field = TREE_CHAIN (field))
5134e4b17023SJohn Marino {
5135e4b17023SJohn Marino if (DECL_NAME (field) != NULL_TREE
5136e4b17023SJohn Marino || (TREE_CODE (TREE_TYPE (field)) != RECORD_TYPE
5137e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (field)) != UNION_TYPE))
5138e4b17023SJohn Marino continue;
5139e4b17023SJohn Marino if (comptypes (lhs_main_type, TYPE_MAIN_VARIANT (TREE_TYPE (field))))
5140e4b17023SJohn Marino {
5141e4b17023SJohn Marino if (found_field != NULL_TREE)
5142e4b17023SJohn Marino return NULL_TREE;
5143e4b17023SJohn Marino found_field = field;
5144e4b17023SJohn Marino }
5145e4b17023SJohn Marino else if (find_anonymous_field_with_type (TREE_TYPE (field),
5146e4b17023SJohn Marino lhs_main_type))
5147e4b17023SJohn Marino {
5148e4b17023SJohn Marino if (found_field != NULL_TREE)
5149e4b17023SJohn Marino return NULL_TREE;
5150e4b17023SJohn Marino found_field = field;
5151e4b17023SJohn Marino found_sub_field = true;
5152e4b17023SJohn Marino }
5153e4b17023SJohn Marino }
5154e4b17023SJohn Marino
5155e4b17023SJohn Marino if (found_field == NULL_TREE)
5156e4b17023SJohn Marino return NULL_TREE;
5157e4b17023SJohn Marino
5158e4b17023SJohn Marino ret = fold_build3_loc (location, COMPONENT_REF, TREE_TYPE (found_field),
5159e4b17023SJohn Marino build_fold_indirect_ref (rhs), found_field,
5160e4b17023SJohn Marino NULL_TREE);
5161e4b17023SJohn Marino ret = build_fold_addr_expr_loc (location, ret);
5162e4b17023SJohn Marino
5163e4b17023SJohn Marino if (found_sub_field)
5164e4b17023SJohn Marino {
5165e4b17023SJohn Marino ret = convert_to_anonymous_field (location, type, ret);
5166e4b17023SJohn Marino gcc_assert (ret != NULL_TREE);
5167e4b17023SJohn Marino }
5168e4b17023SJohn Marino
5169e4b17023SJohn Marino return ret;
5170e4b17023SJohn Marino }
5171e4b17023SJohn Marino
5172e4b17023SJohn Marino /* Convert value RHS to type TYPE as preparation for an assignment to
5173e4b17023SJohn Marino an lvalue of type TYPE. If ORIGTYPE is not NULL_TREE, it is the
5174e4b17023SJohn Marino original type of RHS; this differs from TREE_TYPE (RHS) for enum
5175e4b17023SJohn Marino types. NULL_POINTER_CONSTANT says whether RHS was a null pointer
5176e4b17023SJohn Marino constant before any folding.
5177e4b17023SJohn Marino The real work of conversion is done by `convert'.
5178e4b17023SJohn Marino The purpose of this function is to generate error messages
5179e4b17023SJohn Marino for assignments that are not allowed in C.
5180e4b17023SJohn Marino ERRTYPE says whether it is argument passing, assignment,
5181e4b17023SJohn Marino initialization or return.
5182e4b17023SJohn Marino
5183e4b17023SJohn Marino LOCATION is the location of the RHS.
5184e4b17023SJohn Marino FUNCTION is a tree for the function being called.
5185e4b17023SJohn Marino PARMNUM is the number of the argument, for printing in error messages. */
5186e4b17023SJohn Marino
5187e4b17023SJohn Marino static tree
convert_for_assignment(location_t location,tree type,tree rhs,tree origtype,enum impl_conv errtype,bool null_pointer_constant,tree fundecl,tree function,int parmnum)5188e4b17023SJohn Marino convert_for_assignment (location_t location, tree type, tree rhs,
5189e4b17023SJohn Marino tree origtype, enum impl_conv errtype,
5190e4b17023SJohn Marino bool null_pointer_constant, tree fundecl,
5191e4b17023SJohn Marino tree function, int parmnum)
5192e4b17023SJohn Marino {
5193e4b17023SJohn Marino enum tree_code codel = TREE_CODE (type);
5194e4b17023SJohn Marino tree orig_rhs = rhs;
5195e4b17023SJohn Marino tree rhstype;
5196e4b17023SJohn Marino enum tree_code coder;
5197e4b17023SJohn Marino tree rname = NULL_TREE;
5198e4b17023SJohn Marino bool objc_ok = false;
5199e4b17023SJohn Marino
5200e4b17023SJohn Marino if (errtype == ic_argpass)
5201e4b17023SJohn Marino {
5202e4b17023SJohn Marino tree selector;
5203e4b17023SJohn Marino /* Change pointer to function to the function itself for
5204e4b17023SJohn Marino diagnostics. */
5205e4b17023SJohn Marino if (TREE_CODE (function) == ADDR_EXPR
5206e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
5207e4b17023SJohn Marino function = TREE_OPERAND (function, 0);
5208e4b17023SJohn Marino
5209e4b17023SJohn Marino /* Handle an ObjC selector specially for diagnostics. */
5210e4b17023SJohn Marino selector = objc_message_selector ();
5211e4b17023SJohn Marino rname = function;
5212e4b17023SJohn Marino if (selector && parmnum > 2)
5213e4b17023SJohn Marino {
5214e4b17023SJohn Marino rname = selector;
5215e4b17023SJohn Marino parmnum -= 2;
5216e4b17023SJohn Marino }
5217e4b17023SJohn Marino }
5218e4b17023SJohn Marino
5219e4b17023SJohn Marino /* This macro is used to emit diagnostics to ensure that all format
5220e4b17023SJohn Marino strings are complete sentences, visible to gettext and checked at
5221e4b17023SJohn Marino compile time. */
5222e4b17023SJohn Marino #define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \
5223e4b17023SJohn Marino do { \
5224e4b17023SJohn Marino switch (errtype) \
5225e4b17023SJohn Marino { \
5226e4b17023SJohn Marino case ic_argpass: \
5227e4b17023SJohn Marino if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \
5228e4b17023SJohn Marino inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \
5229e4b17023SJohn Marino ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
5230e4b17023SJohn Marino "expected %qT but argument is of type %qT", \
5231e4b17023SJohn Marino type, rhstype); \
5232e4b17023SJohn Marino break; \
5233e4b17023SJohn Marino case ic_assign: \
5234e4b17023SJohn Marino pedwarn (LOCATION, OPT, AS); \
5235e4b17023SJohn Marino break; \
5236e4b17023SJohn Marino case ic_init: \
5237e4b17023SJohn Marino pedwarn_init (LOCATION, OPT, IN); \
5238e4b17023SJohn Marino break; \
5239e4b17023SJohn Marino case ic_return: \
5240e4b17023SJohn Marino pedwarn (LOCATION, OPT, RE); \
5241e4b17023SJohn Marino break; \
5242e4b17023SJohn Marino default: \
5243e4b17023SJohn Marino gcc_unreachable (); \
5244e4b17023SJohn Marino } \
5245e4b17023SJohn Marino } while (0)
5246e4b17023SJohn Marino
5247e4b17023SJohn Marino /* This macro is used to emit diagnostics to ensure that all format
5248e4b17023SJohn Marino strings are complete sentences, visible to gettext and checked at
5249e4b17023SJohn Marino compile time. It is the same as WARN_FOR_ASSIGNMENT but with an
5250e4b17023SJohn Marino extra parameter to enumerate qualifiers. */
5251e4b17023SJohn Marino
5252e4b17023SJohn Marino #define WARN_FOR_QUALIFIERS(LOCATION, OPT, AR, AS, IN, RE, QUALS) \
5253e4b17023SJohn Marino do { \
5254e4b17023SJohn Marino switch (errtype) \
5255e4b17023SJohn Marino { \
5256e4b17023SJohn Marino case ic_argpass: \
5257e4b17023SJohn Marino if (pedwarn (LOCATION, OPT, AR, parmnum, rname, QUALS)) \
5258e4b17023SJohn Marino inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \
5259e4b17023SJohn Marino ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
5260e4b17023SJohn Marino "expected %qT but argument is of type %qT", \
5261e4b17023SJohn Marino type, rhstype); \
5262e4b17023SJohn Marino break; \
5263e4b17023SJohn Marino case ic_assign: \
5264e4b17023SJohn Marino pedwarn (LOCATION, OPT, AS, QUALS); \
5265e4b17023SJohn Marino break; \
5266e4b17023SJohn Marino case ic_init: \
5267e4b17023SJohn Marino pedwarn (LOCATION, OPT, IN, QUALS); \
5268e4b17023SJohn Marino break; \
5269e4b17023SJohn Marino case ic_return: \
5270e4b17023SJohn Marino pedwarn (LOCATION, OPT, RE, QUALS); \
5271e4b17023SJohn Marino break; \
5272e4b17023SJohn Marino default: \
5273e4b17023SJohn Marino gcc_unreachable (); \
5274e4b17023SJohn Marino } \
5275e4b17023SJohn Marino } while (0)
5276e4b17023SJohn Marino
5277e4b17023SJohn Marino if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR)
5278e4b17023SJohn Marino rhs = TREE_OPERAND (rhs, 0);
5279e4b17023SJohn Marino
5280e4b17023SJohn Marino rhstype = TREE_TYPE (rhs);
5281e4b17023SJohn Marino coder = TREE_CODE (rhstype);
5282e4b17023SJohn Marino
5283e4b17023SJohn Marino if (coder == ERROR_MARK)
5284e4b17023SJohn Marino return error_mark_node;
5285e4b17023SJohn Marino
5286e4b17023SJohn Marino if (c_dialect_objc ())
5287e4b17023SJohn Marino {
5288e4b17023SJohn Marino int parmno;
5289e4b17023SJohn Marino
5290e4b17023SJohn Marino switch (errtype)
5291e4b17023SJohn Marino {
5292e4b17023SJohn Marino case ic_return:
5293e4b17023SJohn Marino parmno = 0;
5294e4b17023SJohn Marino break;
5295e4b17023SJohn Marino
5296e4b17023SJohn Marino case ic_assign:
5297e4b17023SJohn Marino parmno = -1;
5298e4b17023SJohn Marino break;
5299e4b17023SJohn Marino
5300e4b17023SJohn Marino case ic_init:
5301e4b17023SJohn Marino parmno = -2;
5302e4b17023SJohn Marino break;
5303e4b17023SJohn Marino
5304e4b17023SJohn Marino default:
5305e4b17023SJohn Marino parmno = parmnum;
5306e4b17023SJohn Marino break;
5307e4b17023SJohn Marino }
5308e4b17023SJohn Marino
5309e4b17023SJohn Marino objc_ok = objc_compare_types (type, rhstype, parmno, rname);
5310e4b17023SJohn Marino }
5311e4b17023SJohn Marino
5312e4b17023SJohn Marino if (warn_cxx_compat)
5313e4b17023SJohn Marino {
5314e4b17023SJohn Marino tree checktype = origtype != NULL_TREE ? origtype : rhstype;
5315e4b17023SJohn Marino if (checktype != error_mark_node
5316e4b17023SJohn Marino && TREE_CODE (type) == ENUMERAL_TYPE
5317e4b17023SJohn Marino && TYPE_MAIN_VARIANT (checktype) != TYPE_MAIN_VARIANT (type))
5318e4b17023SJohn Marino {
5319e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (input_location, OPT_Wc___compat,
5320e4b17023SJohn Marino G_("enum conversion when passing argument "
5321e4b17023SJohn Marino "%d of %qE is invalid in C++"),
5322e4b17023SJohn Marino G_("enum conversion in assignment is "
5323e4b17023SJohn Marino "invalid in C++"),
5324e4b17023SJohn Marino G_("enum conversion in initialization is "
5325e4b17023SJohn Marino "invalid in C++"),
5326e4b17023SJohn Marino G_("enum conversion in return is "
5327e4b17023SJohn Marino "invalid in C++"));
5328e4b17023SJohn Marino }
5329e4b17023SJohn Marino }
5330e4b17023SJohn Marino
5331e4b17023SJohn Marino if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
5332e4b17023SJohn Marino return rhs;
5333e4b17023SJohn Marino
5334e4b17023SJohn Marino if (coder == VOID_TYPE)
5335e4b17023SJohn Marino {
5336e4b17023SJohn Marino /* Except for passing an argument to an unprototyped function,
5337e4b17023SJohn Marino this is a constraint violation. When passing an argument to
5338e4b17023SJohn Marino an unprototyped function, it is compile-time undefined;
5339e4b17023SJohn Marino making it a constraint in that case was rejected in
5340e4b17023SJohn Marino DR#252. */
5341e4b17023SJohn Marino error_at (location, "void value not ignored as it ought to be");
5342e4b17023SJohn Marino return error_mark_node;
5343e4b17023SJohn Marino }
5344e4b17023SJohn Marino rhs = require_complete_type (rhs);
5345e4b17023SJohn Marino if (rhs == error_mark_node)
5346e4b17023SJohn Marino return error_mark_node;
5347e4b17023SJohn Marino /* A type converts to a reference to it.
5348e4b17023SJohn Marino This code doesn't fully support references, it's just for the
5349e4b17023SJohn Marino special case of va_start and va_copy. */
5350e4b17023SJohn Marino if (codel == REFERENCE_TYPE
5351e4b17023SJohn Marino && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
5352e4b17023SJohn Marino {
5353e4b17023SJohn Marino if (!lvalue_p (rhs))
5354e4b17023SJohn Marino {
5355e4b17023SJohn Marino error_at (location, "cannot pass rvalue to reference parameter");
5356e4b17023SJohn Marino return error_mark_node;
5357e4b17023SJohn Marino }
5358e4b17023SJohn Marino if (!c_mark_addressable (rhs))
5359e4b17023SJohn Marino return error_mark_node;
5360e4b17023SJohn Marino rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
5361e4b17023SJohn Marino SET_EXPR_LOCATION (rhs, location);
5362e4b17023SJohn Marino
5363e4b17023SJohn Marino /* We already know that these two types are compatible, but they
5364e4b17023SJohn Marino may not be exactly identical. In fact, `TREE_TYPE (type)' is
5365e4b17023SJohn Marino likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
5366e4b17023SJohn Marino likely to be va_list, a typedef to __builtin_va_list, which
5367e4b17023SJohn Marino is different enough that it will cause problems later. */
5368e4b17023SJohn Marino if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
5369e4b17023SJohn Marino {
5370e4b17023SJohn Marino rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
5371e4b17023SJohn Marino SET_EXPR_LOCATION (rhs, location);
5372e4b17023SJohn Marino }
5373e4b17023SJohn Marino
5374e4b17023SJohn Marino rhs = build1 (NOP_EXPR, type, rhs);
5375e4b17023SJohn Marino SET_EXPR_LOCATION (rhs, location);
5376e4b17023SJohn Marino return rhs;
5377e4b17023SJohn Marino }
5378e4b17023SJohn Marino /* Some types can interconvert without explicit casts. */
5379e4b17023SJohn Marino else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
5380e4b17023SJohn Marino && vector_types_convertible_p (type, TREE_TYPE (rhs), true))
5381e4b17023SJohn Marino return convert (type, rhs);
5382e4b17023SJohn Marino /* Arithmetic types all interconvert, and enum is treated like int. */
5383e4b17023SJohn Marino else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
5384e4b17023SJohn Marino || codel == FIXED_POINT_TYPE
5385e4b17023SJohn Marino || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
5386e4b17023SJohn Marino || codel == BOOLEAN_TYPE)
5387e4b17023SJohn Marino && (coder == INTEGER_TYPE || coder == REAL_TYPE
5388e4b17023SJohn Marino || coder == FIXED_POINT_TYPE
5389e4b17023SJohn Marino || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
5390e4b17023SJohn Marino || coder == BOOLEAN_TYPE))
5391e4b17023SJohn Marino {
5392e4b17023SJohn Marino tree ret;
5393e4b17023SJohn Marino bool save = in_late_binary_op;
5394e4b17023SJohn Marino if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE)
5395e4b17023SJohn Marino in_late_binary_op = true;
5396e4b17023SJohn Marino ret = convert_and_check (type, orig_rhs);
5397e4b17023SJohn Marino if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE)
5398e4b17023SJohn Marino in_late_binary_op = save;
5399e4b17023SJohn Marino return ret;
5400e4b17023SJohn Marino }
5401e4b17023SJohn Marino
5402e4b17023SJohn Marino /* Aggregates in different TUs might need conversion. */
5403e4b17023SJohn Marino if ((codel == RECORD_TYPE || codel == UNION_TYPE)
5404e4b17023SJohn Marino && codel == coder
5405e4b17023SJohn Marino && comptypes (type, rhstype))
5406e4b17023SJohn Marino return convert_and_check (type, rhs);
5407e4b17023SJohn Marino
5408e4b17023SJohn Marino /* Conversion to a transparent union or record from its member types.
5409e4b17023SJohn Marino This applies only to function arguments. */
5410e4b17023SJohn Marino if (((codel == UNION_TYPE || codel == RECORD_TYPE)
5411e4b17023SJohn Marino && TYPE_TRANSPARENT_AGGR (type))
5412e4b17023SJohn Marino && errtype == ic_argpass)
5413e4b17023SJohn Marino {
5414e4b17023SJohn Marino tree memb, marginal_memb = NULL_TREE;
5415e4b17023SJohn Marino
5416e4b17023SJohn Marino for (memb = TYPE_FIELDS (type); memb ; memb = DECL_CHAIN (memb))
5417e4b17023SJohn Marino {
5418e4b17023SJohn Marino tree memb_type = TREE_TYPE (memb);
5419e4b17023SJohn Marino
5420e4b17023SJohn Marino if (comptypes (TYPE_MAIN_VARIANT (memb_type),
5421e4b17023SJohn Marino TYPE_MAIN_VARIANT (rhstype)))
5422e4b17023SJohn Marino break;
5423e4b17023SJohn Marino
5424e4b17023SJohn Marino if (TREE_CODE (memb_type) != POINTER_TYPE)
5425e4b17023SJohn Marino continue;
5426e4b17023SJohn Marino
5427e4b17023SJohn Marino if (coder == POINTER_TYPE)
5428e4b17023SJohn Marino {
5429e4b17023SJohn Marino tree ttl = TREE_TYPE (memb_type);
5430e4b17023SJohn Marino tree ttr = TREE_TYPE (rhstype);
5431e4b17023SJohn Marino
5432e4b17023SJohn Marino /* Any non-function converts to a [const][volatile] void *
5433e4b17023SJohn Marino and vice versa; otherwise, targets must be the same.
5434e4b17023SJohn Marino Meanwhile, the lhs target must have all the qualifiers of
5435e4b17023SJohn Marino the rhs. */
5436e4b17023SJohn Marino if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
5437e4b17023SJohn Marino || comp_target_types (location, memb_type, rhstype))
5438e4b17023SJohn Marino {
5439e4b17023SJohn Marino /* If this type won't generate any warnings, use it. */
5440e4b17023SJohn Marino if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
5441e4b17023SJohn Marino || ((TREE_CODE (ttr) == FUNCTION_TYPE
5442e4b17023SJohn Marino && TREE_CODE (ttl) == FUNCTION_TYPE)
5443e4b17023SJohn Marino ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
5444e4b17023SJohn Marino == TYPE_QUALS (ttr))
5445e4b17023SJohn Marino : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
5446e4b17023SJohn Marino == TYPE_QUALS (ttl))))
5447e4b17023SJohn Marino break;
5448e4b17023SJohn Marino
5449e4b17023SJohn Marino /* Keep looking for a better type, but remember this one. */
5450e4b17023SJohn Marino if (!marginal_memb)
5451e4b17023SJohn Marino marginal_memb = memb;
5452e4b17023SJohn Marino }
5453e4b17023SJohn Marino }
5454e4b17023SJohn Marino
5455e4b17023SJohn Marino /* Can convert integer zero to any pointer type. */
5456e4b17023SJohn Marino if (null_pointer_constant)
5457e4b17023SJohn Marino {
5458e4b17023SJohn Marino rhs = null_pointer_node;
5459e4b17023SJohn Marino break;
5460e4b17023SJohn Marino }
5461e4b17023SJohn Marino }
5462e4b17023SJohn Marino
5463e4b17023SJohn Marino if (memb || marginal_memb)
5464e4b17023SJohn Marino {
5465e4b17023SJohn Marino if (!memb)
5466e4b17023SJohn Marino {
5467e4b17023SJohn Marino /* We have only a marginally acceptable member type;
5468e4b17023SJohn Marino it needs a warning. */
5469e4b17023SJohn Marino tree ttl = TREE_TYPE (TREE_TYPE (marginal_memb));
5470e4b17023SJohn Marino tree ttr = TREE_TYPE (rhstype);
5471e4b17023SJohn Marino
5472e4b17023SJohn Marino /* Const and volatile mean something different for function
5473e4b17023SJohn Marino types, so the usual warnings are not appropriate. */
5474e4b17023SJohn Marino if (TREE_CODE (ttr) == FUNCTION_TYPE
5475e4b17023SJohn Marino && TREE_CODE (ttl) == FUNCTION_TYPE)
5476e4b17023SJohn Marino {
5477e4b17023SJohn Marino /* Because const and volatile on functions are
5478e4b17023SJohn Marino restrictions that say the function will not do
5479e4b17023SJohn Marino certain things, it is okay to use a const or volatile
5480e4b17023SJohn Marino function where an ordinary one is wanted, but not
5481e4b17023SJohn Marino vice-versa. */
5482e4b17023SJohn Marino if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
5483e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
5484e4b17023SJohn Marino WARN_FOR_QUALIFIERS (location, 0,
5485e4b17023SJohn Marino G_("passing argument %d of %qE "
5486e4b17023SJohn Marino "makes %q#v qualified function "
5487e4b17023SJohn Marino "pointer from unqualified"),
5488e4b17023SJohn Marino G_("assignment makes %q#v qualified "
5489e4b17023SJohn Marino "function pointer from "
5490e4b17023SJohn Marino "unqualified"),
5491e4b17023SJohn Marino G_("initialization makes %q#v qualified "
5492e4b17023SJohn Marino "function pointer from "
5493e4b17023SJohn Marino "unqualified"),
5494e4b17023SJohn Marino G_("return makes %q#v qualified function "
5495e4b17023SJohn Marino "pointer from unqualified"),
5496e4b17023SJohn Marino TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
5497e4b17023SJohn Marino }
5498e4b17023SJohn Marino else if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
5499e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
5500e4b17023SJohn Marino WARN_FOR_QUALIFIERS (location, 0,
5501e4b17023SJohn Marino G_("passing argument %d of %qE discards "
5502e4b17023SJohn Marino "%qv qualifier from pointer target type"),
5503e4b17023SJohn Marino G_("assignment discards %qv qualifier "
5504e4b17023SJohn Marino "from pointer target type"),
5505e4b17023SJohn Marino G_("initialization discards %qv qualifier "
5506e4b17023SJohn Marino "from pointer target type"),
5507e4b17023SJohn Marino G_("return discards %qv qualifier from "
5508e4b17023SJohn Marino "pointer target type"),
5509e4b17023SJohn Marino TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
5510e4b17023SJohn Marino
5511e4b17023SJohn Marino memb = marginal_memb;
5512e4b17023SJohn Marino }
5513e4b17023SJohn Marino
5514e4b17023SJohn Marino if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
5515e4b17023SJohn Marino pedwarn (location, OPT_pedantic,
5516e4b17023SJohn Marino "ISO C prohibits argument conversion to union type");
5517e4b17023SJohn Marino
5518e4b17023SJohn Marino rhs = fold_convert_loc (location, TREE_TYPE (memb), rhs);
5519e4b17023SJohn Marino return build_constructor_single (type, memb, rhs);
5520e4b17023SJohn Marino }
5521e4b17023SJohn Marino }
5522e4b17023SJohn Marino
5523e4b17023SJohn Marino /* Conversions among pointers */
5524e4b17023SJohn Marino else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
5525e4b17023SJohn Marino && (coder == codel))
5526e4b17023SJohn Marino {
5527e4b17023SJohn Marino tree ttl = TREE_TYPE (type);
5528e4b17023SJohn Marino tree ttr = TREE_TYPE (rhstype);
5529e4b17023SJohn Marino tree mvl = ttl;
5530e4b17023SJohn Marino tree mvr = ttr;
5531e4b17023SJohn Marino bool is_opaque_pointer;
5532e4b17023SJohn Marino int target_cmp = 0; /* Cache comp_target_types () result. */
5533e4b17023SJohn Marino addr_space_t asl;
5534e4b17023SJohn Marino addr_space_t asr;
5535e4b17023SJohn Marino
5536e4b17023SJohn Marino if (TREE_CODE (mvl) != ARRAY_TYPE)
5537e4b17023SJohn Marino mvl = TYPE_MAIN_VARIANT (mvl);
5538e4b17023SJohn Marino if (TREE_CODE (mvr) != ARRAY_TYPE)
5539e4b17023SJohn Marino mvr = TYPE_MAIN_VARIANT (mvr);
5540e4b17023SJohn Marino /* Opaque pointers are treated like void pointers. */
5541e4b17023SJohn Marino is_opaque_pointer = vector_targets_convertible_p (ttl, ttr);
5542e4b17023SJohn Marino
5543e4b17023SJohn Marino /* The Plan 9 compiler permits a pointer to a struct to be
5544e4b17023SJohn Marino automatically converted into a pointer to an anonymous field
5545e4b17023SJohn Marino within the struct. */
5546e4b17023SJohn Marino if (flag_plan9_extensions
5547e4b17023SJohn Marino && (TREE_CODE (mvl) == RECORD_TYPE || TREE_CODE(mvl) == UNION_TYPE)
5548e4b17023SJohn Marino && (TREE_CODE (mvr) == RECORD_TYPE || TREE_CODE(mvr) == UNION_TYPE)
5549e4b17023SJohn Marino && mvl != mvr)
5550e4b17023SJohn Marino {
5551e4b17023SJohn Marino tree new_rhs = convert_to_anonymous_field (location, type, rhs);
5552e4b17023SJohn Marino if (new_rhs != NULL_TREE)
5553e4b17023SJohn Marino {
5554e4b17023SJohn Marino rhs = new_rhs;
5555e4b17023SJohn Marino rhstype = TREE_TYPE (rhs);
5556e4b17023SJohn Marino coder = TREE_CODE (rhstype);
5557e4b17023SJohn Marino ttr = TREE_TYPE (rhstype);
5558e4b17023SJohn Marino mvr = TYPE_MAIN_VARIANT (ttr);
5559e4b17023SJohn Marino }
5560e4b17023SJohn Marino }
5561e4b17023SJohn Marino
5562e4b17023SJohn Marino /* C++ does not allow the implicit conversion void* -> T*. However,
5563e4b17023SJohn Marino for the purpose of reducing the number of false positives, we
5564e4b17023SJohn Marino tolerate the special case of
5565e4b17023SJohn Marino
5566e4b17023SJohn Marino int *p = NULL;
5567e4b17023SJohn Marino
5568e4b17023SJohn Marino where NULL is typically defined in C to be '(void *) 0'. */
5569e4b17023SJohn Marino if (VOID_TYPE_P (ttr) && rhs != null_pointer_node && !VOID_TYPE_P (ttl))
5570e4b17023SJohn Marino warning_at (location, OPT_Wc___compat,
5571e4b17023SJohn Marino "request for implicit conversion "
5572e4b17023SJohn Marino "from %qT to %qT not permitted in C++", rhstype, type);
5573e4b17023SJohn Marino
5574e4b17023SJohn Marino /* See if the pointers point to incompatible address spaces. */
5575e4b17023SJohn Marino asl = TYPE_ADDR_SPACE (ttl);
5576e4b17023SJohn Marino asr = TYPE_ADDR_SPACE (ttr);
5577e4b17023SJohn Marino if (!null_pointer_constant_p (rhs)
5578e4b17023SJohn Marino && asr != asl && !targetm.addr_space.subset_p (asr, asl))
5579e4b17023SJohn Marino {
5580e4b17023SJohn Marino switch (errtype)
5581e4b17023SJohn Marino {
5582e4b17023SJohn Marino case ic_argpass:
5583e4b17023SJohn Marino error_at (location, "passing argument %d of %qE from pointer to "
5584e4b17023SJohn Marino "non-enclosed address space", parmnum, rname);
5585e4b17023SJohn Marino break;
5586e4b17023SJohn Marino case ic_assign:
5587e4b17023SJohn Marino error_at (location, "assignment from pointer to "
5588e4b17023SJohn Marino "non-enclosed address space");
5589e4b17023SJohn Marino break;
5590e4b17023SJohn Marino case ic_init:
5591e4b17023SJohn Marino error_at (location, "initialization from pointer to "
5592e4b17023SJohn Marino "non-enclosed address space");
5593e4b17023SJohn Marino break;
5594e4b17023SJohn Marino case ic_return:
5595e4b17023SJohn Marino error_at (location, "return from pointer to "
5596e4b17023SJohn Marino "non-enclosed address space");
5597e4b17023SJohn Marino break;
5598e4b17023SJohn Marino default:
5599e4b17023SJohn Marino gcc_unreachable ();
5600e4b17023SJohn Marino }
5601e4b17023SJohn Marino return error_mark_node;
5602e4b17023SJohn Marino }
5603e4b17023SJohn Marino
5604e4b17023SJohn Marino /* Check if the right-hand side has a format attribute but the
5605e4b17023SJohn Marino left-hand side doesn't. */
5606e4b17023SJohn Marino if (warn_missing_format_attribute
5607e4b17023SJohn Marino && check_missing_format_attribute (type, rhstype))
5608e4b17023SJohn Marino {
5609e4b17023SJohn Marino switch (errtype)
5610e4b17023SJohn Marino {
5611e4b17023SJohn Marino case ic_argpass:
5612e4b17023SJohn Marino warning_at (location, OPT_Wmissing_format_attribute,
5613e4b17023SJohn Marino "argument %d of %qE might be "
5614e4b17023SJohn Marino "a candidate for a format attribute",
5615e4b17023SJohn Marino parmnum, rname);
5616e4b17023SJohn Marino break;
5617e4b17023SJohn Marino case ic_assign:
5618e4b17023SJohn Marino warning_at (location, OPT_Wmissing_format_attribute,
5619e4b17023SJohn Marino "assignment left-hand side might be "
5620e4b17023SJohn Marino "a candidate for a format attribute");
5621e4b17023SJohn Marino break;
5622e4b17023SJohn Marino case ic_init:
5623e4b17023SJohn Marino warning_at (location, OPT_Wmissing_format_attribute,
5624e4b17023SJohn Marino "initialization left-hand side might be "
5625e4b17023SJohn Marino "a candidate for a format attribute");
5626e4b17023SJohn Marino break;
5627e4b17023SJohn Marino case ic_return:
5628e4b17023SJohn Marino warning_at (location, OPT_Wmissing_format_attribute,
5629e4b17023SJohn Marino "return type might be "
5630e4b17023SJohn Marino "a candidate for a format attribute");
5631e4b17023SJohn Marino break;
5632e4b17023SJohn Marino default:
5633e4b17023SJohn Marino gcc_unreachable ();
5634e4b17023SJohn Marino }
5635e4b17023SJohn Marino }
5636e4b17023SJohn Marino
5637e4b17023SJohn Marino /* Any non-function converts to a [const][volatile] void *
5638e4b17023SJohn Marino and vice versa; otherwise, targets must be the same.
5639e4b17023SJohn Marino Meanwhile, the lhs target must have all the qualifiers of the rhs. */
5640e4b17023SJohn Marino if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
5641e4b17023SJohn Marino || (target_cmp = comp_target_types (location, type, rhstype))
5642e4b17023SJohn Marino || is_opaque_pointer
5643e4b17023SJohn Marino || (c_common_unsigned_type (mvl)
5644e4b17023SJohn Marino == c_common_unsigned_type (mvr)))
5645e4b17023SJohn Marino {
5646e4b17023SJohn Marino if (pedantic
5647e4b17023SJohn Marino && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
5648e4b17023SJohn Marino ||
5649e4b17023SJohn Marino (VOID_TYPE_P (ttr)
5650e4b17023SJohn Marino && !null_pointer_constant
5651e4b17023SJohn Marino && TREE_CODE (ttl) == FUNCTION_TYPE)))
5652e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (location, OPT_pedantic,
5653e4b17023SJohn Marino G_("ISO C forbids passing argument %d of "
5654e4b17023SJohn Marino "%qE between function pointer "
5655e4b17023SJohn Marino "and %<void *%>"),
5656e4b17023SJohn Marino G_("ISO C forbids assignment between "
5657e4b17023SJohn Marino "function pointer and %<void *%>"),
5658e4b17023SJohn Marino G_("ISO C forbids initialization between "
5659e4b17023SJohn Marino "function pointer and %<void *%>"),
5660e4b17023SJohn Marino G_("ISO C forbids return between function "
5661e4b17023SJohn Marino "pointer and %<void *%>"));
5662e4b17023SJohn Marino /* Const and volatile mean something different for function types,
5663e4b17023SJohn Marino so the usual warnings are not appropriate. */
5664e4b17023SJohn Marino else if (TREE_CODE (ttr) != FUNCTION_TYPE
5665e4b17023SJohn Marino && TREE_CODE (ttl) != FUNCTION_TYPE)
5666e4b17023SJohn Marino {
5667e4b17023SJohn Marino if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
5668e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
5669e4b17023SJohn Marino {
5670e4b17023SJohn Marino WARN_FOR_QUALIFIERS (location, 0,
5671e4b17023SJohn Marino G_("passing argument %d of %qE discards "
5672e4b17023SJohn Marino "%qv qualifier from pointer target type"),
5673e4b17023SJohn Marino G_("assignment discards %qv qualifier "
5674e4b17023SJohn Marino "from pointer target type"),
5675e4b17023SJohn Marino G_("initialization discards %qv qualifier "
5676e4b17023SJohn Marino "from pointer target type"),
5677e4b17023SJohn Marino G_("return discards %qv qualifier from "
5678e4b17023SJohn Marino "pointer target type"),
5679e4b17023SJohn Marino TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl));
5680e4b17023SJohn Marino }
5681e4b17023SJohn Marino /* If this is not a case of ignoring a mismatch in signedness,
5682e4b17023SJohn Marino no warning. */
5683e4b17023SJohn Marino else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
5684e4b17023SJohn Marino || target_cmp)
5685e4b17023SJohn Marino ;
5686e4b17023SJohn Marino /* If there is a mismatch, do warn. */
5687e4b17023SJohn Marino else if (warn_pointer_sign)
5688e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (location, OPT_Wpointer_sign,
5689e4b17023SJohn Marino G_("pointer targets in passing argument "
5690e4b17023SJohn Marino "%d of %qE differ in signedness"),
5691e4b17023SJohn Marino G_("pointer targets in assignment "
5692e4b17023SJohn Marino "differ in signedness"),
5693e4b17023SJohn Marino G_("pointer targets in initialization "
5694e4b17023SJohn Marino "differ in signedness"),
5695e4b17023SJohn Marino G_("pointer targets in return differ "
5696e4b17023SJohn Marino "in signedness"));
5697e4b17023SJohn Marino }
5698e4b17023SJohn Marino else if (TREE_CODE (ttl) == FUNCTION_TYPE
5699e4b17023SJohn Marino && TREE_CODE (ttr) == FUNCTION_TYPE)
5700e4b17023SJohn Marino {
5701e4b17023SJohn Marino /* Because const and volatile on functions are restrictions
5702e4b17023SJohn Marino that say the function will not do certain things,
5703e4b17023SJohn Marino it is okay to use a const or volatile function
5704e4b17023SJohn Marino where an ordinary one is wanted, but not vice-versa. */
5705e4b17023SJohn Marino if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
5706e4b17023SJohn Marino & ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
5707e4b17023SJohn Marino WARN_FOR_QUALIFIERS (location, 0,
5708e4b17023SJohn Marino G_("passing argument %d of %qE makes "
5709e4b17023SJohn Marino "%q#v qualified function pointer "
5710e4b17023SJohn Marino "from unqualified"),
5711e4b17023SJohn Marino G_("assignment makes %q#v qualified function "
5712e4b17023SJohn Marino "pointer from unqualified"),
5713e4b17023SJohn Marino G_("initialization makes %q#v qualified "
5714e4b17023SJohn Marino "function pointer from unqualified"),
5715e4b17023SJohn Marino G_("return makes %q#v qualified function "
5716e4b17023SJohn Marino "pointer from unqualified"),
5717e4b17023SJohn Marino TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr));
5718e4b17023SJohn Marino }
5719e4b17023SJohn Marino }
5720e4b17023SJohn Marino else
5721e4b17023SJohn Marino /* Avoid warning about the volatile ObjC EH puts on decls. */
5722e4b17023SJohn Marino if (!objc_ok)
5723e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (location, 0,
5724e4b17023SJohn Marino G_("passing argument %d of %qE from "
5725e4b17023SJohn Marino "incompatible pointer type"),
5726e4b17023SJohn Marino G_("assignment from incompatible pointer type"),
5727e4b17023SJohn Marino G_("initialization from incompatible "
5728e4b17023SJohn Marino "pointer type"),
5729e4b17023SJohn Marino G_("return from incompatible pointer type"));
5730e4b17023SJohn Marino
5731e4b17023SJohn Marino return convert (type, rhs);
5732e4b17023SJohn Marino }
5733e4b17023SJohn Marino else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
5734e4b17023SJohn Marino {
5735e4b17023SJohn Marino /* ??? This should not be an error when inlining calls to
5736e4b17023SJohn Marino unprototyped functions. */
5737e4b17023SJohn Marino error_at (location, "invalid use of non-lvalue array");
5738e4b17023SJohn Marino return error_mark_node;
5739e4b17023SJohn Marino }
5740e4b17023SJohn Marino else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
5741e4b17023SJohn Marino {
5742e4b17023SJohn Marino /* An explicit constant 0 can convert to a pointer,
5743e4b17023SJohn Marino or one that results from arithmetic, even including
5744e4b17023SJohn Marino a cast to integer type. */
5745e4b17023SJohn Marino if (!null_pointer_constant)
5746e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (location, 0,
5747e4b17023SJohn Marino G_("passing argument %d of %qE makes "
5748e4b17023SJohn Marino "pointer from integer without a cast"),
5749e4b17023SJohn Marino G_("assignment makes pointer from integer "
5750e4b17023SJohn Marino "without a cast"),
5751e4b17023SJohn Marino G_("initialization makes pointer from "
5752e4b17023SJohn Marino "integer without a cast"),
5753e4b17023SJohn Marino G_("return makes pointer from integer "
5754e4b17023SJohn Marino "without a cast"));
5755e4b17023SJohn Marino
5756e4b17023SJohn Marino return convert (type, rhs);
5757e4b17023SJohn Marino }
5758e4b17023SJohn Marino else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
5759e4b17023SJohn Marino {
5760e4b17023SJohn Marino WARN_FOR_ASSIGNMENT (location, 0,
5761e4b17023SJohn Marino G_("passing argument %d of %qE makes integer "
5762e4b17023SJohn Marino "from pointer without a cast"),
5763e4b17023SJohn Marino G_("assignment makes integer from pointer "
5764e4b17023SJohn Marino "without a cast"),
5765e4b17023SJohn Marino G_("initialization makes integer from pointer "
5766e4b17023SJohn Marino "without a cast"),
5767e4b17023SJohn Marino G_("return makes integer from pointer "
5768e4b17023SJohn Marino "without a cast"));
5769e4b17023SJohn Marino return convert (type, rhs);
5770e4b17023SJohn Marino }
5771e4b17023SJohn Marino else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE)
5772e4b17023SJohn Marino {
5773e4b17023SJohn Marino tree ret;
5774e4b17023SJohn Marino bool save = in_late_binary_op;
5775e4b17023SJohn Marino in_late_binary_op = true;
5776e4b17023SJohn Marino ret = convert (type, rhs);
5777e4b17023SJohn Marino in_late_binary_op = save;
5778e4b17023SJohn Marino return ret;
5779e4b17023SJohn Marino }
5780e4b17023SJohn Marino
5781e4b17023SJohn Marino switch (errtype)
5782e4b17023SJohn Marino {
5783e4b17023SJohn Marino case ic_argpass:
5784e4b17023SJohn Marino error_at (location, "incompatible type for argument %d of %qE", parmnum, rname);
5785e4b17023SJohn Marino inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
5786e4b17023SJohn Marino ? DECL_SOURCE_LOCATION (fundecl) : input_location,
5787e4b17023SJohn Marino "expected %qT but argument is of type %qT", type, rhstype);
5788e4b17023SJohn Marino break;
5789e4b17023SJohn Marino case ic_assign:
5790e4b17023SJohn Marino error_at (location, "incompatible types when assigning to type %qT from "
5791e4b17023SJohn Marino "type %qT", type, rhstype);
5792e4b17023SJohn Marino break;
5793e4b17023SJohn Marino case ic_init:
5794e4b17023SJohn Marino error_at (location,
5795e4b17023SJohn Marino "incompatible types when initializing type %qT using type %qT",
5796e4b17023SJohn Marino type, rhstype);
5797e4b17023SJohn Marino break;
5798e4b17023SJohn Marino case ic_return:
5799e4b17023SJohn Marino error_at (location,
5800e4b17023SJohn Marino "incompatible types when returning type %qT but %qT was "
5801e4b17023SJohn Marino "expected", rhstype, type);
5802e4b17023SJohn Marino break;
5803e4b17023SJohn Marino default:
5804e4b17023SJohn Marino gcc_unreachable ();
5805e4b17023SJohn Marino }
5806e4b17023SJohn Marino
5807e4b17023SJohn Marino return error_mark_node;
5808e4b17023SJohn Marino }
5809e4b17023SJohn Marino
5810e4b17023SJohn Marino /* If VALUE is a compound expr all of whose expressions are constant, then
5811e4b17023SJohn Marino return its value. Otherwise, return error_mark_node.
5812e4b17023SJohn Marino
5813e4b17023SJohn Marino This is for handling COMPOUND_EXPRs as initializer elements
5814e4b17023SJohn Marino which is allowed with a warning when -pedantic is specified. */
5815e4b17023SJohn Marino
5816e4b17023SJohn Marino static tree
valid_compound_expr_initializer(tree value,tree endtype)5817e4b17023SJohn Marino valid_compound_expr_initializer (tree value, tree endtype)
5818e4b17023SJohn Marino {
5819e4b17023SJohn Marino if (TREE_CODE (value) == COMPOUND_EXPR)
5820e4b17023SJohn Marino {
5821e4b17023SJohn Marino if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype)
5822e4b17023SJohn Marino == error_mark_node)
5823e4b17023SJohn Marino return error_mark_node;
5824e4b17023SJohn Marino return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
5825e4b17023SJohn Marino endtype);
5826e4b17023SJohn Marino }
5827e4b17023SJohn Marino else if (!initializer_constant_valid_p (value, endtype))
5828e4b17023SJohn Marino return error_mark_node;
5829e4b17023SJohn Marino else
5830e4b17023SJohn Marino return value;
5831e4b17023SJohn Marino }
5832e4b17023SJohn Marino
5833e4b17023SJohn Marino /* Perform appropriate conversions on the initial value of a variable,
5834e4b17023SJohn Marino store it in the declaration DECL,
5835e4b17023SJohn Marino and print any error messages that are appropriate.
5836e4b17023SJohn Marino If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
5837e4b17023SJohn Marino If the init is invalid, store an ERROR_MARK.
5838e4b17023SJohn Marino
5839e4b17023SJohn Marino INIT_LOC is the location of the initial value. */
5840e4b17023SJohn Marino
5841e4b17023SJohn Marino void
store_init_value(location_t init_loc,tree decl,tree init,tree origtype)5842e4b17023SJohn Marino store_init_value (location_t init_loc, tree decl, tree init, tree origtype)
5843e4b17023SJohn Marino {
5844e4b17023SJohn Marino tree value, type;
5845e4b17023SJohn Marino bool npc = false;
5846e4b17023SJohn Marino
5847e4b17023SJohn Marino /* If variable's type was invalidly declared, just ignore it. */
5848e4b17023SJohn Marino
5849e4b17023SJohn Marino type = TREE_TYPE (decl);
5850e4b17023SJohn Marino if (TREE_CODE (type) == ERROR_MARK)
5851e4b17023SJohn Marino return;
5852e4b17023SJohn Marino
5853e4b17023SJohn Marino /* Digest the specified initializer into an expression. */
5854e4b17023SJohn Marino
5855e4b17023SJohn Marino if (init)
5856e4b17023SJohn Marino npc = null_pointer_constant_p (init);
5857e4b17023SJohn Marino value = digest_init (init_loc, type, init, origtype, npc,
5858e4b17023SJohn Marino true, TREE_STATIC (decl));
5859e4b17023SJohn Marino
5860e4b17023SJohn Marino /* Store the expression if valid; else report error. */
5861e4b17023SJohn Marino
5862e4b17023SJohn Marino if (!in_system_header
5863e4b17023SJohn Marino && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && !TREE_STATIC (decl))
5864e4b17023SJohn Marino warning (OPT_Wtraditional, "traditional C rejects automatic "
5865e4b17023SJohn Marino "aggregate initialization");
5866e4b17023SJohn Marino
5867e4b17023SJohn Marino DECL_INITIAL (decl) = value;
5868e4b17023SJohn Marino
5869e4b17023SJohn Marino /* ANSI wants warnings about out-of-range constant initializers. */
5870e4b17023SJohn Marino STRIP_TYPE_NOPS (value);
5871e4b17023SJohn Marino if (TREE_STATIC (decl))
5872e4b17023SJohn Marino constant_expression_warning (value);
5873e4b17023SJohn Marino
5874e4b17023SJohn Marino /* Check if we need to set array size from compound literal size. */
5875e4b17023SJohn Marino if (TREE_CODE (type) == ARRAY_TYPE
5876e4b17023SJohn Marino && TYPE_DOMAIN (type) == 0
5877e4b17023SJohn Marino && value != error_mark_node)
5878e4b17023SJohn Marino {
5879e4b17023SJohn Marino tree inside_init = init;
5880e4b17023SJohn Marino
5881e4b17023SJohn Marino STRIP_TYPE_NOPS (inside_init);
5882e4b17023SJohn Marino inside_init = fold (inside_init);
5883e4b17023SJohn Marino
5884e4b17023SJohn Marino if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
5885e4b17023SJohn Marino {
5886e4b17023SJohn Marino tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
5887e4b17023SJohn Marino
5888e4b17023SJohn Marino if (TYPE_DOMAIN (TREE_TYPE (cldecl)))
5889e4b17023SJohn Marino {
5890e4b17023SJohn Marino /* For int foo[] = (int [3]){1}; we need to set array size
5891e4b17023SJohn Marino now since later on array initializer will be just the
5892e4b17023SJohn Marino brace enclosed list of the compound literal. */
5893e4b17023SJohn Marino tree etype = strip_array_types (TREE_TYPE (decl));
5894e4b17023SJohn Marino type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
5895e4b17023SJohn Marino TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl));
5896e4b17023SJohn Marino layout_type (type);
5897e4b17023SJohn Marino layout_decl (cldecl, 0);
5898e4b17023SJohn Marino TREE_TYPE (decl)
5899e4b17023SJohn Marino = c_build_qualified_type (type, TYPE_QUALS (etype));
5900e4b17023SJohn Marino }
5901e4b17023SJohn Marino }
5902e4b17023SJohn Marino }
5903e4b17023SJohn Marino }
5904e4b17023SJohn Marino
5905e4b17023SJohn Marino /* Methods for storing and printing names for error messages. */
5906e4b17023SJohn Marino
5907e4b17023SJohn Marino /* Implement a spelling stack that allows components of a name to be pushed
5908e4b17023SJohn Marino and popped. Each element on the stack is this structure. */
5909e4b17023SJohn Marino
5910e4b17023SJohn Marino struct spelling
5911e4b17023SJohn Marino {
5912e4b17023SJohn Marino int kind;
5913e4b17023SJohn Marino union
5914e4b17023SJohn Marino {
5915e4b17023SJohn Marino unsigned HOST_WIDE_INT i;
5916e4b17023SJohn Marino const char *s;
5917e4b17023SJohn Marino } u;
5918e4b17023SJohn Marino };
5919e4b17023SJohn Marino
5920e4b17023SJohn Marino #define SPELLING_STRING 1
5921e4b17023SJohn Marino #define SPELLING_MEMBER 2
5922e4b17023SJohn Marino #define SPELLING_BOUNDS 3
5923e4b17023SJohn Marino
5924e4b17023SJohn Marino static struct spelling *spelling; /* Next stack element (unused). */
5925e4b17023SJohn Marino static struct spelling *spelling_base; /* Spelling stack base. */
5926e4b17023SJohn Marino static int spelling_size; /* Size of the spelling stack. */
5927e4b17023SJohn Marino
5928e4b17023SJohn Marino /* Macros to save and restore the spelling stack around push_... functions.
5929e4b17023SJohn Marino Alternative to SAVE_SPELLING_STACK. */
5930e4b17023SJohn Marino
5931e4b17023SJohn Marino #define SPELLING_DEPTH() (spelling - spelling_base)
5932e4b17023SJohn Marino #define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH))
5933e4b17023SJohn Marino
5934e4b17023SJohn Marino /* Push an element on the spelling stack with type KIND and assign VALUE
5935e4b17023SJohn Marino to MEMBER. */
5936e4b17023SJohn Marino
5937e4b17023SJohn Marino #define PUSH_SPELLING(KIND, VALUE, MEMBER) \
5938e4b17023SJohn Marino { \
5939e4b17023SJohn Marino int depth = SPELLING_DEPTH (); \
5940e4b17023SJohn Marino \
5941e4b17023SJohn Marino if (depth >= spelling_size) \
5942e4b17023SJohn Marino { \
5943e4b17023SJohn Marino spelling_size += 10; \
5944e4b17023SJohn Marino spelling_base = XRESIZEVEC (struct spelling, spelling_base, \
5945e4b17023SJohn Marino spelling_size); \
5946e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (depth); \
5947e4b17023SJohn Marino } \
5948e4b17023SJohn Marino \
5949e4b17023SJohn Marino spelling->kind = (KIND); \
5950e4b17023SJohn Marino spelling->MEMBER = (VALUE); \
5951e4b17023SJohn Marino spelling++; \
5952e4b17023SJohn Marino }
5953e4b17023SJohn Marino
5954e4b17023SJohn Marino /* Push STRING on the stack. Printed literally. */
5955e4b17023SJohn Marino
5956e4b17023SJohn Marino static void
push_string(const char * string)5957e4b17023SJohn Marino push_string (const char *string)
5958e4b17023SJohn Marino {
5959e4b17023SJohn Marino PUSH_SPELLING (SPELLING_STRING, string, u.s);
5960e4b17023SJohn Marino }
5961e4b17023SJohn Marino
5962e4b17023SJohn Marino /* Push a member name on the stack. Printed as '.' STRING. */
5963e4b17023SJohn Marino
5964e4b17023SJohn Marino static void
push_member_name(tree decl)5965e4b17023SJohn Marino push_member_name (tree decl)
5966e4b17023SJohn Marino {
5967e4b17023SJohn Marino const char *const string
5968e4b17023SJohn Marino = (DECL_NAME (decl)
5969e4b17023SJohn Marino ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (decl)))
5970e4b17023SJohn Marino : _("<anonymous>"));
5971e4b17023SJohn Marino PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
5972e4b17023SJohn Marino }
5973e4b17023SJohn Marino
5974e4b17023SJohn Marino /* Push an array bounds on the stack. Printed as [BOUNDS]. */
5975e4b17023SJohn Marino
5976e4b17023SJohn Marino static void
push_array_bounds(unsigned HOST_WIDE_INT bounds)5977e4b17023SJohn Marino push_array_bounds (unsigned HOST_WIDE_INT bounds)
5978e4b17023SJohn Marino {
5979e4b17023SJohn Marino PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
5980e4b17023SJohn Marino }
5981e4b17023SJohn Marino
5982e4b17023SJohn Marino /* Compute the maximum size in bytes of the printed spelling. */
5983e4b17023SJohn Marino
5984e4b17023SJohn Marino static int
spelling_length(void)5985e4b17023SJohn Marino spelling_length (void)
5986e4b17023SJohn Marino {
5987e4b17023SJohn Marino int size = 0;
5988e4b17023SJohn Marino struct spelling *p;
5989e4b17023SJohn Marino
5990e4b17023SJohn Marino for (p = spelling_base; p < spelling; p++)
5991e4b17023SJohn Marino {
5992e4b17023SJohn Marino if (p->kind == SPELLING_BOUNDS)
5993e4b17023SJohn Marino size += 25;
5994e4b17023SJohn Marino else
5995e4b17023SJohn Marino size += strlen (p->u.s) + 1;
5996e4b17023SJohn Marino }
5997e4b17023SJohn Marino
5998e4b17023SJohn Marino return size;
5999e4b17023SJohn Marino }
6000e4b17023SJohn Marino
6001e4b17023SJohn Marino /* Print the spelling to BUFFER and return it. */
6002e4b17023SJohn Marino
6003e4b17023SJohn Marino static char *
print_spelling(char * buffer)6004e4b17023SJohn Marino print_spelling (char *buffer)
6005e4b17023SJohn Marino {
6006e4b17023SJohn Marino char *d = buffer;
6007e4b17023SJohn Marino struct spelling *p;
6008e4b17023SJohn Marino
6009e4b17023SJohn Marino for (p = spelling_base; p < spelling; p++)
6010e4b17023SJohn Marino if (p->kind == SPELLING_BOUNDS)
6011e4b17023SJohn Marino {
6012e4b17023SJohn Marino sprintf (d, "[" HOST_WIDE_INT_PRINT_UNSIGNED "]", p->u.i);
6013e4b17023SJohn Marino d += strlen (d);
6014e4b17023SJohn Marino }
6015e4b17023SJohn Marino else
6016e4b17023SJohn Marino {
6017e4b17023SJohn Marino const char *s;
6018e4b17023SJohn Marino if (p->kind == SPELLING_MEMBER)
6019e4b17023SJohn Marino *d++ = '.';
6020e4b17023SJohn Marino for (s = p->u.s; (*d = *s++); d++)
6021e4b17023SJohn Marino ;
6022e4b17023SJohn Marino }
6023e4b17023SJohn Marino *d++ = '\0';
6024e4b17023SJohn Marino return buffer;
6025e4b17023SJohn Marino }
6026e4b17023SJohn Marino
6027e4b17023SJohn Marino /* Issue an error message for a bad initializer component.
6028e4b17023SJohn Marino GMSGID identifies the message.
6029e4b17023SJohn Marino The component name is taken from the spelling stack. */
6030e4b17023SJohn Marino
6031e4b17023SJohn Marino void
error_init(const char * gmsgid)6032e4b17023SJohn Marino error_init (const char *gmsgid)
6033e4b17023SJohn Marino {
6034e4b17023SJohn Marino char *ofwhat;
6035e4b17023SJohn Marino
6036e4b17023SJohn Marino /* The gmsgid may be a format string with %< and %>. */
6037e4b17023SJohn Marino error (gmsgid);
6038e4b17023SJohn Marino ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
6039e4b17023SJohn Marino if (*ofwhat)
6040e4b17023SJohn Marino error ("(near initialization for %qs)", ofwhat);
6041e4b17023SJohn Marino }
6042e4b17023SJohn Marino
6043e4b17023SJohn Marino /* Issue a pedantic warning for a bad initializer component. OPT is
6044e4b17023SJohn Marino the option OPT_* (from options.h) controlling this warning or 0 if
6045e4b17023SJohn Marino it is unconditionally given. GMSGID identifies the message. The
6046e4b17023SJohn Marino component name is taken from the spelling stack. */
6047e4b17023SJohn Marino
6048e4b17023SJohn Marino void
pedwarn_init(location_t location,int opt,const char * gmsgid)6049e4b17023SJohn Marino pedwarn_init (location_t location, int opt, const char *gmsgid)
6050e4b17023SJohn Marino {
6051e4b17023SJohn Marino char *ofwhat;
6052e4b17023SJohn Marino
6053e4b17023SJohn Marino /* The gmsgid may be a format string with %< and %>. */
6054e4b17023SJohn Marino pedwarn (location, opt, gmsgid);
6055e4b17023SJohn Marino ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
6056e4b17023SJohn Marino if (*ofwhat)
6057e4b17023SJohn Marino pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
6058e4b17023SJohn Marino }
6059e4b17023SJohn Marino
6060e4b17023SJohn Marino /* Issue a warning for a bad initializer component.
6061e4b17023SJohn Marino
6062e4b17023SJohn Marino OPT is the OPT_W* value corresponding to the warning option that
6063e4b17023SJohn Marino controls this warning. GMSGID identifies the message. The
6064e4b17023SJohn Marino component name is taken from the spelling stack. */
6065e4b17023SJohn Marino
6066e4b17023SJohn Marino static void
warning_init(int opt,const char * gmsgid)6067e4b17023SJohn Marino warning_init (int opt, const char *gmsgid)
6068e4b17023SJohn Marino {
6069e4b17023SJohn Marino char *ofwhat;
6070e4b17023SJohn Marino
6071e4b17023SJohn Marino /* The gmsgid may be a format string with %< and %>. */
6072e4b17023SJohn Marino warning (opt, gmsgid);
6073e4b17023SJohn Marino ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
6074e4b17023SJohn Marino if (*ofwhat)
6075e4b17023SJohn Marino warning (opt, "(near initialization for %qs)", ofwhat);
6076e4b17023SJohn Marino }
6077e4b17023SJohn Marino
6078e4b17023SJohn Marino /* If TYPE is an array type and EXPR is a parenthesized string
6079e4b17023SJohn Marino constant, warn if pedantic that EXPR is being used to initialize an
6080e4b17023SJohn Marino object of type TYPE. */
6081e4b17023SJohn Marino
6082e4b17023SJohn Marino void
maybe_warn_string_init(tree type,struct c_expr expr)6083e4b17023SJohn Marino maybe_warn_string_init (tree type, struct c_expr expr)
6084e4b17023SJohn Marino {
6085e4b17023SJohn Marino if (pedantic
6086e4b17023SJohn Marino && TREE_CODE (type) == ARRAY_TYPE
6087e4b17023SJohn Marino && TREE_CODE (expr.value) == STRING_CST
6088e4b17023SJohn Marino && expr.original_code != STRING_CST)
6089e4b17023SJohn Marino pedwarn_init (input_location, OPT_pedantic,
6090e4b17023SJohn Marino "array initialized from parenthesized string constant");
6091e4b17023SJohn Marino }
6092e4b17023SJohn Marino
6093e4b17023SJohn Marino /* Digest the parser output INIT as an initializer for type TYPE.
6094e4b17023SJohn Marino Return a C expression of type TYPE to represent the initial value.
6095e4b17023SJohn Marino
6096e4b17023SJohn Marino If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
6097e4b17023SJohn Marino
6098e4b17023SJohn Marino NULL_POINTER_CONSTANT is true if INIT is a null pointer constant.
6099e4b17023SJohn Marino
6100e4b17023SJohn Marino If INIT is a string constant, STRICT_STRING is true if it is
6101e4b17023SJohn Marino unparenthesized or we should not warn here for it being parenthesized.
6102e4b17023SJohn Marino For other types of INIT, STRICT_STRING is not used.
6103e4b17023SJohn Marino
6104e4b17023SJohn Marino INIT_LOC is the location of the INIT.
6105e4b17023SJohn Marino
6106e4b17023SJohn Marino REQUIRE_CONSTANT requests an error if non-constant initializers or
6107e4b17023SJohn Marino elements are seen. */
6108e4b17023SJohn Marino
6109e4b17023SJohn Marino static tree
digest_init(location_t init_loc,tree type,tree init,tree origtype,bool null_pointer_constant,bool strict_string,int require_constant)6110e4b17023SJohn Marino digest_init (location_t init_loc, tree type, tree init, tree origtype,
6111e4b17023SJohn Marino bool null_pointer_constant, bool strict_string,
6112e4b17023SJohn Marino int require_constant)
6113e4b17023SJohn Marino {
6114e4b17023SJohn Marino enum tree_code code = TREE_CODE (type);
6115e4b17023SJohn Marino tree inside_init = init;
6116e4b17023SJohn Marino tree semantic_type = NULL_TREE;
6117e4b17023SJohn Marino bool maybe_const = true;
6118e4b17023SJohn Marino
6119e4b17023SJohn Marino if (type == error_mark_node
6120e4b17023SJohn Marino || !init
6121e4b17023SJohn Marino || init == error_mark_node
6122e4b17023SJohn Marino || TREE_TYPE (init) == error_mark_node)
6123e4b17023SJohn Marino return error_mark_node;
6124e4b17023SJohn Marino
6125e4b17023SJohn Marino STRIP_TYPE_NOPS (inside_init);
6126e4b17023SJohn Marino
6127e4b17023SJohn Marino if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR)
6128e4b17023SJohn Marino {
6129e4b17023SJohn Marino semantic_type = TREE_TYPE (inside_init);
6130e4b17023SJohn Marino inside_init = TREE_OPERAND (inside_init, 0);
6131e4b17023SJohn Marino }
6132e4b17023SJohn Marino inside_init = c_fully_fold (inside_init, require_constant, &maybe_const);
6133e4b17023SJohn Marino inside_init = decl_constant_value_for_optimization (inside_init);
6134e4b17023SJohn Marino
6135e4b17023SJohn Marino /* Initialization of an array of chars from a string constant
6136e4b17023SJohn Marino optionally enclosed in braces. */
6137e4b17023SJohn Marino
6138e4b17023SJohn Marino if (code == ARRAY_TYPE && inside_init
6139e4b17023SJohn Marino && TREE_CODE (inside_init) == STRING_CST)
6140e4b17023SJohn Marino {
6141e4b17023SJohn Marino tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
6142e4b17023SJohn Marino /* Note that an array could be both an array of character type
6143e4b17023SJohn Marino and an array of wchar_t if wchar_t is signed char or unsigned
6144e4b17023SJohn Marino char. */
6145e4b17023SJohn Marino bool char_array = (typ1 == char_type_node
6146e4b17023SJohn Marino || typ1 == signed_char_type_node
6147e4b17023SJohn Marino || typ1 == unsigned_char_type_node);
6148e4b17023SJohn Marino bool wchar_array = !!comptypes (typ1, wchar_type_node);
6149e4b17023SJohn Marino bool char16_array = !!comptypes (typ1, char16_type_node);
6150e4b17023SJohn Marino bool char32_array = !!comptypes (typ1, char32_type_node);
6151e4b17023SJohn Marino
6152e4b17023SJohn Marino if (char_array || wchar_array || char16_array || char32_array)
6153e4b17023SJohn Marino {
6154e4b17023SJohn Marino struct c_expr expr;
6155e4b17023SJohn Marino tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
6156e4b17023SJohn Marino expr.value = inside_init;
6157e4b17023SJohn Marino expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
6158e4b17023SJohn Marino expr.original_type = NULL;
6159e4b17023SJohn Marino maybe_warn_string_init (type, expr);
6160e4b17023SJohn Marino
6161e4b17023SJohn Marino if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
6162e4b17023SJohn Marino pedwarn_init (init_loc, OPT_pedantic,
6163e4b17023SJohn Marino "initialization of a flexible array member");
6164e4b17023SJohn Marino
6165e4b17023SJohn Marino if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
6166e4b17023SJohn Marino TYPE_MAIN_VARIANT (type)))
6167e4b17023SJohn Marino return inside_init;
6168e4b17023SJohn Marino
6169e4b17023SJohn Marino if (char_array)
6170e4b17023SJohn Marino {
6171e4b17023SJohn Marino if (typ2 != char_type_node)
6172e4b17023SJohn Marino {
6173e4b17023SJohn Marino error_init ("char-array initialized from wide string");
6174e4b17023SJohn Marino return error_mark_node;
6175e4b17023SJohn Marino }
6176e4b17023SJohn Marino }
6177e4b17023SJohn Marino else
6178e4b17023SJohn Marino {
6179e4b17023SJohn Marino if (typ2 == char_type_node)
6180e4b17023SJohn Marino {
6181e4b17023SJohn Marino error_init ("wide character array initialized from non-wide "
6182e4b17023SJohn Marino "string");
6183e4b17023SJohn Marino return error_mark_node;
6184e4b17023SJohn Marino }
6185e4b17023SJohn Marino else if (!comptypes(typ1, typ2))
6186e4b17023SJohn Marino {
6187e4b17023SJohn Marino error_init ("wide character array initialized from "
6188e4b17023SJohn Marino "incompatible wide string");
6189e4b17023SJohn Marino return error_mark_node;
6190e4b17023SJohn Marino }
6191e4b17023SJohn Marino }
6192e4b17023SJohn Marino
6193e4b17023SJohn Marino TREE_TYPE (inside_init) = type;
6194e4b17023SJohn Marino if (TYPE_DOMAIN (type) != 0
6195e4b17023SJohn Marino && TYPE_SIZE (type) != 0
6196e4b17023SJohn Marino && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
6197e4b17023SJohn Marino {
6198e4b17023SJohn Marino unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init);
6199e4b17023SJohn Marino
6200e4b17023SJohn Marino /* Subtract the size of a single (possibly wide) character
6201e4b17023SJohn Marino because it's ok to ignore the terminating null char
6202e4b17023SJohn Marino that is counted in the length of the constant. */
6203e4b17023SJohn Marino if (0 > compare_tree_int (TYPE_SIZE_UNIT (type),
6204e4b17023SJohn Marino (len
6205e4b17023SJohn Marino - (TYPE_PRECISION (typ1)
6206e4b17023SJohn Marino / BITS_PER_UNIT))))
6207e4b17023SJohn Marino pedwarn_init (init_loc, 0,
6208e4b17023SJohn Marino ("initializer-string for array of chars "
6209e4b17023SJohn Marino "is too long"));
6210e4b17023SJohn Marino else if (warn_cxx_compat
6211e4b17023SJohn Marino && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), len))
6212e4b17023SJohn Marino warning_at (init_loc, OPT_Wc___compat,
6213e4b17023SJohn Marino ("initializer-string for array chars "
6214e4b17023SJohn Marino "is too long for C++"));
6215e4b17023SJohn Marino }
6216e4b17023SJohn Marino
6217e4b17023SJohn Marino return inside_init;
6218e4b17023SJohn Marino }
6219e4b17023SJohn Marino else if (INTEGRAL_TYPE_P (typ1))
6220e4b17023SJohn Marino {
6221e4b17023SJohn Marino error_init ("array of inappropriate type initialized "
6222e4b17023SJohn Marino "from string constant");
6223e4b17023SJohn Marino return error_mark_node;
6224e4b17023SJohn Marino }
6225e4b17023SJohn Marino }
6226e4b17023SJohn Marino
6227e4b17023SJohn Marino /* Build a VECTOR_CST from a *constant* vector constructor. If the
6228e4b17023SJohn Marino vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
6229e4b17023SJohn Marino below and handle as a constructor. */
6230e4b17023SJohn Marino if (code == VECTOR_TYPE
6231e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE
6232e4b17023SJohn Marino && vector_types_convertible_p (TREE_TYPE (inside_init), type, true)
6233e4b17023SJohn Marino && TREE_CONSTANT (inside_init))
6234e4b17023SJohn Marino {
6235e4b17023SJohn Marino if (TREE_CODE (inside_init) == VECTOR_CST
6236e4b17023SJohn Marino && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
6237e4b17023SJohn Marino TYPE_MAIN_VARIANT (type)))
6238e4b17023SJohn Marino return inside_init;
6239e4b17023SJohn Marino
6240e4b17023SJohn Marino if (TREE_CODE (inside_init) == CONSTRUCTOR)
6241e4b17023SJohn Marino {
6242e4b17023SJohn Marino unsigned HOST_WIDE_INT ix;
6243e4b17023SJohn Marino tree value;
6244e4b17023SJohn Marino bool constant_p = true;
6245e4b17023SJohn Marino
6246e4b17023SJohn Marino /* Iterate through elements and check if all constructor
6247e4b17023SJohn Marino elements are *_CSTs. */
6248e4b17023SJohn Marino FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value)
6249e4b17023SJohn Marino if (!CONSTANT_CLASS_P (value))
6250e4b17023SJohn Marino {
6251e4b17023SJohn Marino constant_p = false;
6252e4b17023SJohn Marino break;
6253e4b17023SJohn Marino }
6254e4b17023SJohn Marino
6255e4b17023SJohn Marino if (constant_p)
6256e4b17023SJohn Marino return build_vector_from_ctor (type,
6257e4b17023SJohn Marino CONSTRUCTOR_ELTS (inside_init));
6258e4b17023SJohn Marino }
6259e4b17023SJohn Marino }
6260e4b17023SJohn Marino
6261e4b17023SJohn Marino if (warn_sequence_point)
6262e4b17023SJohn Marino verify_sequence_points (inside_init);
6263e4b17023SJohn Marino
6264e4b17023SJohn Marino /* Any type can be initialized
6265e4b17023SJohn Marino from an expression of the same type, optionally with braces. */
6266e4b17023SJohn Marino
6267e4b17023SJohn Marino if (inside_init && TREE_TYPE (inside_init) != 0
6268e4b17023SJohn Marino && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
6269e4b17023SJohn Marino TYPE_MAIN_VARIANT (type))
6270e4b17023SJohn Marino || (code == ARRAY_TYPE
6271e4b17023SJohn Marino && comptypes (TREE_TYPE (inside_init), type))
6272e4b17023SJohn Marino || (code == VECTOR_TYPE
6273e4b17023SJohn Marino && comptypes (TREE_TYPE (inside_init), type))
6274e4b17023SJohn Marino || (code == POINTER_TYPE
6275e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
6276e4b17023SJohn Marino && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
6277e4b17023SJohn Marino TREE_TYPE (type)))))
6278e4b17023SJohn Marino {
6279e4b17023SJohn Marino if (code == POINTER_TYPE)
6280e4b17023SJohn Marino {
6281e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE)
6282e4b17023SJohn Marino {
6283e4b17023SJohn Marino if (TREE_CODE (inside_init) == STRING_CST
6284e4b17023SJohn Marino || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
6285e4b17023SJohn Marino inside_init = array_to_pointer_conversion
6286e4b17023SJohn Marino (init_loc, inside_init);
6287e4b17023SJohn Marino else
6288e4b17023SJohn Marino {
6289e4b17023SJohn Marino error_init ("invalid use of non-lvalue array");
6290e4b17023SJohn Marino return error_mark_node;
6291e4b17023SJohn Marino }
6292e4b17023SJohn Marino }
6293e4b17023SJohn Marino }
6294e4b17023SJohn Marino
6295e4b17023SJohn Marino if (code == VECTOR_TYPE)
6296e4b17023SJohn Marino /* Although the types are compatible, we may require a
6297e4b17023SJohn Marino conversion. */
6298e4b17023SJohn Marino inside_init = convert (type, inside_init);
6299e4b17023SJohn Marino
6300e4b17023SJohn Marino if (require_constant
6301e4b17023SJohn Marino && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
6302e4b17023SJohn Marino {
6303e4b17023SJohn Marino /* As an extension, allow initializing objects with static storage
6304e4b17023SJohn Marino duration with compound literals (which are then treated just as
6305e4b17023SJohn Marino the brace enclosed list they contain). Also allow this for
6306e4b17023SJohn Marino vectors, as we can only assign them with compound literals. */
6307*8172914bSzrj if (flag_isoc99 && code != VECTOR_TYPE)
6308*8172914bSzrj pedwarn_init (init_loc, OPT_pedantic, "initializer element "
6309*8172914bSzrj "is not constant");
6310e4b17023SJohn Marino tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
6311e4b17023SJohn Marino inside_init = DECL_INITIAL (decl);
6312e4b17023SJohn Marino }
6313e4b17023SJohn Marino
6314e4b17023SJohn Marino if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
6315e4b17023SJohn Marino && TREE_CODE (inside_init) != CONSTRUCTOR)
6316e4b17023SJohn Marino {
6317e4b17023SJohn Marino error_init ("array initialized from non-constant array expression");
6318e4b17023SJohn Marino return error_mark_node;
6319e4b17023SJohn Marino }
6320e4b17023SJohn Marino
6321e4b17023SJohn Marino /* Compound expressions can only occur here if -pedantic or
6322e4b17023SJohn Marino -pedantic-errors is specified. In the later case, we always want
6323e4b17023SJohn Marino an error. In the former case, we simply want a warning. */
6324e4b17023SJohn Marino if (require_constant && pedantic
6325e4b17023SJohn Marino && TREE_CODE (inside_init) == COMPOUND_EXPR)
6326e4b17023SJohn Marino {
6327e4b17023SJohn Marino inside_init
6328e4b17023SJohn Marino = valid_compound_expr_initializer (inside_init,
6329e4b17023SJohn Marino TREE_TYPE (inside_init));
6330e4b17023SJohn Marino if (inside_init == error_mark_node)
6331e4b17023SJohn Marino error_init ("initializer element is not constant");
6332e4b17023SJohn Marino else
6333e4b17023SJohn Marino pedwarn_init (init_loc, OPT_pedantic,
6334e4b17023SJohn Marino "initializer element is not constant");
6335e4b17023SJohn Marino if (flag_pedantic_errors)
6336e4b17023SJohn Marino inside_init = error_mark_node;
6337e4b17023SJohn Marino }
6338e4b17023SJohn Marino else if (require_constant
6339e4b17023SJohn Marino && !initializer_constant_valid_p (inside_init,
6340e4b17023SJohn Marino TREE_TYPE (inside_init)))
6341e4b17023SJohn Marino {
6342e4b17023SJohn Marino error_init ("initializer element is not constant");
6343e4b17023SJohn Marino inside_init = error_mark_node;
6344e4b17023SJohn Marino }
6345e4b17023SJohn Marino else if (require_constant && !maybe_const)
6346e4b17023SJohn Marino pedwarn_init (init_loc, 0,
6347e4b17023SJohn Marino "initializer element is not a constant expression");
6348e4b17023SJohn Marino
6349e4b17023SJohn Marino /* Added to enable additional -Wmissing-format-attribute warnings. */
6350e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
6351e4b17023SJohn Marino inside_init = convert_for_assignment (init_loc, type, inside_init,
6352e4b17023SJohn Marino origtype,
6353e4b17023SJohn Marino ic_init, null_pointer_constant,
6354e4b17023SJohn Marino NULL_TREE, NULL_TREE, 0);
6355e4b17023SJohn Marino return inside_init;
6356e4b17023SJohn Marino }
6357e4b17023SJohn Marino
6358e4b17023SJohn Marino /* Handle scalar types, including conversions. */
6359e4b17023SJohn Marino
6360e4b17023SJohn Marino if (code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE
6361e4b17023SJohn Marino || code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
6362e4b17023SJohn Marino || code == COMPLEX_TYPE || code == VECTOR_TYPE)
6363e4b17023SJohn Marino {
6364e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
6365e4b17023SJohn Marino && (TREE_CODE (init) == STRING_CST
6366e4b17023SJohn Marino || TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
6367e4b17023SJohn Marino inside_init = init = array_to_pointer_conversion (init_loc, init);
6368e4b17023SJohn Marino if (semantic_type)
6369e4b17023SJohn Marino inside_init = build1 (EXCESS_PRECISION_EXPR, semantic_type,
6370e4b17023SJohn Marino inside_init);
6371e4b17023SJohn Marino inside_init
6372e4b17023SJohn Marino = convert_for_assignment (init_loc, type, inside_init, origtype,
6373e4b17023SJohn Marino ic_init, null_pointer_constant,
6374e4b17023SJohn Marino NULL_TREE, NULL_TREE, 0);
6375e4b17023SJohn Marino
6376e4b17023SJohn Marino /* Check to see if we have already given an error message. */
6377e4b17023SJohn Marino if (inside_init == error_mark_node)
6378e4b17023SJohn Marino ;
6379e4b17023SJohn Marino else if (require_constant && !TREE_CONSTANT (inside_init))
6380e4b17023SJohn Marino {
6381e4b17023SJohn Marino error_init ("initializer element is not constant");
6382e4b17023SJohn Marino inside_init = error_mark_node;
6383e4b17023SJohn Marino }
6384e4b17023SJohn Marino else if (require_constant
6385e4b17023SJohn Marino && !initializer_constant_valid_p (inside_init,
6386e4b17023SJohn Marino TREE_TYPE (inside_init)))
6387e4b17023SJohn Marino {
6388e4b17023SJohn Marino error_init ("initializer element is not computable at load time");
6389e4b17023SJohn Marino inside_init = error_mark_node;
6390e4b17023SJohn Marino }
6391e4b17023SJohn Marino else if (require_constant && !maybe_const)
6392e4b17023SJohn Marino pedwarn_init (init_loc, 0,
6393e4b17023SJohn Marino "initializer element is not a constant expression");
6394e4b17023SJohn Marino
6395e4b17023SJohn Marino return inside_init;
6396e4b17023SJohn Marino }
6397e4b17023SJohn Marino
6398e4b17023SJohn Marino /* Come here only for records and arrays. */
6399e4b17023SJohn Marino
6400e4b17023SJohn Marino if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
6401e4b17023SJohn Marino {
6402e4b17023SJohn Marino error_init ("variable-sized object may not be initialized");
6403e4b17023SJohn Marino return error_mark_node;
6404e4b17023SJohn Marino }
6405e4b17023SJohn Marino
6406e4b17023SJohn Marino error_init ("invalid initializer");
6407e4b17023SJohn Marino return error_mark_node;
6408e4b17023SJohn Marino }
6409e4b17023SJohn Marino
6410e4b17023SJohn Marino /* Handle initializers that use braces. */
6411e4b17023SJohn Marino
6412e4b17023SJohn Marino /* Type of object we are accumulating a constructor for.
6413e4b17023SJohn Marino This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE. */
6414e4b17023SJohn Marino static tree constructor_type;
6415e4b17023SJohn Marino
6416e4b17023SJohn Marino /* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields
6417e4b17023SJohn Marino left to fill. */
6418e4b17023SJohn Marino static tree constructor_fields;
6419e4b17023SJohn Marino
6420e4b17023SJohn Marino /* For an ARRAY_TYPE, this is the specified index
6421e4b17023SJohn Marino at which to store the next element we get. */
6422e4b17023SJohn Marino static tree constructor_index;
6423e4b17023SJohn Marino
6424e4b17023SJohn Marino /* For an ARRAY_TYPE, this is the maximum index. */
6425e4b17023SJohn Marino static tree constructor_max_index;
6426e4b17023SJohn Marino
6427e4b17023SJohn Marino /* For a RECORD_TYPE, this is the first field not yet written out. */
6428e4b17023SJohn Marino static tree constructor_unfilled_fields;
6429e4b17023SJohn Marino
6430e4b17023SJohn Marino /* For an ARRAY_TYPE, this is the index of the first element
6431e4b17023SJohn Marino not yet written out. */
6432e4b17023SJohn Marino static tree constructor_unfilled_index;
6433e4b17023SJohn Marino
6434e4b17023SJohn Marino /* In a RECORD_TYPE, the byte index of the next consecutive field.
6435e4b17023SJohn Marino This is so we can generate gaps between fields, when appropriate. */
6436e4b17023SJohn Marino static tree constructor_bit_index;
6437e4b17023SJohn Marino
6438e4b17023SJohn Marino /* If we are saving up the elements rather than allocating them,
6439e4b17023SJohn Marino this is the list of elements so far (in reverse order,
6440e4b17023SJohn Marino most recent first). */
6441e4b17023SJohn Marino static VEC(constructor_elt,gc) *constructor_elements;
6442e4b17023SJohn Marino
6443e4b17023SJohn Marino /* 1 if constructor should be incrementally stored into a constructor chain,
6444e4b17023SJohn Marino 0 if all the elements should be kept in AVL tree. */
6445e4b17023SJohn Marino static int constructor_incremental;
6446e4b17023SJohn Marino
6447e4b17023SJohn Marino /* 1 if so far this constructor's elements are all compile-time constants. */
6448e4b17023SJohn Marino static int constructor_constant;
6449e4b17023SJohn Marino
6450e4b17023SJohn Marino /* 1 if so far this constructor's elements are all valid address constants. */
6451e4b17023SJohn Marino static int constructor_simple;
6452e4b17023SJohn Marino
6453e4b17023SJohn Marino /* 1 if this constructor has an element that cannot be part of a
6454e4b17023SJohn Marino constant expression. */
6455e4b17023SJohn Marino static int constructor_nonconst;
6456e4b17023SJohn Marino
6457e4b17023SJohn Marino /* 1 if this constructor is erroneous so far. */
6458e4b17023SJohn Marino static int constructor_erroneous;
6459e4b17023SJohn Marino
6460e4b17023SJohn Marino /* Structure for managing pending initializer elements, organized as an
6461e4b17023SJohn Marino AVL tree. */
6462e4b17023SJohn Marino
6463e4b17023SJohn Marino struct init_node
6464e4b17023SJohn Marino {
6465e4b17023SJohn Marino struct init_node *left, *right;
6466e4b17023SJohn Marino struct init_node *parent;
6467e4b17023SJohn Marino int balance;
6468e4b17023SJohn Marino tree purpose;
6469e4b17023SJohn Marino tree value;
6470e4b17023SJohn Marino tree origtype;
6471e4b17023SJohn Marino };
6472e4b17023SJohn Marino
6473e4b17023SJohn Marino /* Tree of pending elements at this constructor level.
6474e4b17023SJohn Marino These are elements encountered out of order
6475e4b17023SJohn Marino which belong at places we haven't reached yet in actually
6476e4b17023SJohn Marino writing the output.
6477e4b17023SJohn Marino Will never hold tree nodes across GC runs. */
6478e4b17023SJohn Marino static struct init_node *constructor_pending_elts;
6479e4b17023SJohn Marino
6480e4b17023SJohn Marino /* The SPELLING_DEPTH of this constructor. */
6481e4b17023SJohn Marino static int constructor_depth;
6482e4b17023SJohn Marino
6483e4b17023SJohn Marino /* DECL node for which an initializer is being read.
6484e4b17023SJohn Marino 0 means we are reading a constructor expression
6485e4b17023SJohn Marino such as (struct foo) {...}. */
6486e4b17023SJohn Marino static tree constructor_decl;
6487e4b17023SJohn Marino
6488e4b17023SJohn Marino /* Nonzero if this is an initializer for a top-level decl. */
6489e4b17023SJohn Marino static int constructor_top_level;
6490e4b17023SJohn Marino
6491e4b17023SJohn Marino /* Nonzero if there were any member designators in this initializer. */
6492e4b17023SJohn Marino static int constructor_designated;
6493e4b17023SJohn Marino
6494e4b17023SJohn Marino /* Nesting depth of designator list. */
6495e4b17023SJohn Marino static int designator_depth;
6496e4b17023SJohn Marino
6497e4b17023SJohn Marino /* Nonzero if there were diagnosed errors in this designator list. */
6498e4b17023SJohn Marino static int designator_erroneous;
6499e4b17023SJohn Marino
6500e4b17023SJohn Marino
6501e4b17023SJohn Marino /* This stack has a level for each implicit or explicit level of
6502e4b17023SJohn Marino structuring in the initializer, including the outermost one. It
6503e4b17023SJohn Marino saves the values of most of the variables above. */
6504e4b17023SJohn Marino
6505e4b17023SJohn Marino struct constructor_range_stack;
6506e4b17023SJohn Marino
6507e4b17023SJohn Marino struct constructor_stack
6508e4b17023SJohn Marino {
6509e4b17023SJohn Marino struct constructor_stack *next;
6510e4b17023SJohn Marino tree type;
6511e4b17023SJohn Marino tree fields;
6512e4b17023SJohn Marino tree index;
6513e4b17023SJohn Marino tree max_index;
6514e4b17023SJohn Marino tree unfilled_index;
6515e4b17023SJohn Marino tree unfilled_fields;
6516e4b17023SJohn Marino tree bit_index;
6517e4b17023SJohn Marino VEC(constructor_elt,gc) *elements;
6518e4b17023SJohn Marino struct init_node *pending_elts;
6519e4b17023SJohn Marino int offset;
6520e4b17023SJohn Marino int depth;
6521e4b17023SJohn Marino /* If value nonzero, this value should replace the entire
6522e4b17023SJohn Marino constructor at this level. */
6523e4b17023SJohn Marino struct c_expr replacement_value;
6524e4b17023SJohn Marino struct constructor_range_stack *range_stack;
6525e4b17023SJohn Marino char constant;
6526e4b17023SJohn Marino char simple;
6527e4b17023SJohn Marino char nonconst;
6528e4b17023SJohn Marino char implicit;
6529e4b17023SJohn Marino char erroneous;
6530e4b17023SJohn Marino char outer;
6531e4b17023SJohn Marino char incremental;
6532e4b17023SJohn Marino char designated;
6533e4b17023SJohn Marino };
6534e4b17023SJohn Marino
6535e4b17023SJohn Marino static struct constructor_stack *constructor_stack;
6536e4b17023SJohn Marino
6537e4b17023SJohn Marino /* This stack represents designators from some range designator up to
6538e4b17023SJohn Marino the last designator in the list. */
6539e4b17023SJohn Marino
6540e4b17023SJohn Marino struct constructor_range_stack
6541e4b17023SJohn Marino {
6542e4b17023SJohn Marino struct constructor_range_stack *next, *prev;
6543e4b17023SJohn Marino struct constructor_stack *stack;
6544e4b17023SJohn Marino tree range_start;
6545e4b17023SJohn Marino tree index;
6546e4b17023SJohn Marino tree range_end;
6547e4b17023SJohn Marino tree fields;
6548e4b17023SJohn Marino };
6549e4b17023SJohn Marino
6550e4b17023SJohn Marino static struct constructor_range_stack *constructor_range_stack;
6551e4b17023SJohn Marino
6552e4b17023SJohn Marino /* This stack records separate initializers that are nested.
6553e4b17023SJohn Marino Nested initializers can't happen in ANSI C, but GNU C allows them
6554e4b17023SJohn Marino in cases like { ... (struct foo) { ... } ... }. */
6555e4b17023SJohn Marino
6556e4b17023SJohn Marino struct initializer_stack
6557e4b17023SJohn Marino {
6558e4b17023SJohn Marino struct initializer_stack *next;
6559e4b17023SJohn Marino tree decl;
6560e4b17023SJohn Marino struct constructor_stack *constructor_stack;
6561e4b17023SJohn Marino struct constructor_range_stack *constructor_range_stack;
6562e4b17023SJohn Marino VEC(constructor_elt,gc) *elements;
6563e4b17023SJohn Marino struct spelling *spelling;
6564e4b17023SJohn Marino struct spelling *spelling_base;
6565e4b17023SJohn Marino int spelling_size;
6566e4b17023SJohn Marino char top_level;
6567e4b17023SJohn Marino char require_constant_value;
6568e4b17023SJohn Marino char require_constant_elements;
6569e4b17023SJohn Marino };
6570e4b17023SJohn Marino
6571e4b17023SJohn Marino static struct initializer_stack *initializer_stack;
6572e4b17023SJohn Marino
6573e4b17023SJohn Marino /* Prepare to parse and output the initializer for variable DECL. */
6574e4b17023SJohn Marino
6575e4b17023SJohn Marino void
start_init(tree decl,tree asmspec_tree ATTRIBUTE_UNUSED,int top_level)6576e4b17023SJohn Marino start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level)
6577e4b17023SJohn Marino {
6578e4b17023SJohn Marino const char *locus;
6579e4b17023SJohn Marino struct initializer_stack *p = XNEW (struct initializer_stack);
6580e4b17023SJohn Marino
6581e4b17023SJohn Marino p->decl = constructor_decl;
6582e4b17023SJohn Marino p->require_constant_value = require_constant_value;
6583e4b17023SJohn Marino p->require_constant_elements = require_constant_elements;
6584e4b17023SJohn Marino p->constructor_stack = constructor_stack;
6585e4b17023SJohn Marino p->constructor_range_stack = constructor_range_stack;
6586e4b17023SJohn Marino p->elements = constructor_elements;
6587e4b17023SJohn Marino p->spelling = spelling;
6588e4b17023SJohn Marino p->spelling_base = spelling_base;
6589e4b17023SJohn Marino p->spelling_size = spelling_size;
6590e4b17023SJohn Marino p->top_level = constructor_top_level;
6591e4b17023SJohn Marino p->next = initializer_stack;
6592e4b17023SJohn Marino initializer_stack = p;
6593e4b17023SJohn Marino
6594e4b17023SJohn Marino constructor_decl = decl;
6595e4b17023SJohn Marino constructor_designated = 0;
6596e4b17023SJohn Marino constructor_top_level = top_level;
6597e4b17023SJohn Marino
6598e4b17023SJohn Marino if (decl != 0 && decl != error_mark_node)
6599e4b17023SJohn Marino {
6600e4b17023SJohn Marino require_constant_value = TREE_STATIC (decl);
6601e4b17023SJohn Marino require_constant_elements
6602e4b17023SJohn Marino = ((TREE_STATIC (decl) || (pedantic && !flag_isoc99))
6603e4b17023SJohn Marino /* For a scalar, you can always use any value to initialize,
6604e4b17023SJohn Marino even within braces. */
6605e4b17023SJohn Marino && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
6606e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
6607e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
6608e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
6609e4b17023SJohn Marino locus = identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (decl)));
6610e4b17023SJohn Marino }
6611e4b17023SJohn Marino else
6612e4b17023SJohn Marino {
6613e4b17023SJohn Marino require_constant_value = 0;
6614e4b17023SJohn Marino require_constant_elements = 0;
6615e4b17023SJohn Marino locus = _("(anonymous)");
6616e4b17023SJohn Marino }
6617e4b17023SJohn Marino
6618e4b17023SJohn Marino constructor_stack = 0;
6619e4b17023SJohn Marino constructor_range_stack = 0;
6620e4b17023SJohn Marino
6621e4b17023SJohn Marino missing_braces_mentioned = 0;
6622e4b17023SJohn Marino
6623e4b17023SJohn Marino spelling_base = 0;
6624e4b17023SJohn Marino spelling_size = 0;
6625e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (0);
6626e4b17023SJohn Marino
6627e4b17023SJohn Marino if (locus)
6628e4b17023SJohn Marino push_string (locus);
6629e4b17023SJohn Marino }
6630e4b17023SJohn Marino
6631e4b17023SJohn Marino void
finish_init(void)6632e4b17023SJohn Marino finish_init (void)
6633e4b17023SJohn Marino {
6634e4b17023SJohn Marino struct initializer_stack *p = initializer_stack;
6635e4b17023SJohn Marino
6636e4b17023SJohn Marino /* Free the whole constructor stack of this initializer. */
6637e4b17023SJohn Marino while (constructor_stack)
6638e4b17023SJohn Marino {
6639e4b17023SJohn Marino struct constructor_stack *q = constructor_stack;
6640e4b17023SJohn Marino constructor_stack = q->next;
6641e4b17023SJohn Marino free (q);
6642e4b17023SJohn Marino }
6643e4b17023SJohn Marino
6644e4b17023SJohn Marino gcc_assert (!constructor_range_stack);
6645e4b17023SJohn Marino
6646e4b17023SJohn Marino /* Pop back to the data of the outer initializer (if any). */
6647e4b17023SJohn Marino free (spelling_base);
6648e4b17023SJohn Marino
6649e4b17023SJohn Marino constructor_decl = p->decl;
6650e4b17023SJohn Marino require_constant_value = p->require_constant_value;
6651e4b17023SJohn Marino require_constant_elements = p->require_constant_elements;
6652e4b17023SJohn Marino constructor_stack = p->constructor_stack;
6653e4b17023SJohn Marino constructor_range_stack = p->constructor_range_stack;
6654e4b17023SJohn Marino constructor_elements = p->elements;
6655e4b17023SJohn Marino spelling = p->spelling;
6656e4b17023SJohn Marino spelling_base = p->spelling_base;
6657e4b17023SJohn Marino spelling_size = p->spelling_size;
6658e4b17023SJohn Marino constructor_top_level = p->top_level;
6659e4b17023SJohn Marino initializer_stack = p->next;
6660e4b17023SJohn Marino free (p);
6661e4b17023SJohn Marino }
6662e4b17023SJohn Marino
6663e4b17023SJohn Marino /* Call here when we see the initializer is surrounded by braces.
6664e4b17023SJohn Marino This is instead of a call to push_init_level;
6665e4b17023SJohn Marino it is matched by a call to pop_init_level.
6666e4b17023SJohn Marino
6667e4b17023SJohn Marino TYPE is the type to initialize, for a constructor expression.
6668e4b17023SJohn Marino For an initializer for a decl, TYPE is zero. */
6669e4b17023SJohn Marino
6670e4b17023SJohn Marino void
really_start_incremental_init(tree type)6671e4b17023SJohn Marino really_start_incremental_init (tree type)
6672e4b17023SJohn Marino {
6673e4b17023SJohn Marino struct constructor_stack *p = XNEW (struct constructor_stack);
6674e4b17023SJohn Marino
6675e4b17023SJohn Marino if (type == 0)
6676e4b17023SJohn Marino type = TREE_TYPE (constructor_decl);
6677e4b17023SJohn Marino
6678e4b17023SJohn Marino if (TREE_CODE (type) == VECTOR_TYPE
6679e4b17023SJohn Marino && TYPE_VECTOR_OPAQUE (type))
6680e4b17023SJohn Marino error ("opaque vector types cannot be initialized");
6681e4b17023SJohn Marino
6682e4b17023SJohn Marino p->type = constructor_type;
6683e4b17023SJohn Marino p->fields = constructor_fields;
6684e4b17023SJohn Marino p->index = constructor_index;
6685e4b17023SJohn Marino p->max_index = constructor_max_index;
6686e4b17023SJohn Marino p->unfilled_index = constructor_unfilled_index;
6687e4b17023SJohn Marino p->unfilled_fields = constructor_unfilled_fields;
6688e4b17023SJohn Marino p->bit_index = constructor_bit_index;
6689e4b17023SJohn Marino p->elements = constructor_elements;
6690e4b17023SJohn Marino p->constant = constructor_constant;
6691e4b17023SJohn Marino p->simple = constructor_simple;
6692e4b17023SJohn Marino p->nonconst = constructor_nonconst;
6693e4b17023SJohn Marino p->erroneous = constructor_erroneous;
6694e4b17023SJohn Marino p->pending_elts = constructor_pending_elts;
6695e4b17023SJohn Marino p->depth = constructor_depth;
6696e4b17023SJohn Marino p->replacement_value.value = 0;
6697e4b17023SJohn Marino p->replacement_value.original_code = ERROR_MARK;
6698e4b17023SJohn Marino p->replacement_value.original_type = NULL;
6699e4b17023SJohn Marino p->implicit = 0;
6700e4b17023SJohn Marino p->range_stack = 0;
6701e4b17023SJohn Marino p->outer = 0;
6702e4b17023SJohn Marino p->incremental = constructor_incremental;
6703e4b17023SJohn Marino p->designated = constructor_designated;
6704e4b17023SJohn Marino p->next = 0;
6705e4b17023SJohn Marino constructor_stack = p;
6706e4b17023SJohn Marino
6707e4b17023SJohn Marino constructor_constant = 1;
6708e4b17023SJohn Marino constructor_simple = 1;
6709e4b17023SJohn Marino constructor_nonconst = 0;
6710e4b17023SJohn Marino constructor_depth = SPELLING_DEPTH ();
6711e4b17023SJohn Marino constructor_elements = 0;
6712e4b17023SJohn Marino constructor_pending_elts = 0;
6713e4b17023SJohn Marino constructor_type = type;
6714e4b17023SJohn Marino constructor_incremental = 1;
6715e4b17023SJohn Marino constructor_designated = 0;
6716e4b17023SJohn Marino designator_depth = 0;
6717e4b17023SJohn Marino designator_erroneous = 0;
6718e4b17023SJohn Marino
6719e4b17023SJohn Marino if (TREE_CODE (constructor_type) == RECORD_TYPE
6720e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
6721e4b17023SJohn Marino {
6722e4b17023SJohn Marino constructor_fields = TYPE_FIELDS (constructor_type);
6723e4b17023SJohn Marino /* Skip any nameless bit fields at the beginning. */
6724e4b17023SJohn Marino while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
6725e4b17023SJohn Marino && DECL_NAME (constructor_fields) == 0)
6726e4b17023SJohn Marino constructor_fields = DECL_CHAIN (constructor_fields);
6727e4b17023SJohn Marino
6728e4b17023SJohn Marino constructor_unfilled_fields = constructor_fields;
6729e4b17023SJohn Marino constructor_bit_index = bitsize_zero_node;
6730e4b17023SJohn Marino }
6731e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6732e4b17023SJohn Marino {
6733e4b17023SJohn Marino if (TYPE_DOMAIN (constructor_type))
6734e4b17023SJohn Marino {
6735e4b17023SJohn Marino constructor_max_index
6736e4b17023SJohn Marino = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
6737e4b17023SJohn Marino
6738e4b17023SJohn Marino /* Detect non-empty initializations of zero-length arrays. */
6739e4b17023SJohn Marino if (constructor_max_index == NULL_TREE
6740e4b17023SJohn Marino && TYPE_SIZE (constructor_type))
6741e4b17023SJohn Marino constructor_max_index = integer_minus_one_node;
6742e4b17023SJohn Marino
6743e4b17023SJohn Marino /* constructor_max_index needs to be an INTEGER_CST. Attempts
6744e4b17023SJohn Marino to initialize VLAs will cause a proper error; avoid tree
6745e4b17023SJohn Marino checking errors as well by setting a safe value. */
6746e4b17023SJohn Marino if (constructor_max_index
6747e4b17023SJohn Marino && TREE_CODE (constructor_max_index) != INTEGER_CST)
6748e4b17023SJohn Marino constructor_max_index = integer_minus_one_node;
6749e4b17023SJohn Marino
6750e4b17023SJohn Marino constructor_index
6751e4b17023SJohn Marino = convert (bitsizetype,
6752e4b17023SJohn Marino TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
6753e4b17023SJohn Marino }
6754e4b17023SJohn Marino else
6755e4b17023SJohn Marino {
6756e4b17023SJohn Marino constructor_index = bitsize_zero_node;
6757e4b17023SJohn Marino constructor_max_index = NULL_TREE;
6758e4b17023SJohn Marino }
6759e4b17023SJohn Marino
6760e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
6761e4b17023SJohn Marino }
6762e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
6763e4b17023SJohn Marino {
6764e4b17023SJohn Marino /* Vectors are like simple fixed-size arrays. */
6765e4b17023SJohn Marino constructor_max_index =
6766e4b17023SJohn Marino bitsize_int (TYPE_VECTOR_SUBPARTS (constructor_type) - 1);
6767e4b17023SJohn Marino constructor_index = bitsize_zero_node;
6768e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
6769e4b17023SJohn Marino }
6770e4b17023SJohn Marino else
6771e4b17023SJohn Marino {
6772e4b17023SJohn Marino /* Handle the case of int x = {5}; */
6773e4b17023SJohn Marino constructor_fields = constructor_type;
6774e4b17023SJohn Marino constructor_unfilled_fields = constructor_type;
6775e4b17023SJohn Marino }
6776e4b17023SJohn Marino }
6777e4b17023SJohn Marino
6778e4b17023SJohn Marino /* Push down into a subobject, for initialization.
6779e4b17023SJohn Marino If this is for an explicit set of braces, IMPLICIT is 0.
6780e4b17023SJohn Marino If it is because the next element belongs at a lower level,
6781e4b17023SJohn Marino IMPLICIT is 1 (or 2 if the push is because of designator list). */
6782e4b17023SJohn Marino
6783e4b17023SJohn Marino void
push_init_level(int implicit,struct obstack * braced_init_obstack)6784e4b17023SJohn Marino push_init_level (int implicit, struct obstack * braced_init_obstack)
6785e4b17023SJohn Marino {
6786e4b17023SJohn Marino struct constructor_stack *p;
6787e4b17023SJohn Marino tree value = NULL_TREE;
6788e4b17023SJohn Marino
6789e4b17023SJohn Marino /* If we've exhausted any levels that didn't have braces,
6790e4b17023SJohn Marino pop them now. If implicit == 1, this will have been done in
6791e4b17023SJohn Marino process_init_element; do not repeat it here because in the case
6792e4b17023SJohn Marino of excess initializers for an empty aggregate this leads to an
6793e4b17023SJohn Marino infinite cycle of popping a level and immediately recreating
6794e4b17023SJohn Marino it. */
6795e4b17023SJohn Marino if (implicit != 1)
6796e4b17023SJohn Marino {
6797e4b17023SJohn Marino while (constructor_stack->implicit)
6798e4b17023SJohn Marino {
6799e4b17023SJohn Marino if ((TREE_CODE (constructor_type) == RECORD_TYPE
6800e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
6801e4b17023SJohn Marino && constructor_fields == 0)
6802e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
6803e4b17023SJohn Marino true, braced_init_obstack);
6804e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE
6805e4b17023SJohn Marino && constructor_max_index
6806e4b17023SJohn Marino && tree_int_cst_lt (constructor_max_index,
6807e4b17023SJohn Marino constructor_index))
6808e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
6809e4b17023SJohn Marino true, braced_init_obstack);
6810e4b17023SJohn Marino else
6811e4b17023SJohn Marino break;
6812e4b17023SJohn Marino }
6813e4b17023SJohn Marino }
6814e4b17023SJohn Marino
6815e4b17023SJohn Marino /* Unless this is an explicit brace, we need to preserve previous
6816e4b17023SJohn Marino content if any. */
6817e4b17023SJohn Marino if (implicit)
6818e4b17023SJohn Marino {
6819e4b17023SJohn Marino if ((TREE_CODE (constructor_type) == RECORD_TYPE
6820e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
6821e4b17023SJohn Marino && constructor_fields)
6822e4b17023SJohn Marino value = find_init_member (constructor_fields, braced_init_obstack);
6823e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6824e4b17023SJohn Marino value = find_init_member (constructor_index, braced_init_obstack);
6825e4b17023SJohn Marino }
6826e4b17023SJohn Marino
6827e4b17023SJohn Marino p = XNEW (struct constructor_stack);
6828e4b17023SJohn Marino p->type = constructor_type;
6829e4b17023SJohn Marino p->fields = constructor_fields;
6830e4b17023SJohn Marino p->index = constructor_index;
6831e4b17023SJohn Marino p->max_index = constructor_max_index;
6832e4b17023SJohn Marino p->unfilled_index = constructor_unfilled_index;
6833e4b17023SJohn Marino p->unfilled_fields = constructor_unfilled_fields;
6834e4b17023SJohn Marino p->bit_index = constructor_bit_index;
6835e4b17023SJohn Marino p->elements = constructor_elements;
6836e4b17023SJohn Marino p->constant = constructor_constant;
6837e4b17023SJohn Marino p->simple = constructor_simple;
6838e4b17023SJohn Marino p->nonconst = constructor_nonconst;
6839e4b17023SJohn Marino p->erroneous = constructor_erroneous;
6840e4b17023SJohn Marino p->pending_elts = constructor_pending_elts;
6841e4b17023SJohn Marino p->depth = constructor_depth;
6842e4b17023SJohn Marino p->replacement_value.value = 0;
6843e4b17023SJohn Marino p->replacement_value.original_code = ERROR_MARK;
6844e4b17023SJohn Marino p->replacement_value.original_type = NULL;
6845e4b17023SJohn Marino p->implicit = implicit;
6846e4b17023SJohn Marino p->outer = 0;
6847e4b17023SJohn Marino p->incremental = constructor_incremental;
6848e4b17023SJohn Marino p->designated = constructor_designated;
6849e4b17023SJohn Marino p->next = constructor_stack;
6850e4b17023SJohn Marino p->range_stack = 0;
6851e4b17023SJohn Marino constructor_stack = p;
6852e4b17023SJohn Marino
6853e4b17023SJohn Marino constructor_constant = 1;
6854e4b17023SJohn Marino constructor_simple = 1;
6855e4b17023SJohn Marino constructor_nonconst = 0;
6856e4b17023SJohn Marino constructor_depth = SPELLING_DEPTH ();
6857e4b17023SJohn Marino constructor_elements = 0;
6858e4b17023SJohn Marino constructor_incremental = 1;
6859e4b17023SJohn Marino constructor_designated = 0;
6860e4b17023SJohn Marino constructor_pending_elts = 0;
6861e4b17023SJohn Marino if (!implicit)
6862e4b17023SJohn Marino {
6863e4b17023SJohn Marino p->range_stack = constructor_range_stack;
6864e4b17023SJohn Marino constructor_range_stack = 0;
6865e4b17023SJohn Marino designator_depth = 0;
6866e4b17023SJohn Marino designator_erroneous = 0;
6867e4b17023SJohn Marino }
6868e4b17023SJohn Marino
6869e4b17023SJohn Marino /* Don't die if an entire brace-pair level is superfluous
6870e4b17023SJohn Marino in the containing level. */
6871e4b17023SJohn Marino if (constructor_type == 0)
6872e4b17023SJohn Marino ;
6873e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == RECORD_TYPE
6874e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
6875e4b17023SJohn Marino {
6876e4b17023SJohn Marino /* Don't die if there are extra init elts at the end. */
6877e4b17023SJohn Marino if (constructor_fields == 0)
6878e4b17023SJohn Marino constructor_type = 0;
6879e4b17023SJohn Marino else
6880e4b17023SJohn Marino {
6881e4b17023SJohn Marino constructor_type = TREE_TYPE (constructor_fields);
6882e4b17023SJohn Marino push_member_name (constructor_fields);
6883e4b17023SJohn Marino constructor_depth++;
6884e4b17023SJohn Marino }
6885e4b17023SJohn Marino }
6886e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6887e4b17023SJohn Marino {
6888e4b17023SJohn Marino constructor_type = TREE_TYPE (constructor_type);
6889e4b17023SJohn Marino push_array_bounds (tree_low_cst (constructor_index, 1));
6890e4b17023SJohn Marino constructor_depth++;
6891e4b17023SJohn Marino }
6892e4b17023SJohn Marino
6893e4b17023SJohn Marino if (constructor_type == 0)
6894e4b17023SJohn Marino {
6895e4b17023SJohn Marino error_init ("extra brace group at end of initializer");
6896e4b17023SJohn Marino constructor_fields = 0;
6897e4b17023SJohn Marino constructor_unfilled_fields = 0;
6898e4b17023SJohn Marino return;
6899e4b17023SJohn Marino }
6900e4b17023SJohn Marino
6901e4b17023SJohn Marino if (value && TREE_CODE (value) == CONSTRUCTOR)
6902e4b17023SJohn Marino {
6903e4b17023SJohn Marino constructor_constant = TREE_CONSTANT (value);
6904e4b17023SJohn Marino constructor_simple = TREE_STATIC (value);
6905e4b17023SJohn Marino constructor_nonconst = CONSTRUCTOR_NON_CONST (value);
6906e4b17023SJohn Marino constructor_elements = CONSTRUCTOR_ELTS (value);
6907e4b17023SJohn Marino if (!VEC_empty (constructor_elt, constructor_elements)
6908e4b17023SJohn Marino && (TREE_CODE (constructor_type) == RECORD_TYPE
6909e4b17023SJohn Marino || TREE_CODE (constructor_type) == ARRAY_TYPE))
6910e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
6911e4b17023SJohn Marino }
6912e4b17023SJohn Marino
6913e4b17023SJohn Marino if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
6914e4b17023SJohn Marino {
6915e4b17023SJohn Marino missing_braces_mentioned = 1;
6916e4b17023SJohn Marino warning_init (OPT_Wmissing_braces, "missing braces around initializer");
6917e4b17023SJohn Marino }
6918e4b17023SJohn Marino
6919e4b17023SJohn Marino if (TREE_CODE (constructor_type) == RECORD_TYPE
6920e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
6921e4b17023SJohn Marino {
6922e4b17023SJohn Marino constructor_fields = TYPE_FIELDS (constructor_type);
6923e4b17023SJohn Marino /* Skip any nameless bit fields at the beginning. */
6924e4b17023SJohn Marino while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
6925e4b17023SJohn Marino && DECL_NAME (constructor_fields) == 0)
6926e4b17023SJohn Marino constructor_fields = DECL_CHAIN (constructor_fields);
6927e4b17023SJohn Marino
6928e4b17023SJohn Marino constructor_unfilled_fields = constructor_fields;
6929e4b17023SJohn Marino constructor_bit_index = bitsize_zero_node;
6930e4b17023SJohn Marino }
6931e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
6932e4b17023SJohn Marino {
6933e4b17023SJohn Marino /* Vectors are like simple fixed-size arrays. */
6934e4b17023SJohn Marino constructor_max_index =
6935e4b17023SJohn Marino bitsize_int (TYPE_VECTOR_SUBPARTS (constructor_type) - 1);
6936e4b17023SJohn Marino constructor_index = bitsize_int (0);
6937e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
6938e4b17023SJohn Marino }
6939e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6940e4b17023SJohn Marino {
6941e4b17023SJohn Marino if (TYPE_DOMAIN (constructor_type))
6942e4b17023SJohn Marino {
6943e4b17023SJohn Marino constructor_max_index
6944e4b17023SJohn Marino = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
6945e4b17023SJohn Marino
6946e4b17023SJohn Marino /* Detect non-empty initializations of zero-length arrays. */
6947e4b17023SJohn Marino if (constructor_max_index == NULL_TREE
6948e4b17023SJohn Marino && TYPE_SIZE (constructor_type))
6949e4b17023SJohn Marino constructor_max_index = integer_minus_one_node;
6950e4b17023SJohn Marino
6951e4b17023SJohn Marino /* constructor_max_index needs to be an INTEGER_CST. Attempts
6952e4b17023SJohn Marino to initialize VLAs will cause a proper error; avoid tree
6953e4b17023SJohn Marino checking errors as well by setting a safe value. */
6954e4b17023SJohn Marino if (constructor_max_index
6955e4b17023SJohn Marino && TREE_CODE (constructor_max_index) != INTEGER_CST)
6956e4b17023SJohn Marino constructor_max_index = integer_minus_one_node;
6957e4b17023SJohn Marino
6958e4b17023SJohn Marino constructor_index
6959e4b17023SJohn Marino = convert (bitsizetype,
6960e4b17023SJohn Marino TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
6961e4b17023SJohn Marino }
6962e4b17023SJohn Marino else
6963e4b17023SJohn Marino constructor_index = bitsize_zero_node;
6964e4b17023SJohn Marino
6965e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
6966e4b17023SJohn Marino if (value && TREE_CODE (value) == STRING_CST)
6967e4b17023SJohn Marino {
6968e4b17023SJohn Marino /* We need to split the char/wchar array into individual
6969e4b17023SJohn Marino characters, so that we don't have to special case it
6970e4b17023SJohn Marino everywhere. */
6971e4b17023SJohn Marino set_nonincremental_init_from_string (value, braced_init_obstack);
6972e4b17023SJohn Marino }
6973e4b17023SJohn Marino }
6974e4b17023SJohn Marino else
6975e4b17023SJohn Marino {
6976e4b17023SJohn Marino if (constructor_type != error_mark_node)
6977e4b17023SJohn Marino warning_init (0, "braces around scalar initializer");
6978e4b17023SJohn Marino constructor_fields = constructor_type;
6979e4b17023SJohn Marino constructor_unfilled_fields = constructor_type;
6980e4b17023SJohn Marino }
6981e4b17023SJohn Marino }
6982e4b17023SJohn Marino
6983e4b17023SJohn Marino /* At the end of an implicit or explicit brace level,
6984e4b17023SJohn Marino finish up that level of constructor. If a single expression
6985e4b17023SJohn Marino with redundant braces initialized that level, return the
6986e4b17023SJohn Marino c_expr structure for that expression. Otherwise, the original_code
6987e4b17023SJohn Marino element is set to ERROR_MARK.
6988e4b17023SJohn Marino If we were outputting the elements as they are read, return 0 as the value
6989e4b17023SJohn Marino from inner levels (process_init_element ignores that),
6990e4b17023SJohn Marino but return error_mark_node as the value from the outermost level
6991e4b17023SJohn Marino (that's what we want to put in DECL_INITIAL).
6992e4b17023SJohn Marino Otherwise, return a CONSTRUCTOR expression as the value. */
6993e4b17023SJohn Marino
6994e4b17023SJohn Marino struct c_expr
pop_init_level(int implicit,struct obstack * braced_init_obstack)6995e4b17023SJohn Marino pop_init_level (int implicit, struct obstack * braced_init_obstack)
6996e4b17023SJohn Marino {
6997e4b17023SJohn Marino struct constructor_stack *p;
6998e4b17023SJohn Marino struct c_expr ret;
6999e4b17023SJohn Marino ret.value = 0;
7000e4b17023SJohn Marino ret.original_code = ERROR_MARK;
7001e4b17023SJohn Marino ret.original_type = NULL;
7002e4b17023SJohn Marino
7003e4b17023SJohn Marino if (implicit == 0)
7004e4b17023SJohn Marino {
7005e4b17023SJohn Marino /* When we come to an explicit close brace,
7006e4b17023SJohn Marino pop any inner levels that didn't have explicit braces. */
7007e4b17023SJohn Marino while (constructor_stack->implicit)
7008e4b17023SJohn Marino {
7009e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
7010e4b17023SJohn Marino true, braced_init_obstack);
7011e4b17023SJohn Marino }
7012e4b17023SJohn Marino gcc_assert (!constructor_range_stack);
7013e4b17023SJohn Marino }
7014e4b17023SJohn Marino
7015e4b17023SJohn Marino /* Now output all pending elements. */
7016e4b17023SJohn Marino constructor_incremental = 1;
7017e4b17023SJohn Marino output_pending_init_elements (1, braced_init_obstack);
7018e4b17023SJohn Marino
7019e4b17023SJohn Marino p = constructor_stack;
7020e4b17023SJohn Marino
7021e4b17023SJohn Marino /* Error for initializing a flexible array member, or a zero-length
7022e4b17023SJohn Marino array member in an inappropriate context. */
7023e4b17023SJohn Marino if (constructor_type && constructor_fields
7024e4b17023SJohn Marino && TREE_CODE (constructor_type) == ARRAY_TYPE
7025e4b17023SJohn Marino && TYPE_DOMAIN (constructor_type)
7026e4b17023SJohn Marino && !TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
7027e4b17023SJohn Marino {
7028e4b17023SJohn Marino /* Silently discard empty initializations. The parser will
7029e4b17023SJohn Marino already have pedwarned for empty brackets. */
7030e4b17023SJohn Marino if (integer_zerop (constructor_unfilled_index))
7031e4b17023SJohn Marino constructor_type = NULL_TREE;
7032e4b17023SJohn Marino else
7033e4b17023SJohn Marino {
7034e4b17023SJohn Marino gcc_assert (!TYPE_SIZE (constructor_type));
7035e4b17023SJohn Marino
7036e4b17023SJohn Marino if (constructor_depth > 2)
7037e4b17023SJohn Marino error_init ("initialization of flexible array member in a nested context");
7038e4b17023SJohn Marino else
7039e4b17023SJohn Marino pedwarn_init (input_location, OPT_pedantic,
7040e4b17023SJohn Marino "initialization of a flexible array member");
7041e4b17023SJohn Marino
7042e4b17023SJohn Marino /* We have already issued an error message for the existence
7043e4b17023SJohn Marino of a flexible array member not at the end of the structure.
7044e4b17023SJohn Marino Discard the initializer so that we do not die later. */
7045e4b17023SJohn Marino if (DECL_CHAIN (constructor_fields) != NULL_TREE)
7046e4b17023SJohn Marino constructor_type = NULL_TREE;
7047e4b17023SJohn Marino }
7048e4b17023SJohn Marino }
7049e4b17023SJohn Marino
7050e4b17023SJohn Marino /* Warn when some struct elements are implicitly initialized to zero. */
7051e4b17023SJohn Marino if (warn_missing_field_initializers
7052e4b17023SJohn Marino && constructor_type
7053e4b17023SJohn Marino && TREE_CODE (constructor_type) == RECORD_TYPE
7054e4b17023SJohn Marino && constructor_unfilled_fields)
7055e4b17023SJohn Marino {
7056e4b17023SJohn Marino bool constructor_zeroinit =
7057e4b17023SJohn Marino (VEC_length (constructor_elt, constructor_elements) == 1
7058e4b17023SJohn Marino && integer_zerop
7059e4b17023SJohn Marino (VEC_index (constructor_elt, constructor_elements, 0)->value));
7060e4b17023SJohn Marino
7061e4b17023SJohn Marino /* Do not warn for flexible array members or zero-length arrays. */
7062e4b17023SJohn Marino while (constructor_unfilled_fields
7063e4b17023SJohn Marino && (!DECL_SIZE (constructor_unfilled_fields)
7064e4b17023SJohn Marino || integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
7065e4b17023SJohn Marino constructor_unfilled_fields = DECL_CHAIN (constructor_unfilled_fields);
7066e4b17023SJohn Marino
7067e4b17023SJohn Marino if (constructor_unfilled_fields
7068e4b17023SJohn Marino /* Do not warn if this level of the initializer uses member
7069e4b17023SJohn Marino designators; it is likely to be deliberate. */
7070e4b17023SJohn Marino && !constructor_designated
7071e4b17023SJohn Marino /* Do not warn about initializing with ` = {0}'. */
7072e4b17023SJohn Marino && !constructor_zeroinit)
7073e4b17023SJohn Marino {
7074e4b17023SJohn Marino push_member_name (constructor_unfilled_fields);
7075e4b17023SJohn Marino warning_init (OPT_Wmissing_field_initializers,
7076e4b17023SJohn Marino "missing initializer");
7077e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (constructor_depth);
7078e4b17023SJohn Marino }
7079e4b17023SJohn Marino }
7080e4b17023SJohn Marino
7081e4b17023SJohn Marino /* Pad out the end of the structure. */
7082e4b17023SJohn Marino if (p->replacement_value.value)
7083e4b17023SJohn Marino /* If this closes a superfluous brace pair,
7084e4b17023SJohn Marino just pass out the element between them. */
7085e4b17023SJohn Marino ret = p->replacement_value;
7086e4b17023SJohn Marino else if (constructor_type == 0)
7087e4b17023SJohn Marino ;
7088e4b17023SJohn Marino else if (TREE_CODE (constructor_type) != RECORD_TYPE
7089e4b17023SJohn Marino && TREE_CODE (constructor_type) != UNION_TYPE
7090e4b17023SJohn Marino && TREE_CODE (constructor_type) != ARRAY_TYPE
7091e4b17023SJohn Marino && TREE_CODE (constructor_type) != VECTOR_TYPE)
7092e4b17023SJohn Marino {
7093e4b17023SJohn Marino /* A nonincremental scalar initializer--just return
7094e4b17023SJohn Marino the element, after verifying there is just one. */
7095e4b17023SJohn Marino if (VEC_empty (constructor_elt,constructor_elements))
7096e4b17023SJohn Marino {
7097e4b17023SJohn Marino if (!constructor_erroneous)
7098e4b17023SJohn Marino error_init ("empty scalar initializer");
7099e4b17023SJohn Marino ret.value = error_mark_node;
7100e4b17023SJohn Marino }
7101e4b17023SJohn Marino else if (VEC_length (constructor_elt,constructor_elements) != 1)
7102e4b17023SJohn Marino {
7103e4b17023SJohn Marino error_init ("extra elements in scalar initializer");
7104e4b17023SJohn Marino ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
7105e4b17023SJohn Marino }
7106e4b17023SJohn Marino else
7107e4b17023SJohn Marino ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
7108e4b17023SJohn Marino }
7109e4b17023SJohn Marino else
7110e4b17023SJohn Marino {
7111e4b17023SJohn Marino if (constructor_erroneous)
7112e4b17023SJohn Marino ret.value = error_mark_node;
7113e4b17023SJohn Marino else
7114e4b17023SJohn Marino {
7115e4b17023SJohn Marino ret.value = build_constructor (constructor_type,
7116e4b17023SJohn Marino constructor_elements);
7117e4b17023SJohn Marino if (constructor_constant)
7118e4b17023SJohn Marino TREE_CONSTANT (ret.value) = 1;
7119e4b17023SJohn Marino if (constructor_constant && constructor_simple)
7120e4b17023SJohn Marino TREE_STATIC (ret.value) = 1;
7121e4b17023SJohn Marino if (constructor_nonconst)
7122e4b17023SJohn Marino CONSTRUCTOR_NON_CONST (ret.value) = 1;
7123e4b17023SJohn Marino }
7124e4b17023SJohn Marino }
7125e4b17023SJohn Marino
7126e4b17023SJohn Marino if (ret.value && TREE_CODE (ret.value) != CONSTRUCTOR)
7127e4b17023SJohn Marino {
7128e4b17023SJohn Marino if (constructor_nonconst)
7129e4b17023SJohn Marino ret.original_code = C_MAYBE_CONST_EXPR;
7130e4b17023SJohn Marino else if (ret.original_code == C_MAYBE_CONST_EXPR)
7131e4b17023SJohn Marino ret.original_code = ERROR_MARK;
7132e4b17023SJohn Marino }
7133e4b17023SJohn Marino
7134e4b17023SJohn Marino constructor_type = p->type;
7135e4b17023SJohn Marino constructor_fields = p->fields;
7136e4b17023SJohn Marino constructor_index = p->index;
7137e4b17023SJohn Marino constructor_max_index = p->max_index;
7138e4b17023SJohn Marino constructor_unfilled_index = p->unfilled_index;
7139e4b17023SJohn Marino constructor_unfilled_fields = p->unfilled_fields;
7140e4b17023SJohn Marino constructor_bit_index = p->bit_index;
7141e4b17023SJohn Marino constructor_elements = p->elements;
7142e4b17023SJohn Marino constructor_constant = p->constant;
7143e4b17023SJohn Marino constructor_simple = p->simple;
7144e4b17023SJohn Marino constructor_nonconst = p->nonconst;
7145e4b17023SJohn Marino constructor_erroneous = p->erroneous;
7146e4b17023SJohn Marino constructor_incremental = p->incremental;
7147e4b17023SJohn Marino constructor_designated = p->designated;
7148e4b17023SJohn Marino constructor_pending_elts = p->pending_elts;
7149e4b17023SJohn Marino constructor_depth = p->depth;
7150e4b17023SJohn Marino if (!p->implicit)
7151e4b17023SJohn Marino constructor_range_stack = p->range_stack;
7152e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (constructor_depth);
7153e4b17023SJohn Marino
7154e4b17023SJohn Marino constructor_stack = p->next;
7155e4b17023SJohn Marino free (p);
7156e4b17023SJohn Marino
7157e4b17023SJohn Marino if (ret.value == 0 && constructor_stack == 0)
7158e4b17023SJohn Marino ret.value = error_mark_node;
7159e4b17023SJohn Marino return ret;
7160e4b17023SJohn Marino }
7161e4b17023SJohn Marino
7162e4b17023SJohn Marino /* Common handling for both array range and field name designators.
7163e4b17023SJohn Marino ARRAY argument is nonzero for array ranges. Returns zero for success. */
7164e4b17023SJohn Marino
7165e4b17023SJohn Marino static int
set_designator(int array,struct obstack * braced_init_obstack)7166e4b17023SJohn Marino set_designator (int array, struct obstack * braced_init_obstack)
7167e4b17023SJohn Marino {
7168e4b17023SJohn Marino tree subtype;
7169e4b17023SJohn Marino enum tree_code subcode;
7170e4b17023SJohn Marino
7171e4b17023SJohn Marino /* Don't die if an entire brace-pair level is superfluous
7172e4b17023SJohn Marino in the containing level. */
7173e4b17023SJohn Marino if (constructor_type == 0)
7174e4b17023SJohn Marino return 1;
7175e4b17023SJohn Marino
7176e4b17023SJohn Marino /* If there were errors in this designator list already, bail out
7177e4b17023SJohn Marino silently. */
7178e4b17023SJohn Marino if (designator_erroneous)
7179e4b17023SJohn Marino return 1;
7180e4b17023SJohn Marino
7181e4b17023SJohn Marino if (!designator_depth)
7182e4b17023SJohn Marino {
7183e4b17023SJohn Marino gcc_assert (!constructor_range_stack);
7184e4b17023SJohn Marino
7185e4b17023SJohn Marino /* Designator list starts at the level of closest explicit
7186e4b17023SJohn Marino braces. */
7187e4b17023SJohn Marino while (constructor_stack->implicit)
7188e4b17023SJohn Marino {
7189e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
7190e4b17023SJohn Marino true, braced_init_obstack);
7191e4b17023SJohn Marino }
7192e4b17023SJohn Marino constructor_designated = 1;
7193e4b17023SJohn Marino return 0;
7194e4b17023SJohn Marino }
7195e4b17023SJohn Marino
7196e4b17023SJohn Marino switch (TREE_CODE (constructor_type))
7197e4b17023SJohn Marino {
7198e4b17023SJohn Marino case RECORD_TYPE:
7199e4b17023SJohn Marino case UNION_TYPE:
7200e4b17023SJohn Marino subtype = TREE_TYPE (constructor_fields);
7201e4b17023SJohn Marino if (subtype != error_mark_node)
7202e4b17023SJohn Marino subtype = TYPE_MAIN_VARIANT (subtype);
7203e4b17023SJohn Marino break;
7204e4b17023SJohn Marino case ARRAY_TYPE:
7205e4b17023SJohn Marino subtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
7206e4b17023SJohn Marino break;
7207e4b17023SJohn Marino default:
7208e4b17023SJohn Marino gcc_unreachable ();
7209e4b17023SJohn Marino }
7210e4b17023SJohn Marino
7211e4b17023SJohn Marino subcode = TREE_CODE (subtype);
7212e4b17023SJohn Marino if (array && subcode != ARRAY_TYPE)
7213e4b17023SJohn Marino {
7214e4b17023SJohn Marino error_init ("array index in non-array initializer");
7215e4b17023SJohn Marino return 1;
7216e4b17023SJohn Marino }
7217e4b17023SJohn Marino else if (!array && subcode != RECORD_TYPE && subcode != UNION_TYPE)
7218e4b17023SJohn Marino {
7219e4b17023SJohn Marino error_init ("field name not in record or union initializer");
7220e4b17023SJohn Marino return 1;
7221e4b17023SJohn Marino }
7222e4b17023SJohn Marino
7223e4b17023SJohn Marino constructor_designated = 1;
7224e4b17023SJohn Marino push_init_level (2, braced_init_obstack);
7225e4b17023SJohn Marino return 0;
7226e4b17023SJohn Marino }
7227e4b17023SJohn Marino
7228e4b17023SJohn Marino /* If there are range designators in designator list, push a new designator
7229e4b17023SJohn Marino to constructor_range_stack. RANGE_END is end of such stack range or
7230e4b17023SJohn Marino NULL_TREE if there is no range designator at this level. */
7231e4b17023SJohn Marino
7232e4b17023SJohn Marino static void
push_range_stack(tree range_end,struct obstack * braced_init_obstack)7233e4b17023SJohn Marino push_range_stack (tree range_end, struct obstack * braced_init_obstack)
7234e4b17023SJohn Marino {
7235e4b17023SJohn Marino struct constructor_range_stack *p;
7236e4b17023SJohn Marino
7237e4b17023SJohn Marino p = (struct constructor_range_stack *)
7238e4b17023SJohn Marino obstack_alloc (braced_init_obstack,
7239e4b17023SJohn Marino sizeof (struct constructor_range_stack));
7240e4b17023SJohn Marino p->prev = constructor_range_stack;
7241e4b17023SJohn Marino p->next = 0;
7242e4b17023SJohn Marino p->fields = constructor_fields;
7243e4b17023SJohn Marino p->range_start = constructor_index;
7244e4b17023SJohn Marino p->index = constructor_index;
7245e4b17023SJohn Marino p->stack = constructor_stack;
7246e4b17023SJohn Marino p->range_end = range_end;
7247e4b17023SJohn Marino if (constructor_range_stack)
7248e4b17023SJohn Marino constructor_range_stack->next = p;
7249e4b17023SJohn Marino constructor_range_stack = p;
7250e4b17023SJohn Marino }
7251e4b17023SJohn Marino
7252e4b17023SJohn Marino /* Within an array initializer, specify the next index to be initialized.
7253e4b17023SJohn Marino FIRST is that index. If LAST is nonzero, then initialize a range
7254e4b17023SJohn Marino of indices, running from FIRST through LAST. */
7255e4b17023SJohn Marino
7256e4b17023SJohn Marino void
set_init_index(tree first,tree last,struct obstack * braced_init_obstack)7257e4b17023SJohn Marino set_init_index (tree first, tree last,
7258e4b17023SJohn Marino struct obstack * braced_init_obstack)
7259e4b17023SJohn Marino {
7260e4b17023SJohn Marino if (set_designator (1, braced_init_obstack))
7261e4b17023SJohn Marino return;
7262e4b17023SJohn Marino
7263e4b17023SJohn Marino designator_erroneous = 1;
7264e4b17023SJohn Marino
7265e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (first))
7266e4b17023SJohn Marino || (last && !INTEGRAL_TYPE_P (TREE_TYPE (last))))
7267e4b17023SJohn Marino {
7268e4b17023SJohn Marino error_init ("array index in initializer not of integer type");
7269e4b17023SJohn Marino return;
7270e4b17023SJohn Marino }
7271e4b17023SJohn Marino
7272e4b17023SJohn Marino if (TREE_CODE (first) != INTEGER_CST)
7273e4b17023SJohn Marino {
7274e4b17023SJohn Marino first = c_fully_fold (first, false, NULL);
7275e4b17023SJohn Marino if (TREE_CODE (first) == INTEGER_CST)
7276e4b17023SJohn Marino pedwarn_init (input_location, OPT_pedantic,
7277e4b17023SJohn Marino "array index in initializer is not "
7278e4b17023SJohn Marino "an integer constant expression");
7279e4b17023SJohn Marino }
7280e4b17023SJohn Marino
7281e4b17023SJohn Marino if (last && TREE_CODE (last) != INTEGER_CST)
7282e4b17023SJohn Marino {
7283e4b17023SJohn Marino last = c_fully_fold (last, false, NULL);
7284e4b17023SJohn Marino if (TREE_CODE (last) == INTEGER_CST)
7285e4b17023SJohn Marino pedwarn_init (input_location, OPT_pedantic,
7286e4b17023SJohn Marino "array index in initializer is not "
7287e4b17023SJohn Marino "an integer constant expression");
7288e4b17023SJohn Marino }
7289e4b17023SJohn Marino
7290e4b17023SJohn Marino if (TREE_CODE (first) != INTEGER_CST)
7291e4b17023SJohn Marino error_init ("nonconstant array index in initializer");
7292e4b17023SJohn Marino else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
7293e4b17023SJohn Marino error_init ("nonconstant array index in initializer");
7294e4b17023SJohn Marino else if (TREE_CODE (constructor_type) != ARRAY_TYPE)
7295e4b17023SJohn Marino error_init ("array index in non-array initializer");
7296e4b17023SJohn Marino else if (tree_int_cst_sgn (first) == -1)
7297e4b17023SJohn Marino error_init ("array index in initializer exceeds array bounds");
7298e4b17023SJohn Marino else if (constructor_max_index
7299e4b17023SJohn Marino && tree_int_cst_lt (constructor_max_index, first))
7300e4b17023SJohn Marino error_init ("array index in initializer exceeds array bounds");
7301e4b17023SJohn Marino else
7302e4b17023SJohn Marino {
7303e4b17023SJohn Marino constant_expression_warning (first);
7304e4b17023SJohn Marino if (last)
7305e4b17023SJohn Marino constant_expression_warning (last);
7306e4b17023SJohn Marino constructor_index = convert (bitsizetype, first);
7307e4b17023SJohn Marino
7308e4b17023SJohn Marino if (last)
7309e4b17023SJohn Marino {
7310e4b17023SJohn Marino if (tree_int_cst_equal (first, last))
7311e4b17023SJohn Marino last = 0;
7312e4b17023SJohn Marino else if (tree_int_cst_lt (last, first))
7313e4b17023SJohn Marino {
7314e4b17023SJohn Marino error_init ("empty index range in initializer");
7315e4b17023SJohn Marino last = 0;
7316e4b17023SJohn Marino }
7317e4b17023SJohn Marino else
7318e4b17023SJohn Marino {
7319e4b17023SJohn Marino last = convert (bitsizetype, last);
7320e4b17023SJohn Marino if (constructor_max_index != 0
7321e4b17023SJohn Marino && tree_int_cst_lt (constructor_max_index, last))
7322e4b17023SJohn Marino {
7323e4b17023SJohn Marino error_init ("array index range in initializer exceeds array bounds");
7324e4b17023SJohn Marino last = 0;
7325e4b17023SJohn Marino }
7326e4b17023SJohn Marino }
7327e4b17023SJohn Marino }
7328e4b17023SJohn Marino
7329e4b17023SJohn Marino designator_depth++;
7330e4b17023SJohn Marino designator_erroneous = 0;
7331e4b17023SJohn Marino if (constructor_range_stack || last)
7332e4b17023SJohn Marino push_range_stack (last, braced_init_obstack);
7333e4b17023SJohn Marino }
7334e4b17023SJohn Marino }
7335e4b17023SJohn Marino
7336e4b17023SJohn Marino /* Within a struct initializer, specify the next field to be initialized. */
7337e4b17023SJohn Marino
7338e4b17023SJohn Marino void
set_init_label(tree fieldname,struct obstack * braced_init_obstack)7339e4b17023SJohn Marino set_init_label (tree fieldname, struct obstack * braced_init_obstack)
7340e4b17023SJohn Marino {
7341e4b17023SJohn Marino tree field;
7342e4b17023SJohn Marino
7343e4b17023SJohn Marino if (set_designator (0, braced_init_obstack))
7344e4b17023SJohn Marino return;
7345e4b17023SJohn Marino
7346e4b17023SJohn Marino designator_erroneous = 1;
7347e4b17023SJohn Marino
7348e4b17023SJohn Marino if (TREE_CODE (constructor_type) != RECORD_TYPE
7349e4b17023SJohn Marino && TREE_CODE (constructor_type) != UNION_TYPE)
7350e4b17023SJohn Marino {
7351e4b17023SJohn Marino error_init ("field name not in record or union initializer");
7352e4b17023SJohn Marino return;
7353e4b17023SJohn Marino }
7354e4b17023SJohn Marino
7355e4b17023SJohn Marino field = lookup_field (constructor_type, fieldname);
7356e4b17023SJohn Marino
7357e4b17023SJohn Marino if (field == 0)
7358e4b17023SJohn Marino error ("unknown field %qE specified in initializer", fieldname);
7359e4b17023SJohn Marino else
7360e4b17023SJohn Marino do
7361e4b17023SJohn Marino {
7362e4b17023SJohn Marino constructor_fields = TREE_VALUE (field);
7363e4b17023SJohn Marino designator_depth++;
7364e4b17023SJohn Marino designator_erroneous = 0;
7365e4b17023SJohn Marino if (constructor_range_stack)
7366e4b17023SJohn Marino push_range_stack (NULL_TREE, braced_init_obstack);
7367e4b17023SJohn Marino field = TREE_CHAIN (field);
7368e4b17023SJohn Marino if (field)
7369e4b17023SJohn Marino {
7370e4b17023SJohn Marino if (set_designator (0, braced_init_obstack))
7371e4b17023SJohn Marino return;
7372e4b17023SJohn Marino }
7373e4b17023SJohn Marino }
7374e4b17023SJohn Marino while (field != NULL_TREE);
7375e4b17023SJohn Marino }
7376e4b17023SJohn Marino
7377e4b17023SJohn Marino /* Add a new initializer to the tree of pending initializers. PURPOSE
7378e4b17023SJohn Marino identifies the initializer, either array index or field in a structure.
7379e4b17023SJohn Marino VALUE is the value of that index or field. If ORIGTYPE is not
7380e4b17023SJohn Marino NULL_TREE, it is the original type of VALUE.
7381e4b17023SJohn Marino
7382e4b17023SJohn Marino IMPLICIT is true if value comes from pop_init_level (1),
7383e4b17023SJohn Marino the new initializer has been merged with the existing one
7384e4b17023SJohn Marino and thus no warnings should be emitted about overriding an
7385e4b17023SJohn Marino existing initializer. */
7386e4b17023SJohn Marino
7387e4b17023SJohn Marino static void
add_pending_init(tree purpose,tree value,tree origtype,bool implicit,struct obstack * braced_init_obstack)7388e4b17023SJohn Marino add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
7389e4b17023SJohn Marino struct obstack * braced_init_obstack)
7390e4b17023SJohn Marino {
7391e4b17023SJohn Marino struct init_node *p, **q, *r;
7392e4b17023SJohn Marino
7393e4b17023SJohn Marino q = &constructor_pending_elts;
7394e4b17023SJohn Marino p = 0;
7395e4b17023SJohn Marino
7396e4b17023SJohn Marino if (TREE_CODE (constructor_type) == ARRAY_TYPE)
7397e4b17023SJohn Marino {
7398e4b17023SJohn Marino while (*q != 0)
7399e4b17023SJohn Marino {
7400e4b17023SJohn Marino p = *q;
7401e4b17023SJohn Marino if (tree_int_cst_lt (purpose, p->purpose))
7402e4b17023SJohn Marino q = &p->left;
7403e4b17023SJohn Marino else if (tree_int_cst_lt (p->purpose, purpose))
7404e4b17023SJohn Marino q = &p->right;
7405e4b17023SJohn Marino else
7406e4b17023SJohn Marino {
7407e4b17023SJohn Marino if (!implicit)
7408e4b17023SJohn Marino {
7409e4b17023SJohn Marino if (TREE_SIDE_EFFECTS (p->value))
7410e4b17023SJohn Marino warning_init (0, "initialized field with side-effects overwritten");
7411e4b17023SJohn Marino else if (warn_override_init)
7412e4b17023SJohn Marino warning_init (OPT_Woverride_init, "initialized field overwritten");
7413e4b17023SJohn Marino }
7414e4b17023SJohn Marino p->value = value;
7415e4b17023SJohn Marino p->origtype = origtype;
7416e4b17023SJohn Marino return;
7417e4b17023SJohn Marino }
7418e4b17023SJohn Marino }
7419e4b17023SJohn Marino }
7420e4b17023SJohn Marino else
7421e4b17023SJohn Marino {
7422e4b17023SJohn Marino tree bitpos;
7423e4b17023SJohn Marino
7424e4b17023SJohn Marino bitpos = bit_position (purpose);
7425e4b17023SJohn Marino while (*q != NULL)
7426e4b17023SJohn Marino {
7427e4b17023SJohn Marino p = *q;
7428e4b17023SJohn Marino if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
7429e4b17023SJohn Marino q = &p->left;
7430e4b17023SJohn Marino else if (p->purpose != purpose)
7431e4b17023SJohn Marino q = &p->right;
7432e4b17023SJohn Marino else
7433e4b17023SJohn Marino {
7434e4b17023SJohn Marino if (!implicit)
7435e4b17023SJohn Marino {
7436e4b17023SJohn Marino if (TREE_SIDE_EFFECTS (p->value))
7437e4b17023SJohn Marino warning_init (0, "initialized field with side-effects overwritten");
7438e4b17023SJohn Marino else if (warn_override_init)
7439e4b17023SJohn Marino warning_init (OPT_Woverride_init, "initialized field overwritten");
7440e4b17023SJohn Marino }
7441e4b17023SJohn Marino p->value = value;
7442e4b17023SJohn Marino p->origtype = origtype;
7443e4b17023SJohn Marino return;
7444e4b17023SJohn Marino }
7445e4b17023SJohn Marino }
7446e4b17023SJohn Marino }
7447e4b17023SJohn Marino
7448e4b17023SJohn Marino r = (struct init_node *) obstack_alloc (braced_init_obstack,
7449e4b17023SJohn Marino sizeof (struct init_node));
7450e4b17023SJohn Marino r->purpose = purpose;
7451e4b17023SJohn Marino r->value = value;
7452e4b17023SJohn Marino r->origtype = origtype;
7453e4b17023SJohn Marino
7454e4b17023SJohn Marino *q = r;
7455e4b17023SJohn Marino r->parent = p;
7456e4b17023SJohn Marino r->left = 0;
7457e4b17023SJohn Marino r->right = 0;
7458e4b17023SJohn Marino r->balance = 0;
7459e4b17023SJohn Marino
7460e4b17023SJohn Marino while (p)
7461e4b17023SJohn Marino {
7462e4b17023SJohn Marino struct init_node *s;
7463e4b17023SJohn Marino
7464e4b17023SJohn Marino if (r == p->left)
7465e4b17023SJohn Marino {
7466e4b17023SJohn Marino if (p->balance == 0)
7467e4b17023SJohn Marino p->balance = -1;
7468e4b17023SJohn Marino else if (p->balance < 0)
7469e4b17023SJohn Marino {
7470e4b17023SJohn Marino if (r->balance < 0)
7471e4b17023SJohn Marino {
7472e4b17023SJohn Marino /* L rotation. */
7473e4b17023SJohn Marino p->left = r->right;
7474e4b17023SJohn Marino if (p->left)
7475e4b17023SJohn Marino p->left->parent = p;
7476e4b17023SJohn Marino r->right = p;
7477e4b17023SJohn Marino
7478e4b17023SJohn Marino p->balance = 0;
7479e4b17023SJohn Marino r->balance = 0;
7480e4b17023SJohn Marino
7481e4b17023SJohn Marino s = p->parent;
7482e4b17023SJohn Marino p->parent = r;
7483e4b17023SJohn Marino r->parent = s;
7484e4b17023SJohn Marino if (s)
7485e4b17023SJohn Marino {
7486e4b17023SJohn Marino if (s->left == p)
7487e4b17023SJohn Marino s->left = r;
7488e4b17023SJohn Marino else
7489e4b17023SJohn Marino s->right = r;
7490e4b17023SJohn Marino }
7491e4b17023SJohn Marino else
7492e4b17023SJohn Marino constructor_pending_elts = r;
7493e4b17023SJohn Marino }
7494e4b17023SJohn Marino else
7495e4b17023SJohn Marino {
7496e4b17023SJohn Marino /* LR rotation. */
7497e4b17023SJohn Marino struct init_node *t = r->right;
7498e4b17023SJohn Marino
7499e4b17023SJohn Marino r->right = t->left;
7500e4b17023SJohn Marino if (r->right)
7501e4b17023SJohn Marino r->right->parent = r;
7502e4b17023SJohn Marino t->left = r;
7503e4b17023SJohn Marino
7504e4b17023SJohn Marino p->left = t->right;
7505e4b17023SJohn Marino if (p->left)
7506e4b17023SJohn Marino p->left->parent = p;
7507e4b17023SJohn Marino t->right = p;
7508e4b17023SJohn Marino
7509e4b17023SJohn Marino p->balance = t->balance < 0;
7510e4b17023SJohn Marino r->balance = -(t->balance > 0);
7511e4b17023SJohn Marino t->balance = 0;
7512e4b17023SJohn Marino
7513e4b17023SJohn Marino s = p->parent;
7514e4b17023SJohn Marino p->parent = t;
7515e4b17023SJohn Marino r->parent = t;
7516e4b17023SJohn Marino t->parent = s;
7517e4b17023SJohn Marino if (s)
7518e4b17023SJohn Marino {
7519e4b17023SJohn Marino if (s->left == p)
7520e4b17023SJohn Marino s->left = t;
7521e4b17023SJohn Marino else
7522e4b17023SJohn Marino s->right = t;
7523e4b17023SJohn Marino }
7524e4b17023SJohn Marino else
7525e4b17023SJohn Marino constructor_pending_elts = t;
7526e4b17023SJohn Marino }
7527e4b17023SJohn Marino break;
7528e4b17023SJohn Marino }
7529e4b17023SJohn Marino else
7530e4b17023SJohn Marino {
7531e4b17023SJohn Marino /* p->balance == +1; growth of left side balances the node. */
7532e4b17023SJohn Marino p->balance = 0;
7533e4b17023SJohn Marino break;
7534e4b17023SJohn Marino }
7535e4b17023SJohn Marino }
7536e4b17023SJohn Marino else /* r == p->right */
7537e4b17023SJohn Marino {
7538e4b17023SJohn Marino if (p->balance == 0)
7539e4b17023SJohn Marino /* Growth propagation from right side. */
7540e4b17023SJohn Marino p->balance++;
7541e4b17023SJohn Marino else if (p->balance > 0)
7542e4b17023SJohn Marino {
7543e4b17023SJohn Marino if (r->balance > 0)
7544e4b17023SJohn Marino {
7545e4b17023SJohn Marino /* R rotation. */
7546e4b17023SJohn Marino p->right = r->left;
7547e4b17023SJohn Marino if (p->right)
7548e4b17023SJohn Marino p->right->parent = p;
7549e4b17023SJohn Marino r->left = p;
7550e4b17023SJohn Marino
7551e4b17023SJohn Marino p->balance = 0;
7552e4b17023SJohn Marino r->balance = 0;
7553e4b17023SJohn Marino
7554e4b17023SJohn Marino s = p->parent;
7555e4b17023SJohn Marino p->parent = r;
7556e4b17023SJohn Marino r->parent = s;
7557e4b17023SJohn Marino if (s)
7558e4b17023SJohn Marino {
7559e4b17023SJohn Marino if (s->left == p)
7560e4b17023SJohn Marino s->left = r;
7561e4b17023SJohn Marino else
7562e4b17023SJohn Marino s->right = r;
7563e4b17023SJohn Marino }
7564e4b17023SJohn Marino else
7565e4b17023SJohn Marino constructor_pending_elts = r;
7566e4b17023SJohn Marino }
7567e4b17023SJohn Marino else /* r->balance == -1 */
7568e4b17023SJohn Marino {
7569e4b17023SJohn Marino /* RL rotation */
7570e4b17023SJohn Marino struct init_node *t = r->left;
7571e4b17023SJohn Marino
7572e4b17023SJohn Marino r->left = t->right;
7573e4b17023SJohn Marino if (r->left)
7574e4b17023SJohn Marino r->left->parent = r;
7575e4b17023SJohn Marino t->right = r;
7576e4b17023SJohn Marino
7577e4b17023SJohn Marino p->right = t->left;
7578e4b17023SJohn Marino if (p->right)
7579e4b17023SJohn Marino p->right->parent = p;
7580e4b17023SJohn Marino t->left = p;
7581e4b17023SJohn Marino
7582e4b17023SJohn Marino r->balance = (t->balance < 0);
7583e4b17023SJohn Marino p->balance = -(t->balance > 0);
7584e4b17023SJohn Marino t->balance = 0;
7585e4b17023SJohn Marino
7586e4b17023SJohn Marino s = p->parent;
7587e4b17023SJohn Marino p->parent = t;
7588e4b17023SJohn Marino r->parent = t;
7589e4b17023SJohn Marino t->parent = s;
7590e4b17023SJohn Marino if (s)
7591e4b17023SJohn Marino {
7592e4b17023SJohn Marino if (s->left == p)
7593e4b17023SJohn Marino s->left = t;
7594e4b17023SJohn Marino else
7595e4b17023SJohn Marino s->right = t;
7596e4b17023SJohn Marino }
7597e4b17023SJohn Marino else
7598e4b17023SJohn Marino constructor_pending_elts = t;
7599e4b17023SJohn Marino }
7600e4b17023SJohn Marino break;
7601e4b17023SJohn Marino }
7602e4b17023SJohn Marino else
7603e4b17023SJohn Marino {
7604e4b17023SJohn Marino /* p->balance == -1; growth of right side balances the node. */
7605e4b17023SJohn Marino p->balance = 0;
7606e4b17023SJohn Marino break;
7607e4b17023SJohn Marino }
7608e4b17023SJohn Marino }
7609e4b17023SJohn Marino
7610e4b17023SJohn Marino r = p;
7611e4b17023SJohn Marino p = p->parent;
7612e4b17023SJohn Marino }
7613e4b17023SJohn Marino }
7614e4b17023SJohn Marino
7615e4b17023SJohn Marino /* Build AVL tree from a sorted chain. */
7616e4b17023SJohn Marino
7617e4b17023SJohn Marino static void
set_nonincremental_init(struct obstack * braced_init_obstack)7618e4b17023SJohn Marino set_nonincremental_init (struct obstack * braced_init_obstack)
7619e4b17023SJohn Marino {
7620e4b17023SJohn Marino unsigned HOST_WIDE_INT ix;
7621e4b17023SJohn Marino tree index, value;
7622e4b17023SJohn Marino
7623e4b17023SJohn Marino if (TREE_CODE (constructor_type) != RECORD_TYPE
7624e4b17023SJohn Marino && TREE_CODE (constructor_type) != ARRAY_TYPE)
7625e4b17023SJohn Marino return;
7626e4b17023SJohn Marino
7627e4b17023SJohn Marino FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
7628e4b17023SJohn Marino {
7629e4b17023SJohn Marino add_pending_init (index, value, NULL_TREE, true,
7630e4b17023SJohn Marino braced_init_obstack);
7631e4b17023SJohn Marino }
7632e4b17023SJohn Marino constructor_elements = 0;
7633e4b17023SJohn Marino if (TREE_CODE (constructor_type) == RECORD_TYPE)
7634e4b17023SJohn Marino {
7635e4b17023SJohn Marino constructor_unfilled_fields = TYPE_FIELDS (constructor_type);
7636e4b17023SJohn Marino /* Skip any nameless bit fields at the beginning. */
7637e4b17023SJohn Marino while (constructor_unfilled_fields != 0
7638e4b17023SJohn Marino && DECL_C_BIT_FIELD (constructor_unfilled_fields)
7639e4b17023SJohn Marino && DECL_NAME (constructor_unfilled_fields) == 0)
7640e4b17023SJohn Marino constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
7641e4b17023SJohn Marino
7642e4b17023SJohn Marino }
7643e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
7644e4b17023SJohn Marino {
7645e4b17023SJohn Marino if (TYPE_DOMAIN (constructor_type))
7646e4b17023SJohn Marino constructor_unfilled_index
7647e4b17023SJohn Marino = convert (bitsizetype,
7648e4b17023SJohn Marino TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
7649e4b17023SJohn Marino else
7650e4b17023SJohn Marino constructor_unfilled_index = bitsize_zero_node;
7651e4b17023SJohn Marino }
7652e4b17023SJohn Marino constructor_incremental = 0;
7653e4b17023SJohn Marino }
7654e4b17023SJohn Marino
7655e4b17023SJohn Marino /* Build AVL tree from a string constant. */
7656e4b17023SJohn Marino
7657e4b17023SJohn Marino static void
set_nonincremental_init_from_string(tree str,struct obstack * braced_init_obstack)7658e4b17023SJohn Marino set_nonincremental_init_from_string (tree str,
7659e4b17023SJohn Marino struct obstack * braced_init_obstack)
7660e4b17023SJohn Marino {
7661e4b17023SJohn Marino tree value, purpose, type;
7662e4b17023SJohn Marino HOST_WIDE_INT val[2];
7663e4b17023SJohn Marino const char *p, *end;
7664e4b17023SJohn Marino int byte, wchar_bytes, charwidth, bitpos;
7665e4b17023SJohn Marino
7666e4b17023SJohn Marino gcc_assert (TREE_CODE (constructor_type) == ARRAY_TYPE);
7667e4b17023SJohn Marino
7668e4b17023SJohn Marino wchar_bytes = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) / BITS_PER_UNIT;
7669e4b17023SJohn Marino charwidth = TYPE_PRECISION (char_type_node);
7670e4b17023SJohn Marino type = TREE_TYPE (constructor_type);
7671e4b17023SJohn Marino p = TREE_STRING_POINTER (str);
7672e4b17023SJohn Marino end = p + TREE_STRING_LENGTH (str);
7673e4b17023SJohn Marino
7674e4b17023SJohn Marino for (purpose = bitsize_zero_node;
7675e4b17023SJohn Marino p < end && !tree_int_cst_lt (constructor_max_index, purpose);
7676e4b17023SJohn Marino purpose = size_binop (PLUS_EXPR, purpose, bitsize_one_node))
7677e4b17023SJohn Marino {
7678e4b17023SJohn Marino if (wchar_bytes == 1)
7679e4b17023SJohn Marino {
7680e4b17023SJohn Marino val[1] = (unsigned char) *p++;
7681e4b17023SJohn Marino val[0] = 0;
7682e4b17023SJohn Marino }
7683e4b17023SJohn Marino else
7684e4b17023SJohn Marino {
7685e4b17023SJohn Marino val[0] = 0;
7686e4b17023SJohn Marino val[1] = 0;
7687e4b17023SJohn Marino for (byte = 0; byte < wchar_bytes; byte++)
7688e4b17023SJohn Marino {
7689e4b17023SJohn Marino if (BYTES_BIG_ENDIAN)
7690e4b17023SJohn Marino bitpos = (wchar_bytes - byte - 1) * charwidth;
7691e4b17023SJohn Marino else
7692e4b17023SJohn Marino bitpos = byte * charwidth;
7693e4b17023SJohn Marino val[bitpos < HOST_BITS_PER_WIDE_INT]
7694e4b17023SJohn Marino |= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++))
7695e4b17023SJohn Marino << (bitpos % HOST_BITS_PER_WIDE_INT);
7696e4b17023SJohn Marino }
7697e4b17023SJohn Marino }
7698e4b17023SJohn Marino
7699e4b17023SJohn Marino if (!TYPE_UNSIGNED (type))
7700e4b17023SJohn Marino {
7701e4b17023SJohn Marino bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR;
7702e4b17023SJohn Marino if (bitpos < HOST_BITS_PER_WIDE_INT)
7703e4b17023SJohn Marino {
7704e4b17023SJohn Marino if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
7705e4b17023SJohn Marino {
7706e4b17023SJohn Marino val[1] |= ((HOST_WIDE_INT) -1) << bitpos;
7707e4b17023SJohn Marino val[0] = -1;
7708e4b17023SJohn Marino }
7709e4b17023SJohn Marino }
7710e4b17023SJohn Marino else if (bitpos == HOST_BITS_PER_WIDE_INT)
7711e4b17023SJohn Marino {
7712e4b17023SJohn Marino if (val[1] < 0)
7713e4b17023SJohn Marino val[0] = -1;
7714e4b17023SJohn Marino }
7715e4b17023SJohn Marino else if (val[0] & (((HOST_WIDE_INT) 1)
7716e4b17023SJohn Marino << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
7717e4b17023SJohn Marino val[0] |= ((HOST_WIDE_INT) -1)
7718e4b17023SJohn Marino << (bitpos - HOST_BITS_PER_WIDE_INT);
7719e4b17023SJohn Marino }
7720e4b17023SJohn Marino
7721e4b17023SJohn Marino value = build_int_cst_wide (type, val[1], val[0]);
7722e4b17023SJohn Marino add_pending_init (purpose, value, NULL_TREE, true,
7723e4b17023SJohn Marino braced_init_obstack);
7724e4b17023SJohn Marino }
7725e4b17023SJohn Marino
7726e4b17023SJohn Marino constructor_incremental = 0;
7727e4b17023SJohn Marino }
7728e4b17023SJohn Marino
7729e4b17023SJohn Marino /* Return value of FIELD in pending initializer or zero if the field was
7730e4b17023SJohn Marino not initialized yet. */
7731e4b17023SJohn Marino
7732e4b17023SJohn Marino static tree
find_init_member(tree field,struct obstack * braced_init_obstack)7733e4b17023SJohn Marino find_init_member (tree field, struct obstack * braced_init_obstack)
7734e4b17023SJohn Marino {
7735e4b17023SJohn Marino struct init_node *p;
7736e4b17023SJohn Marino
7737e4b17023SJohn Marino if (TREE_CODE (constructor_type) == ARRAY_TYPE)
7738e4b17023SJohn Marino {
7739e4b17023SJohn Marino if (constructor_incremental
7740e4b17023SJohn Marino && tree_int_cst_lt (field, constructor_unfilled_index))
7741e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
7742e4b17023SJohn Marino
7743e4b17023SJohn Marino p = constructor_pending_elts;
7744e4b17023SJohn Marino while (p)
7745e4b17023SJohn Marino {
7746e4b17023SJohn Marino if (tree_int_cst_lt (field, p->purpose))
7747e4b17023SJohn Marino p = p->left;
7748e4b17023SJohn Marino else if (tree_int_cst_lt (p->purpose, field))
7749e4b17023SJohn Marino p = p->right;
7750e4b17023SJohn Marino else
7751e4b17023SJohn Marino return p->value;
7752e4b17023SJohn Marino }
7753e4b17023SJohn Marino }
7754e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == RECORD_TYPE)
7755e4b17023SJohn Marino {
7756e4b17023SJohn Marino tree bitpos = bit_position (field);
7757e4b17023SJohn Marino
7758e4b17023SJohn Marino if (constructor_incremental
7759e4b17023SJohn Marino && (!constructor_unfilled_fields
7760e4b17023SJohn Marino || tree_int_cst_lt (bitpos,
7761e4b17023SJohn Marino bit_position (constructor_unfilled_fields))))
7762e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
7763e4b17023SJohn Marino
7764e4b17023SJohn Marino p = constructor_pending_elts;
7765e4b17023SJohn Marino while (p)
7766e4b17023SJohn Marino {
7767e4b17023SJohn Marino if (field == p->purpose)
7768e4b17023SJohn Marino return p->value;
7769e4b17023SJohn Marino else if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
7770e4b17023SJohn Marino p = p->left;
7771e4b17023SJohn Marino else
7772e4b17023SJohn Marino p = p->right;
7773e4b17023SJohn Marino }
7774e4b17023SJohn Marino }
7775e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == UNION_TYPE)
7776e4b17023SJohn Marino {
7777e4b17023SJohn Marino if (!VEC_empty (constructor_elt, constructor_elements)
7778e4b17023SJohn Marino && (VEC_last (constructor_elt, constructor_elements)->index
7779e4b17023SJohn Marino == field))
7780e4b17023SJohn Marino return VEC_last (constructor_elt, constructor_elements)->value;
7781e4b17023SJohn Marino }
7782e4b17023SJohn Marino return 0;
7783e4b17023SJohn Marino }
7784e4b17023SJohn Marino
7785e4b17023SJohn Marino /* "Output" the next constructor element.
7786e4b17023SJohn Marino At top level, really output it to assembler code now.
7787e4b17023SJohn Marino Otherwise, collect it in a list from which we will make a CONSTRUCTOR.
7788e4b17023SJohn Marino If ORIGTYPE is not NULL_TREE, it is the original type of VALUE.
7789e4b17023SJohn Marino TYPE is the data type that the containing data type wants here.
7790e4b17023SJohn Marino FIELD is the field (a FIELD_DECL) or the index that this element fills.
7791e4b17023SJohn Marino If VALUE is a string constant, STRICT_STRING is true if it is
7792e4b17023SJohn Marino unparenthesized or we should not warn here for it being parenthesized.
7793e4b17023SJohn Marino For other types of VALUE, STRICT_STRING is not used.
7794e4b17023SJohn Marino
7795e4b17023SJohn Marino PENDING if non-nil means output pending elements that belong
7796e4b17023SJohn Marino right after this element. (PENDING is normally 1;
7797e4b17023SJohn Marino it is 0 while outputting pending elements, to avoid recursion.)
7798e4b17023SJohn Marino
7799e4b17023SJohn Marino IMPLICIT is true if value comes from pop_init_level (1),
7800e4b17023SJohn Marino the new initializer has been merged with the existing one
7801e4b17023SJohn Marino and thus no warnings should be emitted about overriding an
7802e4b17023SJohn Marino existing initializer. */
7803e4b17023SJohn Marino
7804e4b17023SJohn Marino 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)7805e4b17023SJohn Marino output_init_element (tree value, tree origtype, bool strict_string, tree type,
7806e4b17023SJohn Marino tree field, int pending, bool implicit,
7807e4b17023SJohn Marino struct obstack * braced_init_obstack)
7808e4b17023SJohn Marino {
7809e4b17023SJohn Marino tree semantic_type = NULL_TREE;
7810e4b17023SJohn Marino constructor_elt *celt;
7811e4b17023SJohn Marino bool maybe_const = true;
7812e4b17023SJohn Marino bool npc;
7813e4b17023SJohn Marino
7814e4b17023SJohn Marino if (type == error_mark_node || value == error_mark_node)
7815e4b17023SJohn Marino {
7816e4b17023SJohn Marino constructor_erroneous = 1;
7817e4b17023SJohn Marino return;
7818e4b17023SJohn Marino }
7819e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
7820e4b17023SJohn Marino && (TREE_CODE (value) == STRING_CST
7821e4b17023SJohn Marino || TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
7822e4b17023SJohn Marino && !(TREE_CODE (value) == STRING_CST
7823e4b17023SJohn Marino && TREE_CODE (type) == ARRAY_TYPE
7824e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (type)))
7825e4b17023SJohn Marino && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
7826e4b17023SJohn Marino TYPE_MAIN_VARIANT (type)))
7827e4b17023SJohn Marino value = array_to_pointer_conversion (input_location, value);
7828e4b17023SJohn Marino
7829e4b17023SJohn Marino if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
7830*8172914bSzrj && require_constant_value && pending)
7831e4b17023SJohn Marino {
7832e4b17023SJohn Marino /* As an extension, allow initializing objects with static storage
7833e4b17023SJohn Marino duration with compound literals (which are then treated just as
7834e4b17023SJohn Marino the brace enclosed list they contain). */
7835*8172914bSzrj if (flag_isoc99)
7836*8172914bSzrj pedwarn_init (input_location, OPT_pedantic, "initializer element is not "
7837*8172914bSzrj "constant");
7838e4b17023SJohn Marino tree decl = COMPOUND_LITERAL_EXPR_DECL (value);
7839e4b17023SJohn Marino value = DECL_INITIAL (decl);
7840e4b17023SJohn Marino }
7841e4b17023SJohn Marino
7842e4b17023SJohn Marino npc = null_pointer_constant_p (value);
7843e4b17023SJohn Marino if (TREE_CODE (value) == EXCESS_PRECISION_EXPR)
7844e4b17023SJohn Marino {
7845e4b17023SJohn Marino semantic_type = TREE_TYPE (value);
7846e4b17023SJohn Marino value = TREE_OPERAND (value, 0);
7847e4b17023SJohn Marino }
7848e4b17023SJohn Marino value = c_fully_fold (value, require_constant_value, &maybe_const);
7849e4b17023SJohn Marino
7850e4b17023SJohn Marino if (value == error_mark_node)
7851e4b17023SJohn Marino constructor_erroneous = 1;
7852e4b17023SJohn Marino else if (!TREE_CONSTANT (value))
7853e4b17023SJohn Marino constructor_constant = 0;
7854e4b17023SJohn Marino else if (!initializer_constant_valid_p (value, TREE_TYPE (value))
7855e4b17023SJohn Marino || ((TREE_CODE (constructor_type) == RECORD_TYPE
7856e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
7857e4b17023SJohn Marino && DECL_C_BIT_FIELD (field)
7858e4b17023SJohn Marino && TREE_CODE (value) != INTEGER_CST))
7859e4b17023SJohn Marino constructor_simple = 0;
7860e4b17023SJohn Marino if (!maybe_const)
7861e4b17023SJohn Marino constructor_nonconst = 1;
7862e4b17023SJohn Marino
7863e4b17023SJohn Marino if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
7864e4b17023SJohn Marino {
7865e4b17023SJohn Marino if (require_constant_value)
7866e4b17023SJohn Marino {
7867e4b17023SJohn Marino error_init ("initializer element is not constant");
7868e4b17023SJohn Marino value = error_mark_node;
7869e4b17023SJohn Marino }
7870e4b17023SJohn Marino else if (require_constant_elements)
7871e4b17023SJohn Marino pedwarn (input_location, 0,
7872e4b17023SJohn Marino "initializer element is not computable at load time");
7873e4b17023SJohn Marino }
7874e4b17023SJohn Marino else if (!maybe_const
7875e4b17023SJohn Marino && (require_constant_value || require_constant_elements))
7876e4b17023SJohn Marino pedwarn_init (input_location, 0,
7877e4b17023SJohn Marino "initializer element is not a constant expression");
7878e4b17023SJohn Marino
7879e4b17023SJohn Marino /* Issue -Wc++-compat warnings about initializing a bitfield with
7880e4b17023SJohn Marino enum type. */
7881e4b17023SJohn Marino if (warn_cxx_compat
7882e4b17023SJohn Marino && field != NULL_TREE
7883e4b17023SJohn Marino && TREE_CODE (field) == FIELD_DECL
7884e4b17023SJohn Marino && DECL_BIT_FIELD_TYPE (field) != NULL_TREE
7885e4b17023SJohn Marino && (TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field))
7886e4b17023SJohn Marino != TYPE_MAIN_VARIANT (type))
7887e4b17023SJohn Marino && TREE_CODE (DECL_BIT_FIELD_TYPE (field)) == ENUMERAL_TYPE)
7888e4b17023SJohn Marino {
7889e4b17023SJohn Marino tree checktype = origtype != NULL_TREE ? origtype : TREE_TYPE (value);
7890e4b17023SJohn Marino if (checktype != error_mark_node
7891e4b17023SJohn Marino && (TYPE_MAIN_VARIANT (checktype)
7892e4b17023SJohn Marino != TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field))))
7893e4b17023SJohn Marino warning_init (OPT_Wc___compat,
7894e4b17023SJohn Marino "enum conversion in initialization is invalid in C++");
7895e4b17023SJohn Marino }
7896e4b17023SJohn Marino
7897e4b17023SJohn Marino /* If this field is empty (and not at the end of structure),
7898e4b17023SJohn Marino don't do anything other than checking the initializer. */
7899e4b17023SJohn Marino if (field
7900e4b17023SJohn Marino && (TREE_TYPE (field) == error_mark_node
7901e4b17023SJohn Marino || (COMPLETE_TYPE_P (TREE_TYPE (field))
7902e4b17023SJohn Marino && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))
7903e4b17023SJohn Marino && (TREE_CODE (constructor_type) == ARRAY_TYPE
7904e4b17023SJohn Marino || DECL_CHAIN (field)))))
7905e4b17023SJohn Marino return;
7906e4b17023SJohn Marino
7907e4b17023SJohn Marino if (semantic_type)
7908e4b17023SJohn Marino value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value);
7909e4b17023SJohn Marino value = digest_init (input_location, type, value, origtype, npc,
7910e4b17023SJohn Marino strict_string, require_constant_value);
7911e4b17023SJohn Marino if (value == error_mark_node)
7912e4b17023SJohn Marino {
7913e4b17023SJohn Marino constructor_erroneous = 1;
7914e4b17023SJohn Marino return;
7915e4b17023SJohn Marino }
7916e4b17023SJohn Marino if (require_constant_value || require_constant_elements)
7917e4b17023SJohn Marino constant_expression_warning (value);
7918e4b17023SJohn Marino
7919e4b17023SJohn Marino /* If this element doesn't come next in sequence,
7920e4b17023SJohn Marino put it on constructor_pending_elts. */
7921e4b17023SJohn Marino if (TREE_CODE (constructor_type) == ARRAY_TYPE
7922e4b17023SJohn Marino && (!constructor_incremental
7923e4b17023SJohn Marino || !tree_int_cst_equal (field, constructor_unfilled_index)))
7924e4b17023SJohn Marino {
7925e4b17023SJohn Marino if (constructor_incremental
7926e4b17023SJohn Marino && tree_int_cst_lt (field, constructor_unfilled_index))
7927e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
7928e4b17023SJohn Marino
7929e4b17023SJohn Marino add_pending_init (field, value, origtype, implicit,
7930e4b17023SJohn Marino braced_init_obstack);
7931e4b17023SJohn Marino return;
7932e4b17023SJohn Marino }
7933e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == RECORD_TYPE
7934e4b17023SJohn Marino && (!constructor_incremental
7935e4b17023SJohn Marino || field != constructor_unfilled_fields))
7936e4b17023SJohn Marino {
7937e4b17023SJohn Marino /* We do this for records but not for unions. In a union,
7938e4b17023SJohn Marino no matter which field is specified, it can be initialized
7939e4b17023SJohn Marino right away since it starts at the beginning of the union. */
7940e4b17023SJohn Marino if (constructor_incremental)
7941e4b17023SJohn Marino {
7942e4b17023SJohn Marino if (!constructor_unfilled_fields)
7943e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
7944e4b17023SJohn Marino else
7945e4b17023SJohn Marino {
7946e4b17023SJohn Marino tree bitpos, unfillpos;
7947e4b17023SJohn Marino
7948e4b17023SJohn Marino bitpos = bit_position (field);
7949e4b17023SJohn Marino unfillpos = bit_position (constructor_unfilled_fields);
7950e4b17023SJohn Marino
7951e4b17023SJohn Marino if (tree_int_cst_lt (bitpos, unfillpos))
7952e4b17023SJohn Marino set_nonincremental_init (braced_init_obstack);
7953e4b17023SJohn Marino }
7954e4b17023SJohn Marino }
7955e4b17023SJohn Marino
7956e4b17023SJohn Marino add_pending_init (field, value, origtype, implicit,
7957e4b17023SJohn Marino braced_init_obstack);
7958e4b17023SJohn Marino return;
7959e4b17023SJohn Marino }
7960e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == UNION_TYPE
7961e4b17023SJohn Marino && !VEC_empty (constructor_elt, constructor_elements))
7962e4b17023SJohn Marino {
7963e4b17023SJohn Marino if (!implicit)
7964e4b17023SJohn Marino {
7965e4b17023SJohn Marino if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
7966e4b17023SJohn Marino constructor_elements)->value))
7967e4b17023SJohn Marino warning_init (0,
7968e4b17023SJohn Marino "initialized field with side-effects overwritten");
7969e4b17023SJohn Marino else if (warn_override_init)
7970e4b17023SJohn Marino warning_init (OPT_Woverride_init, "initialized field overwritten");
7971e4b17023SJohn Marino }
7972e4b17023SJohn Marino
7973e4b17023SJohn Marino /* We can have just one union field set. */
7974e4b17023SJohn Marino constructor_elements = 0;
7975e4b17023SJohn Marino }
7976e4b17023SJohn Marino
7977e4b17023SJohn Marino /* Otherwise, output this element either to
7978e4b17023SJohn Marino constructor_elements or to the assembler file. */
7979e4b17023SJohn Marino
7980e4b17023SJohn Marino celt = VEC_safe_push (constructor_elt, gc, constructor_elements, NULL);
7981e4b17023SJohn Marino celt->index = field;
7982e4b17023SJohn Marino celt->value = value;
7983e4b17023SJohn Marino
7984e4b17023SJohn Marino /* Advance the variable that indicates sequential elements output. */
7985e4b17023SJohn Marino if (TREE_CODE (constructor_type) == ARRAY_TYPE)
7986e4b17023SJohn Marino constructor_unfilled_index
7987e4b17023SJohn Marino = size_binop_loc (input_location, PLUS_EXPR, constructor_unfilled_index,
7988e4b17023SJohn Marino bitsize_one_node);
7989e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == RECORD_TYPE)
7990e4b17023SJohn Marino {
7991e4b17023SJohn Marino constructor_unfilled_fields
7992e4b17023SJohn Marino = DECL_CHAIN (constructor_unfilled_fields);
7993e4b17023SJohn Marino
7994e4b17023SJohn Marino /* Skip any nameless bit fields. */
7995e4b17023SJohn Marino while (constructor_unfilled_fields != 0
7996e4b17023SJohn Marino && DECL_C_BIT_FIELD (constructor_unfilled_fields)
7997e4b17023SJohn Marino && DECL_NAME (constructor_unfilled_fields) == 0)
7998e4b17023SJohn Marino constructor_unfilled_fields =
7999e4b17023SJohn Marino DECL_CHAIN (constructor_unfilled_fields);
8000e4b17023SJohn Marino }
8001e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == UNION_TYPE)
8002e4b17023SJohn Marino constructor_unfilled_fields = 0;
8003e4b17023SJohn Marino
8004e4b17023SJohn Marino /* Now output any pending elements which have become next. */
8005e4b17023SJohn Marino if (pending)
8006e4b17023SJohn Marino output_pending_init_elements (0, braced_init_obstack);
8007e4b17023SJohn Marino }
8008e4b17023SJohn Marino
8009e4b17023SJohn Marino /* Output any pending elements which have become next.
8010e4b17023SJohn Marino As we output elements, constructor_unfilled_{fields,index}
8011e4b17023SJohn Marino advances, which may cause other elements to become next;
8012e4b17023SJohn Marino if so, they too are output.
8013e4b17023SJohn Marino
8014e4b17023SJohn Marino If ALL is 0, we return when there are
8015e4b17023SJohn Marino no more pending elements to output now.
8016e4b17023SJohn Marino
8017e4b17023SJohn Marino If ALL is 1, we output space as necessary so that
8018e4b17023SJohn Marino we can output all the pending elements. */
8019e4b17023SJohn Marino static void
output_pending_init_elements(int all,struct obstack * braced_init_obstack)8020e4b17023SJohn Marino output_pending_init_elements (int all, struct obstack * braced_init_obstack)
8021e4b17023SJohn Marino {
8022e4b17023SJohn Marino struct init_node *elt = constructor_pending_elts;
8023e4b17023SJohn Marino tree next;
8024e4b17023SJohn Marino
8025e4b17023SJohn Marino retry:
8026e4b17023SJohn Marino
8027e4b17023SJohn Marino /* Look through the whole pending tree.
8028e4b17023SJohn Marino If we find an element that should be output now,
8029e4b17023SJohn Marino output it. Otherwise, set NEXT to the element
8030e4b17023SJohn Marino that comes first among those still pending. */
8031e4b17023SJohn Marino
8032e4b17023SJohn Marino next = 0;
8033e4b17023SJohn Marino while (elt)
8034e4b17023SJohn Marino {
8035e4b17023SJohn Marino if (TREE_CODE (constructor_type) == ARRAY_TYPE)
8036e4b17023SJohn Marino {
8037e4b17023SJohn Marino if (tree_int_cst_equal (elt->purpose,
8038e4b17023SJohn Marino constructor_unfilled_index))
8039e4b17023SJohn Marino output_init_element (elt->value, elt->origtype, true,
8040e4b17023SJohn Marino TREE_TYPE (constructor_type),
8041e4b17023SJohn Marino constructor_unfilled_index, 0, false,
8042e4b17023SJohn Marino braced_init_obstack);
8043e4b17023SJohn Marino else if (tree_int_cst_lt (constructor_unfilled_index,
8044e4b17023SJohn Marino elt->purpose))
8045e4b17023SJohn Marino {
8046e4b17023SJohn Marino /* Advance to the next smaller node. */
8047e4b17023SJohn Marino if (elt->left)
8048e4b17023SJohn Marino elt = elt->left;
8049e4b17023SJohn Marino else
8050e4b17023SJohn Marino {
8051e4b17023SJohn Marino /* We have reached the smallest node bigger than the
8052e4b17023SJohn Marino current unfilled index. Fill the space first. */
8053e4b17023SJohn Marino next = elt->purpose;
8054e4b17023SJohn Marino break;
8055e4b17023SJohn Marino }
8056e4b17023SJohn Marino }
8057e4b17023SJohn Marino else
8058e4b17023SJohn Marino {
8059e4b17023SJohn Marino /* Advance to the next bigger node. */
8060e4b17023SJohn Marino if (elt->right)
8061e4b17023SJohn Marino elt = elt->right;
8062e4b17023SJohn Marino else
8063e4b17023SJohn Marino {
8064e4b17023SJohn Marino /* We have reached the biggest node in a subtree. Find
8065e4b17023SJohn Marino the parent of it, which is the next bigger node. */
8066e4b17023SJohn Marino while (elt->parent && elt->parent->right == elt)
8067e4b17023SJohn Marino elt = elt->parent;
8068e4b17023SJohn Marino elt = elt->parent;
8069e4b17023SJohn Marino if (elt && tree_int_cst_lt (constructor_unfilled_index,
8070e4b17023SJohn Marino elt->purpose))
8071e4b17023SJohn Marino {
8072e4b17023SJohn Marino next = elt->purpose;
8073e4b17023SJohn Marino break;
8074e4b17023SJohn Marino }
8075e4b17023SJohn Marino }
8076e4b17023SJohn Marino }
8077e4b17023SJohn Marino }
8078e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == RECORD_TYPE
8079e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
8080e4b17023SJohn Marino {
8081e4b17023SJohn Marino tree ctor_unfilled_bitpos, elt_bitpos;
8082e4b17023SJohn Marino
8083e4b17023SJohn Marino /* If the current record is complete we are done. */
8084e4b17023SJohn Marino if (constructor_unfilled_fields == 0)
8085e4b17023SJohn Marino break;
8086e4b17023SJohn Marino
8087e4b17023SJohn Marino ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields);
8088e4b17023SJohn Marino elt_bitpos = bit_position (elt->purpose);
8089e4b17023SJohn Marino /* We can't compare fields here because there might be empty
8090e4b17023SJohn Marino fields in between. */
8091e4b17023SJohn Marino if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
8092e4b17023SJohn Marino {
8093e4b17023SJohn Marino constructor_unfilled_fields = elt->purpose;
8094e4b17023SJohn Marino output_init_element (elt->value, elt->origtype, true,
8095e4b17023SJohn Marino TREE_TYPE (elt->purpose),
8096e4b17023SJohn Marino elt->purpose, 0, false,
8097e4b17023SJohn Marino braced_init_obstack);
8098e4b17023SJohn Marino }
8099e4b17023SJohn Marino else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
8100e4b17023SJohn Marino {
8101e4b17023SJohn Marino /* Advance to the next smaller node. */
8102e4b17023SJohn Marino if (elt->left)
8103e4b17023SJohn Marino elt = elt->left;
8104e4b17023SJohn Marino else
8105e4b17023SJohn Marino {
8106e4b17023SJohn Marino /* We have reached the smallest node bigger than the
8107e4b17023SJohn Marino current unfilled field. Fill the space first. */
8108e4b17023SJohn Marino next = elt->purpose;
8109e4b17023SJohn Marino break;
8110e4b17023SJohn Marino }
8111e4b17023SJohn Marino }
8112e4b17023SJohn Marino else
8113e4b17023SJohn Marino {
8114e4b17023SJohn Marino /* Advance to the next bigger node. */
8115e4b17023SJohn Marino if (elt->right)
8116e4b17023SJohn Marino elt = elt->right;
8117e4b17023SJohn Marino else
8118e4b17023SJohn Marino {
8119e4b17023SJohn Marino /* We have reached the biggest node in a subtree. Find
8120e4b17023SJohn Marino the parent of it, which is the next bigger node. */
8121e4b17023SJohn Marino while (elt->parent && elt->parent->right == elt)
8122e4b17023SJohn Marino elt = elt->parent;
8123e4b17023SJohn Marino elt = elt->parent;
8124e4b17023SJohn Marino if (elt
8125e4b17023SJohn Marino && (tree_int_cst_lt (ctor_unfilled_bitpos,
8126e4b17023SJohn Marino bit_position (elt->purpose))))
8127e4b17023SJohn Marino {
8128e4b17023SJohn Marino next = elt->purpose;
8129e4b17023SJohn Marino break;
8130e4b17023SJohn Marino }
8131e4b17023SJohn Marino }
8132e4b17023SJohn Marino }
8133e4b17023SJohn Marino }
8134e4b17023SJohn Marino }
8135e4b17023SJohn Marino
8136e4b17023SJohn Marino /* Ordinarily return, but not if we want to output all
8137e4b17023SJohn Marino and there are elements left. */
8138e4b17023SJohn Marino if (!(all && next != 0))
8139e4b17023SJohn Marino return;
8140e4b17023SJohn Marino
8141e4b17023SJohn Marino /* If it's not incremental, just skip over the gap, so that after
8142e4b17023SJohn Marino jumping to retry we will output the next successive element. */
8143e4b17023SJohn Marino if (TREE_CODE (constructor_type) == RECORD_TYPE
8144e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
8145e4b17023SJohn Marino constructor_unfilled_fields = next;
8146e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
8147e4b17023SJohn Marino constructor_unfilled_index = next;
8148e4b17023SJohn Marino
8149e4b17023SJohn Marino /* ELT now points to the node in the pending tree with the next
8150e4b17023SJohn Marino initializer to output. */
8151e4b17023SJohn Marino goto retry;
8152e4b17023SJohn Marino }
8153e4b17023SJohn Marino
8154e4b17023SJohn Marino /* Add one non-braced element to the current constructor level.
8155e4b17023SJohn Marino This adjusts the current position within the constructor's type.
8156e4b17023SJohn Marino This may also start or terminate implicit levels
8157e4b17023SJohn Marino to handle a partly-braced initializer.
8158e4b17023SJohn Marino
8159e4b17023SJohn Marino Once this has found the correct level for the new element,
8160e4b17023SJohn Marino it calls output_init_element.
8161e4b17023SJohn Marino
8162e4b17023SJohn Marino IMPLICIT is true if value comes from pop_init_level (1),
8163e4b17023SJohn Marino the new initializer has been merged with the existing one
8164e4b17023SJohn Marino and thus no warnings should be emitted about overriding an
8165e4b17023SJohn Marino existing initializer. */
8166e4b17023SJohn Marino
8167e4b17023SJohn Marino void
process_init_element(struct c_expr value,bool implicit,struct obstack * braced_init_obstack)8168e4b17023SJohn Marino process_init_element (struct c_expr value, bool implicit,
8169e4b17023SJohn Marino struct obstack * braced_init_obstack)
8170e4b17023SJohn Marino {
8171e4b17023SJohn Marino tree orig_value = value.value;
8172e4b17023SJohn Marino int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
8173e4b17023SJohn Marino bool strict_string = value.original_code == STRING_CST;
8174e4b17023SJohn Marino
8175e4b17023SJohn Marino designator_depth = 0;
8176e4b17023SJohn Marino designator_erroneous = 0;
8177e4b17023SJohn Marino
8178e4b17023SJohn Marino /* Handle superfluous braces around string cst as in
8179e4b17023SJohn Marino char x[] = {"foo"}; */
8180e4b17023SJohn Marino if (string_flag
8181e4b17023SJohn Marino && constructor_type
8182e4b17023SJohn Marino && TREE_CODE (constructor_type) == ARRAY_TYPE
8183e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (constructor_type))
8184e4b17023SJohn Marino && integer_zerop (constructor_unfilled_index))
8185e4b17023SJohn Marino {
8186e4b17023SJohn Marino if (constructor_stack->replacement_value.value)
8187e4b17023SJohn Marino error_init ("excess elements in char array initializer");
8188e4b17023SJohn Marino constructor_stack->replacement_value = value;
8189e4b17023SJohn Marino return;
8190e4b17023SJohn Marino }
8191e4b17023SJohn Marino
8192e4b17023SJohn Marino if (constructor_stack->replacement_value.value != 0)
8193e4b17023SJohn Marino {
8194e4b17023SJohn Marino error_init ("excess elements in struct initializer");
8195e4b17023SJohn Marino return;
8196e4b17023SJohn Marino }
8197e4b17023SJohn Marino
8198e4b17023SJohn Marino /* Ignore elements of a brace group if it is entirely superfluous
8199e4b17023SJohn Marino and has already been diagnosed. */
8200e4b17023SJohn Marino if (constructor_type == 0)
8201e4b17023SJohn Marino return;
8202e4b17023SJohn Marino
8203e4b17023SJohn Marino /* If we've exhausted any levels that didn't have braces,
8204e4b17023SJohn Marino pop them now. */
8205e4b17023SJohn Marino while (constructor_stack->implicit)
8206e4b17023SJohn Marino {
8207e4b17023SJohn Marino if ((TREE_CODE (constructor_type) == RECORD_TYPE
8208e4b17023SJohn Marino || TREE_CODE (constructor_type) == UNION_TYPE)
8209e4b17023SJohn Marino && constructor_fields == 0)
8210e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
8211e4b17023SJohn Marino true, braced_init_obstack);
8212e4b17023SJohn Marino else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
8213e4b17023SJohn Marino || TREE_CODE (constructor_type) == VECTOR_TYPE)
8214e4b17023SJohn Marino && (constructor_max_index == 0
8215e4b17023SJohn Marino || tree_int_cst_lt (constructor_max_index,
8216e4b17023SJohn Marino constructor_index)))
8217e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
8218e4b17023SJohn Marino true, braced_init_obstack);
8219e4b17023SJohn Marino else
8220e4b17023SJohn Marino break;
8221e4b17023SJohn Marino }
8222e4b17023SJohn Marino
8223e4b17023SJohn Marino /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once. */
8224e4b17023SJohn Marino if (constructor_range_stack)
8225e4b17023SJohn Marino {
8226e4b17023SJohn Marino /* If value is a compound literal and we'll be just using its
8227e4b17023SJohn Marino content, don't put it into a SAVE_EXPR. */
8228e4b17023SJohn Marino if (TREE_CODE (value.value) != COMPOUND_LITERAL_EXPR
8229e4b17023SJohn Marino || !require_constant_value
8230e4b17023SJohn Marino || flag_isoc99)
8231e4b17023SJohn Marino {
8232e4b17023SJohn Marino tree semantic_type = NULL_TREE;
8233e4b17023SJohn Marino if (TREE_CODE (value.value) == EXCESS_PRECISION_EXPR)
8234e4b17023SJohn Marino {
8235e4b17023SJohn Marino semantic_type = TREE_TYPE (value.value);
8236e4b17023SJohn Marino value.value = TREE_OPERAND (value.value, 0);
8237e4b17023SJohn Marino }
8238e4b17023SJohn Marino value.value = c_save_expr (value.value);
8239e4b17023SJohn Marino if (semantic_type)
8240e4b17023SJohn Marino value.value = build1 (EXCESS_PRECISION_EXPR, semantic_type,
8241e4b17023SJohn Marino value.value);
8242e4b17023SJohn Marino }
8243e4b17023SJohn Marino }
8244e4b17023SJohn Marino
8245e4b17023SJohn Marino while (1)
8246e4b17023SJohn Marino {
8247e4b17023SJohn Marino if (TREE_CODE (constructor_type) == RECORD_TYPE)
8248e4b17023SJohn Marino {
8249e4b17023SJohn Marino tree fieldtype;
8250e4b17023SJohn Marino enum tree_code fieldcode;
8251e4b17023SJohn Marino
8252e4b17023SJohn Marino if (constructor_fields == 0)
8253e4b17023SJohn Marino {
8254e4b17023SJohn Marino pedwarn_init (input_location, 0,
8255e4b17023SJohn Marino "excess elements in struct initializer");
8256e4b17023SJohn Marino break;
8257e4b17023SJohn Marino }
8258e4b17023SJohn Marino
8259e4b17023SJohn Marino fieldtype = TREE_TYPE (constructor_fields);
8260e4b17023SJohn Marino if (fieldtype != error_mark_node)
8261e4b17023SJohn Marino fieldtype = TYPE_MAIN_VARIANT (fieldtype);
8262e4b17023SJohn Marino fieldcode = TREE_CODE (fieldtype);
8263e4b17023SJohn Marino
8264e4b17023SJohn Marino /* Error for non-static initialization of a flexible array member. */
8265e4b17023SJohn Marino if (fieldcode == ARRAY_TYPE
8266e4b17023SJohn Marino && !require_constant_value
8267e4b17023SJohn Marino && TYPE_SIZE (fieldtype) == NULL_TREE
8268e4b17023SJohn Marino && DECL_CHAIN (constructor_fields) == NULL_TREE)
8269e4b17023SJohn Marino {
8270e4b17023SJohn Marino error_init ("non-static initialization of a flexible array member");
8271e4b17023SJohn Marino break;
8272e4b17023SJohn Marino }
8273e4b17023SJohn Marino
8274e4b17023SJohn Marino /* Accept a string constant to initialize a subarray. */
8275e4b17023SJohn Marino if (value.value != 0
8276e4b17023SJohn Marino && fieldcode == ARRAY_TYPE
8277e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (fieldtype))
8278e4b17023SJohn Marino && string_flag)
8279e4b17023SJohn Marino value.value = orig_value;
8280e4b17023SJohn Marino /* Otherwise, if we have come to a subaggregate,
8281e4b17023SJohn Marino and we don't have an element of its type, push into it. */
8282e4b17023SJohn Marino else if (value.value != 0
8283e4b17023SJohn Marino && value.value != error_mark_node
8284e4b17023SJohn Marino && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
8285e4b17023SJohn Marino && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
8286e4b17023SJohn Marino || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
8287e4b17023SJohn Marino {
8288e4b17023SJohn Marino push_init_level (1, braced_init_obstack);
8289e4b17023SJohn Marino continue;
8290e4b17023SJohn Marino }
8291e4b17023SJohn Marino
8292e4b17023SJohn Marino if (value.value)
8293e4b17023SJohn Marino {
8294e4b17023SJohn Marino push_member_name (constructor_fields);
8295e4b17023SJohn Marino output_init_element (value.value, value.original_type,
8296e4b17023SJohn Marino strict_string, fieldtype,
8297e4b17023SJohn Marino constructor_fields, 1, implicit,
8298e4b17023SJohn Marino braced_init_obstack);
8299e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (constructor_depth);
8300e4b17023SJohn Marino }
8301e4b17023SJohn Marino else
8302e4b17023SJohn Marino /* Do the bookkeeping for an element that was
8303e4b17023SJohn Marino directly output as a constructor. */
8304e4b17023SJohn Marino {
8305e4b17023SJohn Marino /* For a record, keep track of end position of last field. */
8306e4b17023SJohn Marino if (DECL_SIZE (constructor_fields))
8307e4b17023SJohn Marino constructor_bit_index
8308e4b17023SJohn Marino = size_binop_loc (input_location, PLUS_EXPR,
8309e4b17023SJohn Marino bit_position (constructor_fields),
8310e4b17023SJohn Marino DECL_SIZE (constructor_fields));
8311e4b17023SJohn Marino
8312e4b17023SJohn Marino /* If the current field was the first one not yet written out,
8313e4b17023SJohn Marino it isn't now, so update. */
8314e4b17023SJohn Marino if (constructor_unfilled_fields == constructor_fields)
8315e4b17023SJohn Marino {
8316e4b17023SJohn Marino constructor_unfilled_fields = DECL_CHAIN (constructor_fields);
8317e4b17023SJohn Marino /* Skip any nameless bit fields. */
8318e4b17023SJohn Marino while (constructor_unfilled_fields != 0
8319e4b17023SJohn Marino && DECL_C_BIT_FIELD (constructor_unfilled_fields)
8320e4b17023SJohn Marino && DECL_NAME (constructor_unfilled_fields) == 0)
8321e4b17023SJohn Marino constructor_unfilled_fields =
8322e4b17023SJohn Marino DECL_CHAIN (constructor_unfilled_fields);
8323e4b17023SJohn Marino }
8324e4b17023SJohn Marino }
8325e4b17023SJohn Marino
8326e4b17023SJohn Marino constructor_fields = DECL_CHAIN (constructor_fields);
8327e4b17023SJohn Marino /* Skip any nameless bit fields at the beginning. */
8328e4b17023SJohn Marino while (constructor_fields != 0
8329e4b17023SJohn Marino && DECL_C_BIT_FIELD (constructor_fields)
8330e4b17023SJohn Marino && DECL_NAME (constructor_fields) == 0)
8331e4b17023SJohn Marino constructor_fields = DECL_CHAIN (constructor_fields);
8332e4b17023SJohn Marino }
8333e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == UNION_TYPE)
8334e4b17023SJohn Marino {
8335e4b17023SJohn Marino tree fieldtype;
8336e4b17023SJohn Marino enum tree_code fieldcode;
8337e4b17023SJohn Marino
8338e4b17023SJohn Marino if (constructor_fields == 0)
8339e4b17023SJohn Marino {
8340e4b17023SJohn Marino pedwarn_init (input_location, 0,
8341e4b17023SJohn Marino "excess elements in union initializer");
8342e4b17023SJohn Marino break;
8343e4b17023SJohn Marino }
8344e4b17023SJohn Marino
8345e4b17023SJohn Marino fieldtype = TREE_TYPE (constructor_fields);
8346e4b17023SJohn Marino if (fieldtype != error_mark_node)
8347e4b17023SJohn Marino fieldtype = TYPE_MAIN_VARIANT (fieldtype);
8348e4b17023SJohn Marino fieldcode = TREE_CODE (fieldtype);
8349e4b17023SJohn Marino
8350e4b17023SJohn Marino /* Warn that traditional C rejects initialization of unions.
8351e4b17023SJohn Marino We skip the warning if the value is zero. This is done
8352e4b17023SJohn Marino under the assumption that the zero initializer in user
8353e4b17023SJohn Marino code appears conditioned on e.g. __STDC__ to avoid
8354e4b17023SJohn Marino "missing initializer" warnings and relies on default
8355e4b17023SJohn Marino initialization to zero in the traditional C case.
8356e4b17023SJohn Marino We also skip the warning if the initializer is designated,
8357e4b17023SJohn Marino again on the assumption that this must be conditional on
8358e4b17023SJohn Marino __STDC__ anyway (and we've already complained about the
8359e4b17023SJohn Marino member-designator already). */
8360e4b17023SJohn Marino if (!in_system_header && !constructor_designated
8361e4b17023SJohn Marino && !(value.value && (integer_zerop (value.value)
8362e4b17023SJohn Marino || real_zerop (value.value))))
8363e4b17023SJohn Marino warning (OPT_Wtraditional, "traditional C rejects initialization "
8364e4b17023SJohn Marino "of unions");
8365e4b17023SJohn Marino
8366e4b17023SJohn Marino /* Accept a string constant to initialize a subarray. */
8367e4b17023SJohn Marino if (value.value != 0
8368e4b17023SJohn Marino && fieldcode == ARRAY_TYPE
8369e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (fieldtype))
8370e4b17023SJohn Marino && string_flag)
8371e4b17023SJohn Marino value.value = orig_value;
8372e4b17023SJohn Marino /* Otherwise, if we have come to a subaggregate,
8373e4b17023SJohn Marino and we don't have an element of its type, push into it. */
8374e4b17023SJohn Marino else if (value.value != 0
8375e4b17023SJohn Marino && value.value != error_mark_node
8376e4b17023SJohn Marino && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
8377e4b17023SJohn Marino && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
8378e4b17023SJohn Marino || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE))
8379e4b17023SJohn Marino {
8380e4b17023SJohn Marino push_init_level (1, braced_init_obstack);
8381e4b17023SJohn Marino continue;
8382e4b17023SJohn Marino }
8383e4b17023SJohn Marino
8384e4b17023SJohn Marino if (value.value)
8385e4b17023SJohn Marino {
8386e4b17023SJohn Marino push_member_name (constructor_fields);
8387e4b17023SJohn Marino output_init_element (value.value, value.original_type,
8388e4b17023SJohn Marino strict_string, fieldtype,
8389e4b17023SJohn Marino constructor_fields, 1, implicit,
8390e4b17023SJohn Marino braced_init_obstack);
8391e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (constructor_depth);
8392e4b17023SJohn Marino }
8393e4b17023SJohn Marino else
8394e4b17023SJohn Marino /* Do the bookkeeping for an element that was
8395e4b17023SJohn Marino directly output as a constructor. */
8396e4b17023SJohn Marino {
8397e4b17023SJohn Marino constructor_bit_index = DECL_SIZE (constructor_fields);
8398e4b17023SJohn Marino constructor_unfilled_fields = DECL_CHAIN (constructor_fields);
8399e4b17023SJohn Marino }
8400e4b17023SJohn Marino
8401e4b17023SJohn Marino constructor_fields = 0;
8402e4b17023SJohn Marino }
8403e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
8404e4b17023SJohn Marino {
8405e4b17023SJohn Marino tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
8406e4b17023SJohn Marino enum tree_code eltcode = TREE_CODE (elttype);
8407e4b17023SJohn Marino
8408e4b17023SJohn Marino /* Accept a string constant to initialize a subarray. */
8409e4b17023SJohn Marino if (value.value != 0
8410e4b17023SJohn Marino && eltcode == ARRAY_TYPE
8411e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (elttype))
8412e4b17023SJohn Marino && string_flag)
8413e4b17023SJohn Marino value.value = orig_value;
8414e4b17023SJohn Marino /* Otherwise, if we have come to a subaggregate,
8415e4b17023SJohn Marino and we don't have an element of its type, push into it. */
8416e4b17023SJohn Marino else if (value.value != 0
8417e4b17023SJohn Marino && value.value != error_mark_node
8418e4b17023SJohn Marino && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype
8419e4b17023SJohn Marino && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
8420e4b17023SJohn Marino || eltcode == UNION_TYPE || eltcode == VECTOR_TYPE))
8421e4b17023SJohn Marino {
8422e4b17023SJohn Marino push_init_level (1, braced_init_obstack);
8423e4b17023SJohn Marino continue;
8424e4b17023SJohn Marino }
8425e4b17023SJohn Marino
8426e4b17023SJohn Marino if (constructor_max_index != 0
8427e4b17023SJohn Marino && (tree_int_cst_lt (constructor_max_index, constructor_index)
8428e4b17023SJohn Marino || integer_all_onesp (constructor_max_index)))
8429e4b17023SJohn Marino {
8430e4b17023SJohn Marino pedwarn_init (input_location, 0,
8431e4b17023SJohn Marino "excess elements in array initializer");
8432e4b17023SJohn Marino break;
8433e4b17023SJohn Marino }
8434e4b17023SJohn Marino
8435e4b17023SJohn Marino /* Now output the actual element. */
8436e4b17023SJohn Marino if (value.value)
8437e4b17023SJohn Marino {
8438e4b17023SJohn Marino push_array_bounds (tree_low_cst (constructor_index, 1));
8439e4b17023SJohn Marino output_init_element (value.value, value.original_type,
8440e4b17023SJohn Marino strict_string, elttype,
8441e4b17023SJohn Marino constructor_index, 1, implicit,
8442e4b17023SJohn Marino braced_init_obstack);
8443e4b17023SJohn Marino RESTORE_SPELLING_DEPTH (constructor_depth);
8444e4b17023SJohn Marino }
8445e4b17023SJohn Marino
8446e4b17023SJohn Marino constructor_index
8447e4b17023SJohn Marino = size_binop_loc (input_location, PLUS_EXPR,
8448e4b17023SJohn Marino constructor_index, bitsize_one_node);
8449e4b17023SJohn Marino
8450e4b17023SJohn Marino if (!value.value)
8451e4b17023SJohn Marino /* If we are doing the bookkeeping for an element that was
8452e4b17023SJohn Marino directly output as a constructor, we must update
8453e4b17023SJohn Marino constructor_unfilled_index. */
8454e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
8455e4b17023SJohn Marino }
8456e4b17023SJohn Marino else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
8457e4b17023SJohn Marino {
8458e4b17023SJohn Marino tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
8459e4b17023SJohn Marino
8460e4b17023SJohn Marino /* Do a basic check of initializer size. Note that vectors
8461e4b17023SJohn Marino always have a fixed size derived from their type. */
8462e4b17023SJohn Marino if (tree_int_cst_lt (constructor_max_index, constructor_index))
8463e4b17023SJohn Marino {
8464e4b17023SJohn Marino pedwarn_init (input_location, 0,
8465e4b17023SJohn Marino "excess elements in vector initializer");
8466e4b17023SJohn Marino break;
8467e4b17023SJohn Marino }
8468e4b17023SJohn Marino
8469e4b17023SJohn Marino /* Now output the actual element. */
8470e4b17023SJohn Marino if (value.value)
8471e4b17023SJohn Marino {
8472e4b17023SJohn Marino if (TREE_CODE (value.value) == VECTOR_CST)
8473e4b17023SJohn Marino elttype = TYPE_MAIN_VARIANT (constructor_type);
8474e4b17023SJohn Marino output_init_element (value.value, value.original_type,
8475e4b17023SJohn Marino strict_string, elttype,
8476e4b17023SJohn Marino constructor_index, 1, implicit,
8477e4b17023SJohn Marino braced_init_obstack);
8478e4b17023SJohn Marino }
8479e4b17023SJohn Marino
8480e4b17023SJohn Marino constructor_index
8481e4b17023SJohn Marino = size_binop_loc (input_location,
8482e4b17023SJohn Marino PLUS_EXPR, constructor_index, bitsize_one_node);
8483e4b17023SJohn Marino
8484e4b17023SJohn Marino if (!value.value)
8485e4b17023SJohn Marino /* If we are doing the bookkeeping for an element that was
8486e4b17023SJohn Marino directly output as a constructor, we must update
8487e4b17023SJohn Marino constructor_unfilled_index. */
8488e4b17023SJohn Marino constructor_unfilled_index = constructor_index;
8489e4b17023SJohn Marino }
8490e4b17023SJohn Marino
8491e4b17023SJohn Marino /* Handle the sole element allowed in a braced initializer
8492e4b17023SJohn Marino for a scalar variable. */
8493e4b17023SJohn Marino else if (constructor_type != error_mark_node
8494e4b17023SJohn Marino && constructor_fields == 0)
8495e4b17023SJohn Marino {
8496e4b17023SJohn Marino pedwarn_init (input_location, 0,
8497e4b17023SJohn Marino "excess elements in scalar initializer");
8498e4b17023SJohn Marino break;
8499e4b17023SJohn Marino }
8500e4b17023SJohn Marino else
8501e4b17023SJohn Marino {
8502e4b17023SJohn Marino if (value.value)
8503e4b17023SJohn Marino output_init_element (value.value, value.original_type,
8504e4b17023SJohn Marino strict_string, constructor_type,
8505e4b17023SJohn Marino NULL_TREE, 1, implicit,
8506e4b17023SJohn Marino braced_init_obstack);
8507e4b17023SJohn Marino constructor_fields = 0;
8508e4b17023SJohn Marino }
8509e4b17023SJohn Marino
8510e4b17023SJohn Marino /* Handle range initializers either at this level or anywhere higher
8511e4b17023SJohn Marino in the designator stack. */
8512e4b17023SJohn Marino if (constructor_range_stack)
8513e4b17023SJohn Marino {
8514e4b17023SJohn Marino struct constructor_range_stack *p, *range_stack;
8515e4b17023SJohn Marino int finish = 0;
8516e4b17023SJohn Marino
8517e4b17023SJohn Marino range_stack = constructor_range_stack;
8518e4b17023SJohn Marino constructor_range_stack = 0;
8519e4b17023SJohn Marino while (constructor_stack != range_stack->stack)
8520e4b17023SJohn Marino {
8521e4b17023SJohn Marino gcc_assert (constructor_stack->implicit);
8522e4b17023SJohn Marino process_init_element (pop_init_level (1,
8523e4b17023SJohn Marino braced_init_obstack),
8524e4b17023SJohn Marino true, braced_init_obstack);
8525e4b17023SJohn Marino }
8526e4b17023SJohn Marino for (p = range_stack;
8527e4b17023SJohn Marino !p->range_end || tree_int_cst_equal (p->index, p->range_end);
8528e4b17023SJohn Marino p = p->prev)
8529e4b17023SJohn Marino {
8530e4b17023SJohn Marino gcc_assert (constructor_stack->implicit);
8531e4b17023SJohn Marino process_init_element (pop_init_level (1, braced_init_obstack),
8532e4b17023SJohn Marino true, braced_init_obstack);
8533e4b17023SJohn Marino }
8534e4b17023SJohn Marino
8535e4b17023SJohn Marino p->index = size_binop_loc (input_location,
8536e4b17023SJohn Marino PLUS_EXPR, p->index, bitsize_one_node);
8537e4b17023SJohn Marino if (tree_int_cst_equal (p->index, p->range_end) && !p->prev)
8538e4b17023SJohn Marino finish = 1;
8539e4b17023SJohn Marino
8540e4b17023SJohn Marino while (1)
8541e4b17023SJohn Marino {
8542e4b17023SJohn Marino constructor_index = p->index;
8543e4b17023SJohn Marino constructor_fields = p->fields;
8544e4b17023SJohn Marino if (finish && p->range_end && p->index == p->range_start)
8545e4b17023SJohn Marino {
8546e4b17023SJohn Marino finish = 0;
8547e4b17023SJohn Marino p->prev = 0;
8548e4b17023SJohn Marino }
8549e4b17023SJohn Marino p = p->next;
8550e4b17023SJohn Marino if (!p)
8551e4b17023SJohn Marino break;
8552e4b17023SJohn Marino push_init_level (2, braced_init_obstack);
8553e4b17023SJohn Marino p->stack = constructor_stack;
8554e4b17023SJohn Marino if (p->range_end && tree_int_cst_equal (p->index, p->range_end))
8555e4b17023SJohn Marino p->index = p->range_start;
8556e4b17023SJohn Marino }
8557e4b17023SJohn Marino
8558e4b17023SJohn Marino if (!finish)
8559e4b17023SJohn Marino constructor_range_stack = range_stack;
8560e4b17023SJohn Marino continue;
8561e4b17023SJohn Marino }
8562e4b17023SJohn Marino
8563e4b17023SJohn Marino break;
8564e4b17023SJohn Marino }
8565e4b17023SJohn Marino
8566e4b17023SJohn Marino constructor_range_stack = 0;
8567e4b17023SJohn Marino }
8568e4b17023SJohn Marino
8569e4b17023SJohn Marino /* Build a complete asm-statement, whose components are a CV_QUALIFIER
8570e4b17023SJohn Marino (guaranteed to be 'volatile' or null) and ARGS (represented using
8571e4b17023SJohn Marino an ASM_EXPR node). */
8572e4b17023SJohn Marino tree
build_asm_stmt(tree cv_qualifier,tree args)8573e4b17023SJohn Marino build_asm_stmt (tree cv_qualifier, tree args)
8574e4b17023SJohn Marino {
8575e4b17023SJohn Marino if (!ASM_VOLATILE_P (args) && cv_qualifier)
8576e4b17023SJohn Marino ASM_VOLATILE_P (args) = 1;
8577e4b17023SJohn Marino return add_stmt (args);
8578e4b17023SJohn Marino }
8579e4b17023SJohn Marino
8580e4b17023SJohn Marino /* Build an asm-expr, whose components are a STRING, some OUTPUTS,
8581e4b17023SJohn Marino some INPUTS, and some CLOBBERS. The latter three may be NULL.
8582e4b17023SJohn Marino SIMPLE indicates whether there was anything at all after the
8583e4b17023SJohn Marino string in the asm expression -- asm("blah") and asm("blah" : )
8584e4b17023SJohn Marino are subtly different. We use a ASM_EXPR node to represent this. */
8585e4b17023SJohn Marino tree
build_asm_expr(location_t loc,tree string,tree outputs,tree inputs,tree clobbers,tree labels,bool simple)8586e4b17023SJohn Marino build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
8587e4b17023SJohn Marino tree clobbers, tree labels, bool simple)
8588e4b17023SJohn Marino {
8589e4b17023SJohn Marino tree tail;
8590e4b17023SJohn Marino tree args;
8591e4b17023SJohn Marino int i;
8592e4b17023SJohn Marino const char *constraint;
8593e4b17023SJohn Marino const char **oconstraints;
8594e4b17023SJohn Marino bool allows_mem, allows_reg, is_inout;
8595e4b17023SJohn Marino int ninputs, noutputs;
8596e4b17023SJohn Marino
8597e4b17023SJohn Marino ninputs = list_length (inputs);
8598e4b17023SJohn Marino noutputs = list_length (outputs);
8599e4b17023SJohn Marino oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
8600e4b17023SJohn Marino
8601e4b17023SJohn Marino string = resolve_asm_operand_names (string, outputs, inputs, labels);
8602e4b17023SJohn Marino
8603e4b17023SJohn Marino /* Remove output conversions that change the type but not the mode. */
8604e4b17023SJohn Marino for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
8605e4b17023SJohn Marino {
8606e4b17023SJohn Marino tree output = TREE_VALUE (tail);
8607e4b17023SJohn Marino
8608e4b17023SJohn Marino /* ??? Really, this should not be here. Users should be using a
8609e4b17023SJohn Marino proper lvalue, dammit. But there's a long history of using casts
8610e4b17023SJohn Marino in the output operands. In cases like longlong.h, this becomes a
8611e4b17023SJohn Marino primitive form of typechecking -- if the cast can be removed, then
8612e4b17023SJohn Marino the output operand had a type of the proper width; otherwise we'll
8613e4b17023SJohn Marino get an error. Gross, but ... */
8614e4b17023SJohn Marino STRIP_NOPS (output);
8615e4b17023SJohn Marino
8616e4b17023SJohn Marino if (!lvalue_or_else (loc, output, lv_asm))
8617e4b17023SJohn Marino output = error_mark_node;
8618e4b17023SJohn Marino
8619e4b17023SJohn Marino if (output != error_mark_node
8620e4b17023SJohn Marino && (TREE_READONLY (output)
8621e4b17023SJohn Marino || TYPE_READONLY (TREE_TYPE (output))
8622e4b17023SJohn Marino || ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE
8623e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (output)) == UNION_TYPE)
8624e4b17023SJohn Marino && C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
8625e4b17023SJohn Marino readonly_error (output, lv_asm);
8626e4b17023SJohn Marino
8627e4b17023SJohn Marino constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
8628e4b17023SJohn Marino oconstraints[i] = constraint;
8629e4b17023SJohn Marino
8630e4b17023SJohn Marino if (parse_output_constraint (&constraint, i, ninputs, noutputs,
8631e4b17023SJohn Marino &allows_mem, &allows_reg, &is_inout))
8632e4b17023SJohn Marino {
8633e4b17023SJohn Marino /* If the operand is going to end up in memory,
8634e4b17023SJohn Marino mark it addressable. */
8635e4b17023SJohn Marino if (!allows_reg && !c_mark_addressable (output))
8636e4b17023SJohn Marino output = error_mark_node;
8637e4b17023SJohn Marino if (!(!allows_reg && allows_mem)
8638e4b17023SJohn Marino && output != error_mark_node
8639e4b17023SJohn Marino && VOID_TYPE_P (TREE_TYPE (output)))
8640e4b17023SJohn Marino {
8641e4b17023SJohn Marino error_at (loc, "invalid use of void expression");
8642e4b17023SJohn Marino output = error_mark_node;
8643e4b17023SJohn Marino }
8644e4b17023SJohn Marino }
8645e4b17023SJohn Marino else
8646e4b17023SJohn Marino output = error_mark_node;
8647e4b17023SJohn Marino
8648e4b17023SJohn Marino TREE_VALUE (tail) = output;
8649e4b17023SJohn Marino }
8650e4b17023SJohn Marino
8651e4b17023SJohn Marino for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
8652e4b17023SJohn Marino {
8653e4b17023SJohn Marino tree input;
8654e4b17023SJohn Marino
8655e4b17023SJohn Marino constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
8656e4b17023SJohn Marino input = TREE_VALUE (tail);
8657e4b17023SJohn Marino
8658e4b17023SJohn Marino if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
8659e4b17023SJohn Marino oconstraints, &allows_mem, &allows_reg))
8660e4b17023SJohn Marino {
8661e4b17023SJohn Marino /* If the operand is going to end up in memory,
8662e4b17023SJohn Marino mark it addressable. */
8663e4b17023SJohn Marino if (!allows_reg && allows_mem)
8664e4b17023SJohn Marino {
8665e4b17023SJohn Marino /* Strip the nops as we allow this case. FIXME, this really
8666e4b17023SJohn Marino should be rejected or made deprecated. */
8667e4b17023SJohn Marino STRIP_NOPS (input);
8668e4b17023SJohn Marino if (!c_mark_addressable (input))
8669e4b17023SJohn Marino input = error_mark_node;
8670e4b17023SJohn Marino }
8671e4b17023SJohn Marino else if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input)))
8672e4b17023SJohn Marino {
8673e4b17023SJohn Marino error_at (loc, "invalid use of void expression");
8674e4b17023SJohn Marino input = error_mark_node;
8675e4b17023SJohn Marino }
8676e4b17023SJohn Marino }
8677e4b17023SJohn Marino else
8678e4b17023SJohn Marino input = error_mark_node;
8679e4b17023SJohn Marino
8680e4b17023SJohn Marino TREE_VALUE (tail) = input;
8681e4b17023SJohn Marino }
8682e4b17023SJohn Marino
8683e4b17023SJohn Marino /* ASMs with labels cannot have outputs. This should have been
8684e4b17023SJohn Marino enforced by the parser. */
8685e4b17023SJohn Marino gcc_assert (outputs == NULL || labels == NULL);
8686e4b17023SJohn Marino
8687e4b17023SJohn Marino args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers, labels);
8688e4b17023SJohn Marino
8689e4b17023SJohn Marino /* asm statements without outputs, including simple ones, are treated
8690e4b17023SJohn Marino as volatile. */
8691e4b17023SJohn Marino ASM_INPUT_P (args) = simple;
8692e4b17023SJohn Marino ASM_VOLATILE_P (args) = (noutputs == 0);
8693e4b17023SJohn Marino
8694e4b17023SJohn Marino return args;
8695e4b17023SJohn Marino }
8696e4b17023SJohn Marino
8697e4b17023SJohn Marino /* Generate a goto statement to LABEL. LOC is the location of the
8698e4b17023SJohn Marino GOTO. */
8699e4b17023SJohn Marino
8700e4b17023SJohn Marino tree
c_finish_goto_label(location_t loc,tree label)8701e4b17023SJohn Marino c_finish_goto_label (location_t loc, tree label)
8702e4b17023SJohn Marino {
8703e4b17023SJohn Marino tree decl = lookup_label_for_goto (loc, label);
8704e4b17023SJohn Marino if (!decl)
8705e4b17023SJohn Marino return NULL_TREE;
8706e4b17023SJohn Marino TREE_USED (decl) = 1;
8707e4b17023SJohn Marino {
8708e4b17023SJohn Marino tree t = build1 (GOTO_EXPR, void_type_node, decl);
8709e4b17023SJohn Marino SET_EXPR_LOCATION (t, loc);
8710e4b17023SJohn Marino return add_stmt (t);
8711e4b17023SJohn Marino }
8712e4b17023SJohn Marino }
8713e4b17023SJohn Marino
8714e4b17023SJohn Marino /* Generate a computed goto statement to EXPR. LOC is the location of
8715e4b17023SJohn Marino the GOTO. */
8716e4b17023SJohn Marino
8717e4b17023SJohn Marino tree
c_finish_goto_ptr(location_t loc,tree expr)8718e4b17023SJohn Marino c_finish_goto_ptr (location_t loc, tree expr)
8719e4b17023SJohn Marino {
8720e4b17023SJohn Marino tree t;
8721e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C forbids %<goto *expr;%>");
8722e4b17023SJohn Marino expr = c_fully_fold (expr, false, NULL);
8723e4b17023SJohn Marino expr = convert (ptr_type_node, expr);
8724e4b17023SJohn Marino t = build1 (GOTO_EXPR, void_type_node, expr);
8725e4b17023SJohn Marino SET_EXPR_LOCATION (t, loc);
8726e4b17023SJohn Marino return add_stmt (t);
8727e4b17023SJohn Marino }
8728e4b17023SJohn Marino
8729e4b17023SJohn Marino /* Generate a C `return' statement. RETVAL is the expression for what
8730e4b17023SJohn Marino to return, or a null pointer for `return;' with no value. LOC is
8731e4b17023SJohn Marino the location of the return statement. If ORIGTYPE is not NULL_TREE, it
8732e4b17023SJohn Marino is the original type of RETVAL. */
8733e4b17023SJohn Marino
8734e4b17023SJohn Marino tree
c_finish_return(location_t loc,tree retval,tree origtype)8735e4b17023SJohn Marino c_finish_return (location_t loc, tree retval, tree origtype)
8736e4b17023SJohn Marino {
8737e4b17023SJohn Marino tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
8738e4b17023SJohn Marino bool no_warning = false;
8739e4b17023SJohn Marino bool npc = false;
8740e4b17023SJohn Marino
8741e4b17023SJohn Marino if (TREE_THIS_VOLATILE (current_function_decl))
8742e4b17023SJohn Marino warning_at (loc, 0,
8743e4b17023SJohn Marino "function declared %<noreturn%> has a %<return%> statement");
8744e4b17023SJohn Marino
8745e4b17023SJohn Marino if (retval)
8746e4b17023SJohn Marino {
8747e4b17023SJohn Marino tree semantic_type = NULL_TREE;
8748e4b17023SJohn Marino npc = null_pointer_constant_p (retval);
8749e4b17023SJohn Marino if (TREE_CODE (retval) == EXCESS_PRECISION_EXPR)
8750e4b17023SJohn Marino {
8751e4b17023SJohn Marino semantic_type = TREE_TYPE (retval);
8752e4b17023SJohn Marino retval = TREE_OPERAND (retval, 0);
8753e4b17023SJohn Marino }
8754e4b17023SJohn Marino retval = c_fully_fold (retval, false, NULL);
8755e4b17023SJohn Marino if (semantic_type)
8756e4b17023SJohn Marino retval = build1 (EXCESS_PRECISION_EXPR, semantic_type, retval);
8757e4b17023SJohn Marino }
8758e4b17023SJohn Marino
8759e4b17023SJohn Marino if (!retval)
8760e4b17023SJohn Marino {
8761e4b17023SJohn Marino current_function_returns_null = 1;
8762e4b17023SJohn Marino if ((warn_return_type || flag_isoc99)
8763e4b17023SJohn Marino && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
8764e4b17023SJohn Marino {
8765e4b17023SJohn Marino pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wreturn_type,
8766e4b17023SJohn Marino "%<return%> with no value, in "
8767e4b17023SJohn Marino "function returning non-void");
8768e4b17023SJohn Marino no_warning = true;
8769e4b17023SJohn Marino }
8770e4b17023SJohn Marino }
8771e4b17023SJohn Marino else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
8772e4b17023SJohn Marino {
8773e4b17023SJohn Marino current_function_returns_null = 1;
8774e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
8775e4b17023SJohn Marino pedwarn (loc, 0,
8776e4b17023SJohn Marino "%<return%> with a value, in function returning void");
8777e4b17023SJohn Marino else
8778e4b17023SJohn Marino pedwarn (loc, OPT_pedantic, "ISO C forbids "
8779e4b17023SJohn Marino "%<return%> with expression, in function returning void");
8780e4b17023SJohn Marino }
8781e4b17023SJohn Marino else
8782e4b17023SJohn Marino {
8783e4b17023SJohn Marino tree t = convert_for_assignment (loc, valtype, retval, origtype,
8784e4b17023SJohn Marino ic_return,
8785e4b17023SJohn Marino npc, NULL_TREE, NULL_TREE, 0);
8786e4b17023SJohn Marino tree res = DECL_RESULT (current_function_decl);
8787e4b17023SJohn Marino tree inner;
8788e4b17023SJohn Marino bool save;
8789e4b17023SJohn Marino
8790e4b17023SJohn Marino current_function_returns_value = 1;
8791e4b17023SJohn Marino if (t == error_mark_node)
8792e4b17023SJohn Marino return NULL_TREE;
8793e4b17023SJohn Marino
8794e4b17023SJohn Marino save = in_late_binary_op;
8795e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (res)) == BOOLEAN_TYPE
8796e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (res)) == COMPLEX_TYPE)
8797e4b17023SJohn Marino in_late_binary_op = true;
8798e4b17023SJohn Marino inner = t = convert (TREE_TYPE (res), t);
8799e4b17023SJohn Marino in_late_binary_op = save;
8800e4b17023SJohn Marino
8801e4b17023SJohn Marino /* Strip any conversions, additions, and subtractions, and see if
8802e4b17023SJohn Marino we are returning the address of a local variable. Warn if so. */
8803e4b17023SJohn Marino while (1)
8804e4b17023SJohn Marino {
8805e4b17023SJohn Marino switch (TREE_CODE (inner))
8806e4b17023SJohn Marino {
8807e4b17023SJohn Marino CASE_CONVERT:
8808e4b17023SJohn Marino case NON_LVALUE_EXPR:
8809e4b17023SJohn Marino case PLUS_EXPR:
8810e4b17023SJohn Marino case POINTER_PLUS_EXPR:
8811e4b17023SJohn Marino inner = TREE_OPERAND (inner, 0);
8812e4b17023SJohn Marino continue;
8813e4b17023SJohn Marino
8814e4b17023SJohn Marino case MINUS_EXPR:
8815e4b17023SJohn Marino /* If the second operand of the MINUS_EXPR has a pointer
8816e4b17023SJohn Marino type (or is converted from it), this may be valid, so
8817e4b17023SJohn Marino don't give a warning. */
8818e4b17023SJohn Marino {
8819e4b17023SJohn Marino tree op1 = TREE_OPERAND (inner, 1);
8820e4b17023SJohn Marino
8821e4b17023SJohn Marino while (!POINTER_TYPE_P (TREE_TYPE (op1))
8822e4b17023SJohn Marino && (CONVERT_EXPR_P (op1)
8823e4b17023SJohn Marino || TREE_CODE (op1) == NON_LVALUE_EXPR))
8824e4b17023SJohn Marino op1 = TREE_OPERAND (op1, 0);
8825e4b17023SJohn Marino
8826e4b17023SJohn Marino if (POINTER_TYPE_P (TREE_TYPE (op1)))
8827e4b17023SJohn Marino break;
8828e4b17023SJohn Marino
8829e4b17023SJohn Marino inner = TREE_OPERAND (inner, 0);
8830e4b17023SJohn Marino continue;
8831e4b17023SJohn Marino }
8832e4b17023SJohn Marino
8833e4b17023SJohn Marino case ADDR_EXPR:
8834e4b17023SJohn Marino inner = TREE_OPERAND (inner, 0);
8835e4b17023SJohn Marino
8836e4b17023SJohn Marino while (REFERENCE_CLASS_P (inner)
8837e4b17023SJohn Marino && TREE_CODE (inner) != INDIRECT_REF)
8838e4b17023SJohn Marino inner = TREE_OPERAND (inner, 0);
8839e4b17023SJohn Marino
8840e4b17023SJohn Marino if (DECL_P (inner)
8841e4b17023SJohn Marino && !DECL_EXTERNAL (inner)
8842e4b17023SJohn Marino && !TREE_STATIC (inner)
8843e4b17023SJohn Marino && DECL_CONTEXT (inner) == current_function_decl)
8844e4b17023SJohn Marino warning_at (loc,
8845e4b17023SJohn Marino 0, "function returns address of local variable");
8846e4b17023SJohn Marino break;
8847e4b17023SJohn Marino
8848e4b17023SJohn Marino default:
8849e4b17023SJohn Marino break;
8850e4b17023SJohn Marino }
8851e4b17023SJohn Marino
8852e4b17023SJohn Marino break;
8853e4b17023SJohn Marino }
8854e4b17023SJohn Marino
8855e4b17023SJohn Marino retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
8856e4b17023SJohn Marino SET_EXPR_LOCATION (retval, loc);
8857e4b17023SJohn Marino
8858e4b17023SJohn Marino if (warn_sequence_point)
8859e4b17023SJohn Marino verify_sequence_points (retval);
8860e4b17023SJohn Marino }
8861e4b17023SJohn Marino
8862e4b17023SJohn Marino ret_stmt = build_stmt (loc, RETURN_EXPR, retval);
8863e4b17023SJohn Marino TREE_NO_WARNING (ret_stmt) |= no_warning;
8864e4b17023SJohn Marino return add_stmt (ret_stmt);
8865e4b17023SJohn Marino }
8866e4b17023SJohn Marino
8867e4b17023SJohn Marino struct c_switch {
8868e4b17023SJohn Marino /* The SWITCH_EXPR being built. */
8869e4b17023SJohn Marino tree switch_expr;
8870e4b17023SJohn Marino
8871e4b17023SJohn Marino /* The original type of the testing expression, i.e. before the
8872e4b17023SJohn Marino default conversion is applied. */
8873e4b17023SJohn Marino tree orig_type;
8874e4b17023SJohn Marino
8875e4b17023SJohn Marino /* A splay-tree mapping the low element of a case range to the high
8876e4b17023SJohn Marino element, or NULL_TREE if there is no high element. Used to
8877e4b17023SJohn Marino determine whether or not a new case label duplicates an old case
8878e4b17023SJohn Marino label. We need a tree, rather than simply a hash table, because
8879e4b17023SJohn Marino of the GNU case range extension. */
8880e4b17023SJohn Marino splay_tree cases;
8881e4b17023SJohn Marino
8882e4b17023SJohn Marino /* The bindings at the point of the switch. This is used for
8883e4b17023SJohn Marino warnings crossing decls when branching to a case label. */
8884e4b17023SJohn Marino struct c_spot_bindings *bindings;
8885e4b17023SJohn Marino
8886e4b17023SJohn Marino /* The next node on the stack. */
8887e4b17023SJohn Marino struct c_switch *next;
8888e4b17023SJohn Marino };
8889e4b17023SJohn Marino
8890e4b17023SJohn Marino /* A stack of the currently active switch statements. The innermost
8891e4b17023SJohn Marino switch statement is on the top of the stack. There is no need to
8892e4b17023SJohn Marino mark the stack for garbage collection because it is only active
8893e4b17023SJohn Marino during the processing of the body of a function, and we never
8894e4b17023SJohn Marino collect at that point. */
8895e4b17023SJohn Marino
8896e4b17023SJohn Marino struct c_switch *c_switch_stack;
8897e4b17023SJohn Marino
8898e4b17023SJohn Marino /* Start a C switch statement, testing expression EXP. Return the new
8899e4b17023SJohn Marino SWITCH_EXPR. SWITCH_LOC is the location of the `switch'.
8900e4b17023SJohn Marino SWITCH_COND_LOC is the location of the switch's condition. */
8901e4b17023SJohn Marino
8902e4b17023SJohn Marino tree
c_start_case(location_t switch_loc,location_t switch_cond_loc,tree exp)8903e4b17023SJohn Marino c_start_case (location_t switch_loc,
8904e4b17023SJohn Marino location_t switch_cond_loc,
8905e4b17023SJohn Marino tree exp)
8906e4b17023SJohn Marino {
8907e4b17023SJohn Marino tree orig_type = error_mark_node;
8908e4b17023SJohn Marino struct c_switch *cs;
8909e4b17023SJohn Marino
8910e4b17023SJohn Marino if (exp != error_mark_node)
8911e4b17023SJohn Marino {
8912e4b17023SJohn Marino orig_type = TREE_TYPE (exp);
8913e4b17023SJohn Marino
8914e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (orig_type))
8915e4b17023SJohn Marino {
8916e4b17023SJohn Marino if (orig_type != error_mark_node)
8917e4b17023SJohn Marino {
8918e4b17023SJohn Marino error_at (switch_cond_loc, "switch quantity not an integer");
8919e4b17023SJohn Marino orig_type = error_mark_node;
8920e4b17023SJohn Marino }
8921e4b17023SJohn Marino exp = integer_zero_node;
8922e4b17023SJohn Marino }
8923e4b17023SJohn Marino else
8924e4b17023SJohn Marino {
8925e4b17023SJohn Marino tree type = TYPE_MAIN_VARIANT (orig_type);
8926e4b17023SJohn Marino
8927e4b17023SJohn Marino if (!in_system_header
8928e4b17023SJohn Marino && (type == long_integer_type_node
8929e4b17023SJohn Marino || type == long_unsigned_type_node))
8930e4b17023SJohn Marino warning_at (switch_cond_loc,
8931e4b17023SJohn Marino OPT_Wtraditional, "%<long%> switch expression not "
8932e4b17023SJohn Marino "converted to %<int%> in ISO C");
8933e4b17023SJohn Marino
8934e4b17023SJohn Marino exp = c_fully_fold (exp, false, NULL);
8935e4b17023SJohn Marino exp = default_conversion (exp);
8936e4b17023SJohn Marino
8937e4b17023SJohn Marino if (warn_sequence_point)
8938e4b17023SJohn Marino verify_sequence_points (exp);
8939e4b17023SJohn Marino }
8940e4b17023SJohn Marino }
8941e4b17023SJohn Marino
8942e4b17023SJohn Marino /* Add this new SWITCH_EXPR to the stack. */
8943e4b17023SJohn Marino cs = XNEW (struct c_switch);
8944e4b17023SJohn Marino cs->switch_expr = build3 (SWITCH_EXPR, orig_type, exp, NULL_TREE, NULL_TREE);
8945e4b17023SJohn Marino SET_EXPR_LOCATION (cs->switch_expr, switch_loc);
8946e4b17023SJohn Marino cs->orig_type = orig_type;
8947e4b17023SJohn Marino cs->cases = splay_tree_new (case_compare, NULL, NULL);
8948e4b17023SJohn Marino cs->bindings = c_get_switch_bindings ();
8949e4b17023SJohn Marino cs->next = c_switch_stack;
8950e4b17023SJohn Marino c_switch_stack = cs;
8951e4b17023SJohn Marino
8952e4b17023SJohn Marino return add_stmt (cs->switch_expr);
8953e4b17023SJohn Marino }
8954e4b17023SJohn Marino
8955e4b17023SJohn Marino /* Process a case label at location LOC. */
8956e4b17023SJohn Marino
8957e4b17023SJohn Marino tree
do_case(location_t loc,tree low_value,tree high_value)8958e4b17023SJohn Marino do_case (location_t loc, tree low_value, tree high_value)
8959e4b17023SJohn Marino {
8960e4b17023SJohn Marino tree label = NULL_TREE;
8961e4b17023SJohn Marino
8962e4b17023SJohn Marino if (low_value && TREE_CODE (low_value) != INTEGER_CST)
8963e4b17023SJohn Marino {
8964e4b17023SJohn Marino low_value = c_fully_fold (low_value, false, NULL);
8965e4b17023SJohn Marino if (TREE_CODE (low_value) == INTEGER_CST)
8966e4b17023SJohn Marino pedwarn (input_location, OPT_pedantic,
8967e4b17023SJohn Marino "case label is not an integer constant expression");
8968e4b17023SJohn Marino }
8969e4b17023SJohn Marino
8970e4b17023SJohn Marino if (high_value && TREE_CODE (high_value) != INTEGER_CST)
8971e4b17023SJohn Marino {
8972e4b17023SJohn Marino high_value = c_fully_fold (high_value, false, NULL);
8973e4b17023SJohn Marino if (TREE_CODE (high_value) == INTEGER_CST)
8974e4b17023SJohn Marino pedwarn (input_location, OPT_pedantic,
8975e4b17023SJohn Marino "case label is not an integer constant expression");
8976e4b17023SJohn Marino }
8977e4b17023SJohn Marino
8978e4b17023SJohn Marino if (c_switch_stack == NULL)
8979e4b17023SJohn Marino {
8980e4b17023SJohn Marino if (low_value)
8981e4b17023SJohn Marino error_at (loc, "case label not within a switch statement");
8982e4b17023SJohn Marino else
8983e4b17023SJohn Marino error_at (loc, "%<default%> label not within a switch statement");
8984e4b17023SJohn Marino return NULL_TREE;
8985e4b17023SJohn Marino }
8986e4b17023SJohn Marino
8987e4b17023SJohn Marino if (c_check_switch_jump_warnings (c_switch_stack->bindings,
8988e4b17023SJohn Marino EXPR_LOCATION (c_switch_stack->switch_expr),
8989e4b17023SJohn Marino loc))
8990e4b17023SJohn Marino return NULL_TREE;
8991e4b17023SJohn Marino
8992e4b17023SJohn Marino label = c_add_case_label (loc, c_switch_stack->cases,
8993e4b17023SJohn Marino SWITCH_COND (c_switch_stack->switch_expr),
8994e4b17023SJohn Marino c_switch_stack->orig_type,
8995e4b17023SJohn Marino low_value, high_value);
8996e4b17023SJohn Marino if (label == error_mark_node)
8997e4b17023SJohn Marino label = NULL_TREE;
8998e4b17023SJohn Marino return label;
8999e4b17023SJohn Marino }
9000e4b17023SJohn Marino
9001e4b17023SJohn Marino /* Finish the switch statement. */
9002e4b17023SJohn Marino
9003e4b17023SJohn Marino void
c_finish_case(tree body)9004e4b17023SJohn Marino c_finish_case (tree body)
9005e4b17023SJohn Marino {
9006e4b17023SJohn Marino struct c_switch *cs = c_switch_stack;
9007e4b17023SJohn Marino location_t switch_location;
9008e4b17023SJohn Marino
9009e4b17023SJohn Marino SWITCH_BODY (cs->switch_expr) = body;
9010e4b17023SJohn Marino
9011e4b17023SJohn Marino /* Emit warnings as needed. */
9012e4b17023SJohn Marino switch_location = EXPR_LOCATION (cs->switch_expr);
9013e4b17023SJohn Marino c_do_switch_warnings (cs->cases, switch_location,
9014e4b17023SJohn Marino TREE_TYPE (cs->switch_expr),
9015e4b17023SJohn Marino SWITCH_COND (cs->switch_expr));
9016e4b17023SJohn Marino
9017e4b17023SJohn Marino /* Pop the stack. */
9018e4b17023SJohn Marino c_switch_stack = cs->next;
9019e4b17023SJohn Marino splay_tree_delete (cs->cases);
9020e4b17023SJohn Marino c_release_switch_bindings (cs->bindings);
9021e4b17023SJohn Marino XDELETE (cs);
9022e4b17023SJohn Marino }
9023e4b17023SJohn Marino
9024e4b17023SJohn Marino /* Emit an if statement. IF_LOCUS is the location of the 'if'. COND,
9025e4b17023SJohn Marino THEN_BLOCK and ELSE_BLOCK are expressions to be used; ELSE_BLOCK
9026e4b17023SJohn Marino may be null. NESTED_IF is true if THEN_BLOCK contains another IF
9027e4b17023SJohn Marino statement, and was not surrounded with parenthesis. */
9028e4b17023SJohn Marino
9029e4b17023SJohn Marino void
c_finish_if_stmt(location_t if_locus,tree cond,tree then_block,tree else_block,bool nested_if)9030e4b17023SJohn Marino c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
9031e4b17023SJohn Marino tree else_block, bool nested_if)
9032e4b17023SJohn Marino {
9033e4b17023SJohn Marino tree stmt;
9034e4b17023SJohn Marino
9035e4b17023SJohn Marino /* Diagnose an ambiguous else if if-then-else is nested inside if-then. */
9036e4b17023SJohn Marino if (warn_parentheses && nested_if && else_block == NULL)
9037e4b17023SJohn Marino {
9038e4b17023SJohn Marino tree inner_if = then_block;
9039e4b17023SJohn Marino
9040e4b17023SJohn Marino /* We know from the grammar productions that there is an IF nested
9041e4b17023SJohn Marino within THEN_BLOCK. Due to labels and c99 conditional declarations,
9042e4b17023SJohn Marino it might not be exactly THEN_BLOCK, but should be the last
9043e4b17023SJohn Marino non-container statement within. */
9044e4b17023SJohn Marino while (1)
9045e4b17023SJohn Marino switch (TREE_CODE (inner_if))
9046e4b17023SJohn Marino {
9047e4b17023SJohn Marino case COND_EXPR:
9048e4b17023SJohn Marino goto found;
9049e4b17023SJohn Marino case BIND_EXPR:
9050e4b17023SJohn Marino inner_if = BIND_EXPR_BODY (inner_if);
9051e4b17023SJohn Marino break;
9052e4b17023SJohn Marino case STATEMENT_LIST:
9053e4b17023SJohn Marino inner_if = expr_last (then_block);
9054e4b17023SJohn Marino break;
9055e4b17023SJohn Marino case TRY_FINALLY_EXPR:
9056e4b17023SJohn Marino case TRY_CATCH_EXPR:
9057e4b17023SJohn Marino inner_if = TREE_OPERAND (inner_if, 0);
9058e4b17023SJohn Marino break;
9059e4b17023SJohn Marino default:
9060e4b17023SJohn Marino gcc_unreachable ();
9061e4b17023SJohn Marino }
9062e4b17023SJohn Marino found:
9063e4b17023SJohn Marino
9064e4b17023SJohn Marino if (COND_EXPR_ELSE (inner_if))
9065e4b17023SJohn Marino warning_at (if_locus, OPT_Wparentheses,
9066e4b17023SJohn Marino "suggest explicit braces to avoid ambiguous %<else%>");
9067e4b17023SJohn Marino }
9068e4b17023SJohn Marino
9069e4b17023SJohn Marino stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
9070e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, if_locus);
9071e4b17023SJohn Marino add_stmt (stmt);
9072e4b17023SJohn Marino }
9073e4b17023SJohn Marino
9074e4b17023SJohn Marino /* Emit a general-purpose loop construct. START_LOCUS is the location of
9075e4b17023SJohn Marino the beginning of the loop. COND is the loop condition. COND_IS_FIRST
9076e4b17023SJohn Marino is false for DO loops. INCR is the FOR increment expression. BODY is
9077e4b17023SJohn Marino the statement controlled by the loop. BLAB is the break label. CLAB is
9078e4b17023SJohn Marino the continue label. Everything is allowed to be NULL. */
9079e4b17023SJohn Marino
9080e4b17023SJohn Marino void
c_finish_loop(location_t start_locus,tree cond,tree incr,tree body,tree blab,tree clab,bool cond_is_first)9081e4b17023SJohn Marino c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
9082e4b17023SJohn Marino tree blab, tree clab, bool cond_is_first)
9083e4b17023SJohn Marino {
9084e4b17023SJohn Marino tree entry = NULL, exit = NULL, t;
9085e4b17023SJohn Marino
9086e4b17023SJohn Marino /* If the condition is zero don't generate a loop construct. */
9087e4b17023SJohn Marino if (cond && integer_zerop (cond))
9088e4b17023SJohn Marino {
9089e4b17023SJohn Marino if (cond_is_first)
9090e4b17023SJohn Marino {
9091e4b17023SJohn Marino t = build_and_jump (&blab);
9092e4b17023SJohn Marino SET_EXPR_LOCATION (t, start_locus);
9093e4b17023SJohn Marino add_stmt (t);
9094e4b17023SJohn Marino }
9095e4b17023SJohn Marino }
9096e4b17023SJohn Marino else
9097e4b17023SJohn Marino {
9098e4b17023SJohn Marino tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
9099e4b17023SJohn Marino
9100e4b17023SJohn Marino /* If we have an exit condition, then we build an IF with gotos either
9101e4b17023SJohn Marino out of the loop, or to the top of it. If there's no exit condition,
9102e4b17023SJohn Marino then we just build a jump back to the top. */
9103e4b17023SJohn Marino exit = build_and_jump (&LABEL_EXPR_LABEL (top));
9104e4b17023SJohn Marino
9105e4b17023SJohn Marino if (cond && !integer_nonzerop (cond))
9106e4b17023SJohn Marino {
9107e4b17023SJohn Marino /* Canonicalize the loop condition to the end. This means
9108e4b17023SJohn Marino generating a branch to the loop condition. Reuse the
9109e4b17023SJohn Marino continue label, if possible. */
9110e4b17023SJohn Marino if (cond_is_first)
9111e4b17023SJohn Marino {
9112e4b17023SJohn Marino if (incr || !clab)
9113e4b17023SJohn Marino {
9114e4b17023SJohn Marino entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
9115e4b17023SJohn Marino t = build_and_jump (&LABEL_EXPR_LABEL (entry));
9116e4b17023SJohn Marino }
9117e4b17023SJohn Marino else
9118e4b17023SJohn Marino t = build1 (GOTO_EXPR, void_type_node, clab);
9119e4b17023SJohn Marino SET_EXPR_LOCATION (t, start_locus);
9120e4b17023SJohn Marino add_stmt (t);
9121e4b17023SJohn Marino }
9122e4b17023SJohn Marino
9123e4b17023SJohn Marino t = build_and_jump (&blab);
9124e4b17023SJohn Marino if (cond_is_first)
9125e4b17023SJohn Marino exit = fold_build3_loc (start_locus,
9126e4b17023SJohn Marino COND_EXPR, void_type_node, cond, exit, t);
9127e4b17023SJohn Marino else
9128e4b17023SJohn Marino exit = fold_build3_loc (input_location,
9129e4b17023SJohn Marino COND_EXPR, void_type_node, cond, exit, t);
9130e4b17023SJohn Marino }
9131e4b17023SJohn Marino
9132e4b17023SJohn Marino add_stmt (top);
9133e4b17023SJohn Marino }
9134e4b17023SJohn Marino
9135e4b17023SJohn Marino if (body)
9136e4b17023SJohn Marino add_stmt (body);
9137e4b17023SJohn Marino if (clab)
9138e4b17023SJohn Marino add_stmt (build1 (LABEL_EXPR, void_type_node, clab));
9139e4b17023SJohn Marino if (incr)
9140e4b17023SJohn Marino add_stmt (incr);
9141e4b17023SJohn Marino if (entry)
9142e4b17023SJohn Marino add_stmt (entry);
9143e4b17023SJohn Marino if (exit)
9144e4b17023SJohn Marino add_stmt (exit);
9145e4b17023SJohn Marino if (blab)
9146e4b17023SJohn Marino add_stmt (build1 (LABEL_EXPR, void_type_node, blab));
9147e4b17023SJohn Marino }
9148e4b17023SJohn Marino
9149e4b17023SJohn Marino tree
c_finish_bc_stmt(location_t loc,tree * label_p,bool is_break)9150e4b17023SJohn Marino c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break)
9151e4b17023SJohn Marino {
9152e4b17023SJohn Marino bool skip;
9153e4b17023SJohn Marino tree label = *label_p;
9154e4b17023SJohn Marino
9155e4b17023SJohn Marino /* In switch statements break is sometimes stylistically used after
9156e4b17023SJohn Marino a return statement. This can lead to spurious warnings about
9157e4b17023SJohn Marino control reaching the end of a non-void function when it is
9158e4b17023SJohn Marino inlined. Note that we are calling block_may_fallthru with
9159e4b17023SJohn Marino language specific tree nodes; this works because
9160e4b17023SJohn Marino block_may_fallthru returns true when given something it does not
9161e4b17023SJohn Marino understand. */
9162e4b17023SJohn Marino skip = !block_may_fallthru (cur_stmt_list);
9163e4b17023SJohn Marino
9164e4b17023SJohn Marino if (!label)
9165e4b17023SJohn Marino {
9166e4b17023SJohn Marino if (!skip)
9167e4b17023SJohn Marino *label_p = label = create_artificial_label (loc);
9168e4b17023SJohn Marino }
9169e4b17023SJohn Marino else if (TREE_CODE (label) == LABEL_DECL)
9170e4b17023SJohn Marino ;
9171e4b17023SJohn Marino else switch (TREE_INT_CST_LOW (label))
9172e4b17023SJohn Marino {
9173e4b17023SJohn Marino case 0:
9174e4b17023SJohn Marino if (is_break)
9175e4b17023SJohn Marino error_at (loc, "break statement not within loop or switch");
9176e4b17023SJohn Marino else
9177e4b17023SJohn Marino error_at (loc, "continue statement not within a loop");
9178e4b17023SJohn Marino return NULL_TREE;
9179e4b17023SJohn Marino
9180e4b17023SJohn Marino case 1:
9181e4b17023SJohn Marino gcc_assert (is_break);
9182e4b17023SJohn Marino error_at (loc, "break statement used with OpenMP for loop");
9183e4b17023SJohn Marino return NULL_TREE;
9184e4b17023SJohn Marino
9185e4b17023SJohn Marino default:
9186e4b17023SJohn Marino gcc_unreachable ();
9187e4b17023SJohn Marino }
9188e4b17023SJohn Marino
9189e4b17023SJohn Marino if (skip)
9190e4b17023SJohn Marino return NULL_TREE;
9191e4b17023SJohn Marino
9192e4b17023SJohn Marino if (!is_break)
9193e4b17023SJohn Marino add_stmt (build_predict_expr (PRED_CONTINUE, NOT_TAKEN));
9194e4b17023SJohn Marino
9195e4b17023SJohn Marino return add_stmt (build1 (GOTO_EXPR, void_type_node, label));
9196e4b17023SJohn Marino }
9197e4b17023SJohn Marino
9198e4b17023SJohn Marino /* A helper routine for c_process_expr_stmt and c_finish_stmt_expr. */
9199e4b17023SJohn Marino
9200e4b17023SJohn Marino static void
emit_side_effect_warnings(location_t loc,tree expr)9201e4b17023SJohn Marino emit_side_effect_warnings (location_t loc, tree expr)
9202e4b17023SJohn Marino {
9203e4b17023SJohn Marino if (expr == error_mark_node)
9204e4b17023SJohn Marino ;
9205e4b17023SJohn Marino else if (!TREE_SIDE_EFFECTS (expr))
9206e4b17023SJohn Marino {
9207e4b17023SJohn Marino if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
9208e4b17023SJohn Marino warning_at (loc, OPT_Wunused_value, "statement with no effect");
9209e4b17023SJohn Marino }
9210e4b17023SJohn Marino else
9211e4b17023SJohn Marino warn_if_unused_value (expr, loc);
9212e4b17023SJohn Marino }
9213e4b17023SJohn Marino
9214e4b17023SJohn Marino /* Process an expression as if it were a complete statement. Emit
9215e4b17023SJohn Marino diagnostics, but do not call ADD_STMT. LOC is the location of the
9216e4b17023SJohn Marino statement. */
9217e4b17023SJohn Marino
9218e4b17023SJohn Marino tree
c_process_expr_stmt(location_t loc,tree expr)9219e4b17023SJohn Marino c_process_expr_stmt (location_t loc, tree expr)
9220e4b17023SJohn Marino {
9221e4b17023SJohn Marino tree exprv;
9222e4b17023SJohn Marino
9223e4b17023SJohn Marino if (!expr)
9224e4b17023SJohn Marino return NULL_TREE;
9225e4b17023SJohn Marino
9226e4b17023SJohn Marino expr = c_fully_fold (expr, false, NULL);
9227e4b17023SJohn Marino
9228e4b17023SJohn Marino if (warn_sequence_point)
9229e4b17023SJohn Marino verify_sequence_points (expr);
9230e4b17023SJohn Marino
9231e4b17023SJohn Marino if (TREE_TYPE (expr) != error_mark_node
9232e4b17023SJohn Marino && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
9233e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
9234e4b17023SJohn Marino error_at (loc, "expression statement has incomplete type");
9235e4b17023SJohn Marino
9236e4b17023SJohn Marino /* If we're not processing a statement expression, warn about unused values.
9237e4b17023SJohn Marino Warnings for statement expressions will be emitted later, once we figure
9238e4b17023SJohn Marino out which is the result. */
9239e4b17023SJohn Marino if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
9240e4b17023SJohn Marino && warn_unused_value)
9241e4b17023SJohn Marino emit_side_effect_warnings (loc, expr);
9242e4b17023SJohn Marino
9243e4b17023SJohn Marino exprv = expr;
9244e4b17023SJohn Marino while (TREE_CODE (exprv) == COMPOUND_EXPR)
9245e4b17023SJohn Marino exprv = TREE_OPERAND (exprv, 1);
9246e4b17023SJohn Marino while (CONVERT_EXPR_P (exprv))
9247e4b17023SJohn Marino exprv = TREE_OPERAND (exprv, 0);
9248e4b17023SJohn Marino if (DECL_P (exprv)
9249e4b17023SJohn Marino || handled_component_p (exprv)
9250e4b17023SJohn Marino || TREE_CODE (exprv) == ADDR_EXPR)
9251e4b17023SJohn Marino mark_exp_read (exprv);
9252e4b17023SJohn Marino
9253e4b17023SJohn Marino /* If the expression is not of a type to which we cannot assign a line
9254e4b17023SJohn Marino number, wrap the thing in a no-op NOP_EXPR. */
9255e4b17023SJohn Marino if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
9256e4b17023SJohn Marino {
9257e4b17023SJohn Marino expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
9258e4b17023SJohn Marino SET_EXPR_LOCATION (expr, loc);
9259e4b17023SJohn Marino }
9260e4b17023SJohn Marino
9261e4b17023SJohn Marino return expr;
9262e4b17023SJohn Marino }
9263e4b17023SJohn Marino
9264e4b17023SJohn Marino /* Emit an expression as a statement. LOC is the location of the
9265e4b17023SJohn Marino expression. */
9266e4b17023SJohn Marino
9267e4b17023SJohn Marino tree
c_finish_expr_stmt(location_t loc,tree expr)9268e4b17023SJohn Marino c_finish_expr_stmt (location_t loc, tree expr)
9269e4b17023SJohn Marino {
9270e4b17023SJohn Marino if (expr)
9271e4b17023SJohn Marino return add_stmt (c_process_expr_stmt (loc, expr));
9272e4b17023SJohn Marino else
9273e4b17023SJohn Marino return NULL;
9274e4b17023SJohn Marino }
9275e4b17023SJohn Marino
9276e4b17023SJohn Marino /* Do the opposite and emit a statement as an expression. To begin,
9277e4b17023SJohn Marino create a new binding level and return it. */
9278e4b17023SJohn Marino
9279e4b17023SJohn Marino tree
c_begin_stmt_expr(void)9280e4b17023SJohn Marino c_begin_stmt_expr (void)
9281e4b17023SJohn Marino {
9282e4b17023SJohn Marino tree ret;
9283e4b17023SJohn Marino
9284e4b17023SJohn Marino /* We must force a BLOCK for this level so that, if it is not expanded
9285e4b17023SJohn Marino later, there is a way to turn off the entire subtree of blocks that
9286e4b17023SJohn Marino are contained in it. */
9287e4b17023SJohn Marino keep_next_level ();
9288e4b17023SJohn Marino ret = c_begin_compound_stmt (true);
9289e4b17023SJohn Marino
9290e4b17023SJohn Marino c_bindings_start_stmt_expr (c_switch_stack == NULL
9291e4b17023SJohn Marino ? NULL
9292e4b17023SJohn Marino : c_switch_stack->bindings);
9293e4b17023SJohn Marino
9294e4b17023SJohn Marino /* Mark the current statement list as belonging to a statement list. */
9295e4b17023SJohn Marino STATEMENT_LIST_STMT_EXPR (ret) = 1;
9296e4b17023SJohn Marino
9297e4b17023SJohn Marino return ret;
9298e4b17023SJohn Marino }
9299e4b17023SJohn Marino
9300e4b17023SJohn Marino /* LOC is the location of the compound statement to which this body
9301e4b17023SJohn Marino belongs. */
9302e4b17023SJohn Marino
9303e4b17023SJohn Marino tree
c_finish_stmt_expr(location_t loc,tree body)9304e4b17023SJohn Marino c_finish_stmt_expr (location_t loc, tree body)
9305e4b17023SJohn Marino {
9306e4b17023SJohn Marino tree last, type, tmp, val;
9307e4b17023SJohn Marino tree *last_p;
9308e4b17023SJohn Marino
9309e4b17023SJohn Marino body = c_end_compound_stmt (loc, body, true);
9310e4b17023SJohn Marino
9311e4b17023SJohn Marino c_bindings_end_stmt_expr (c_switch_stack == NULL
9312e4b17023SJohn Marino ? NULL
9313e4b17023SJohn Marino : c_switch_stack->bindings);
9314e4b17023SJohn Marino
9315e4b17023SJohn Marino /* Locate the last statement in BODY. See c_end_compound_stmt
9316e4b17023SJohn Marino about always returning a BIND_EXPR. */
9317e4b17023SJohn Marino last_p = &BIND_EXPR_BODY (body);
9318e4b17023SJohn Marino last = BIND_EXPR_BODY (body);
9319e4b17023SJohn Marino
9320e4b17023SJohn Marino continue_searching:
9321e4b17023SJohn Marino if (TREE_CODE (last) == STATEMENT_LIST)
9322e4b17023SJohn Marino {
9323e4b17023SJohn Marino tree_stmt_iterator i;
9324e4b17023SJohn Marino
9325e4b17023SJohn Marino /* This can happen with degenerate cases like ({ }). No value. */
9326e4b17023SJohn Marino if (!TREE_SIDE_EFFECTS (last))
9327e4b17023SJohn Marino return body;
9328e4b17023SJohn Marino
9329e4b17023SJohn Marino /* If we're supposed to generate side effects warnings, process
9330e4b17023SJohn Marino all of the statements except the last. */
9331e4b17023SJohn Marino if (warn_unused_value)
9332e4b17023SJohn Marino {
9333e4b17023SJohn Marino for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i))
9334e4b17023SJohn Marino {
9335e4b17023SJohn Marino location_t tloc;
9336e4b17023SJohn Marino tree t = tsi_stmt (i);
9337e4b17023SJohn Marino
9338e4b17023SJohn Marino tloc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) : loc;
9339e4b17023SJohn Marino emit_side_effect_warnings (tloc, t);
9340e4b17023SJohn Marino }
9341e4b17023SJohn Marino }
9342e4b17023SJohn Marino else
9343e4b17023SJohn Marino i = tsi_last (last);
9344e4b17023SJohn Marino last_p = tsi_stmt_ptr (i);
9345e4b17023SJohn Marino last = *last_p;
9346e4b17023SJohn Marino }
9347e4b17023SJohn Marino
9348e4b17023SJohn Marino /* If the end of the list is exception related, then the list was split
9349e4b17023SJohn Marino by a call to push_cleanup. Continue searching. */
9350e4b17023SJohn Marino if (TREE_CODE (last) == TRY_FINALLY_EXPR
9351e4b17023SJohn Marino || TREE_CODE (last) == TRY_CATCH_EXPR)
9352e4b17023SJohn Marino {
9353e4b17023SJohn Marino last_p = &TREE_OPERAND (last, 0);
9354e4b17023SJohn Marino last = *last_p;
9355e4b17023SJohn Marino goto continue_searching;
9356e4b17023SJohn Marino }
9357e4b17023SJohn Marino
9358e4b17023SJohn Marino if (last == error_mark_node)
9359e4b17023SJohn Marino return last;
9360e4b17023SJohn Marino
9361e4b17023SJohn Marino /* In the case that the BIND_EXPR is not necessary, return the
9362e4b17023SJohn Marino expression out from inside it. */
9363e4b17023SJohn Marino if (last == BIND_EXPR_BODY (body)
9364e4b17023SJohn Marino && BIND_EXPR_VARS (body) == NULL)
9365e4b17023SJohn Marino {
9366e4b17023SJohn Marino /* Even if this looks constant, do not allow it in a constant
9367e4b17023SJohn Marino expression. */
9368e4b17023SJohn Marino last = c_wrap_maybe_const (last, true);
9369e4b17023SJohn Marino /* Do not warn if the return value of a statement expression is
9370e4b17023SJohn Marino unused. */
9371e4b17023SJohn Marino TREE_NO_WARNING (last) = 1;
9372e4b17023SJohn Marino return last;
9373e4b17023SJohn Marino }
9374e4b17023SJohn Marino
9375e4b17023SJohn Marino /* Extract the type of said expression. */
9376e4b17023SJohn Marino type = TREE_TYPE (last);
9377e4b17023SJohn Marino
9378e4b17023SJohn Marino /* If we're not returning a value at all, then the BIND_EXPR that
9379e4b17023SJohn Marino we already have is a fine expression to return. */
9380e4b17023SJohn Marino if (!type || VOID_TYPE_P (type))
9381e4b17023SJohn Marino return body;
9382e4b17023SJohn Marino
9383e4b17023SJohn Marino /* Now that we've located the expression containing the value, it seems
9384e4b17023SJohn Marino silly to make voidify_wrapper_expr repeat the process. Create a
9385e4b17023SJohn Marino temporary of the appropriate type and stick it in a TARGET_EXPR. */
9386e4b17023SJohn Marino tmp = create_tmp_var_raw (type, NULL);
9387e4b17023SJohn Marino
9388e4b17023SJohn Marino /* Unwrap a no-op NOP_EXPR as added by c_finish_expr_stmt. This avoids
9389e4b17023SJohn Marino tree_expr_nonnegative_p giving up immediately. */
9390e4b17023SJohn Marino val = last;
9391e4b17023SJohn Marino if (TREE_CODE (val) == NOP_EXPR
9392e4b17023SJohn Marino && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
9393e4b17023SJohn Marino val = TREE_OPERAND (val, 0);
9394e4b17023SJohn Marino
9395e4b17023SJohn Marino *last_p = build2 (MODIFY_EXPR, void_type_node, tmp, val);
9396e4b17023SJohn Marino SET_EXPR_LOCATION (*last_p, EXPR_LOCATION (last));
9397e4b17023SJohn Marino
9398e4b17023SJohn Marino {
9399e4b17023SJohn Marino tree t = build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
9400e4b17023SJohn Marino SET_EXPR_LOCATION (t, loc);
9401e4b17023SJohn Marino return t;
9402e4b17023SJohn Marino }
9403e4b17023SJohn Marino }
9404e4b17023SJohn Marino
9405e4b17023SJohn Marino /* Begin and end compound statements. This is as simple as pushing
9406e4b17023SJohn Marino and popping new statement lists from the tree. */
9407e4b17023SJohn Marino
9408e4b17023SJohn Marino tree
c_begin_compound_stmt(bool do_scope)9409e4b17023SJohn Marino c_begin_compound_stmt (bool do_scope)
9410e4b17023SJohn Marino {
9411e4b17023SJohn Marino tree stmt = push_stmt_list ();
9412e4b17023SJohn Marino if (do_scope)
9413e4b17023SJohn Marino push_scope ();
9414e4b17023SJohn Marino return stmt;
9415e4b17023SJohn Marino }
9416e4b17023SJohn Marino
9417e4b17023SJohn Marino /* End a compound statement. STMT is the statement. LOC is the
9418e4b17023SJohn Marino location of the compound statement-- this is usually the location
9419e4b17023SJohn Marino of the opening brace. */
9420e4b17023SJohn Marino
9421e4b17023SJohn Marino tree
c_end_compound_stmt(location_t loc,tree stmt,bool do_scope)9422e4b17023SJohn Marino c_end_compound_stmt (location_t loc, tree stmt, bool do_scope)
9423e4b17023SJohn Marino {
9424e4b17023SJohn Marino tree block = NULL;
9425e4b17023SJohn Marino
9426e4b17023SJohn Marino if (do_scope)
9427e4b17023SJohn Marino {
9428e4b17023SJohn Marino if (c_dialect_objc ())
9429e4b17023SJohn Marino objc_clear_super_receiver ();
9430e4b17023SJohn Marino block = pop_scope ();
9431e4b17023SJohn Marino }
9432e4b17023SJohn Marino
9433e4b17023SJohn Marino stmt = pop_stmt_list (stmt);
9434e4b17023SJohn Marino stmt = c_build_bind_expr (loc, block, stmt);
9435e4b17023SJohn Marino
9436e4b17023SJohn Marino /* If this compound statement is nested immediately inside a statement
9437e4b17023SJohn Marino expression, then force a BIND_EXPR to be created. Otherwise we'll
9438e4b17023SJohn Marino do the wrong thing for ({ { 1; } }) or ({ 1; { } }). In particular,
9439e4b17023SJohn Marino STATEMENT_LISTs merge, and thus we can lose track of what statement
9440e4b17023SJohn Marino was really last. */
9441e4b17023SJohn Marino if (building_stmt_list_p ()
9442e4b17023SJohn Marino && STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
9443e4b17023SJohn Marino && TREE_CODE (stmt) != BIND_EXPR)
9444e4b17023SJohn Marino {
9445e4b17023SJohn Marino stmt = build3 (BIND_EXPR, void_type_node, NULL, stmt, NULL);
9446e4b17023SJohn Marino TREE_SIDE_EFFECTS (stmt) = 1;
9447e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, loc);
9448e4b17023SJohn Marino }
9449e4b17023SJohn Marino
9450e4b17023SJohn Marino return stmt;
9451e4b17023SJohn Marino }
9452e4b17023SJohn Marino
9453e4b17023SJohn Marino /* Queue a cleanup. CLEANUP is an expression/statement to be executed
9454e4b17023SJohn Marino when the current scope is exited. EH_ONLY is true when this is not
9455e4b17023SJohn Marino meant to apply to normal control flow transfer. */
9456e4b17023SJohn Marino
9457e4b17023SJohn Marino void
push_cleanup(tree decl,tree cleanup,bool eh_only)9458e4b17023SJohn Marino push_cleanup (tree decl, tree cleanup, bool eh_only)
9459e4b17023SJohn Marino {
9460e4b17023SJohn Marino enum tree_code code;
9461e4b17023SJohn Marino tree stmt, list;
9462e4b17023SJohn Marino bool stmt_expr;
9463e4b17023SJohn Marino
9464e4b17023SJohn Marino code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
9465e4b17023SJohn Marino stmt = build_stmt (DECL_SOURCE_LOCATION (decl), code, NULL, cleanup);
9466e4b17023SJohn Marino add_stmt (stmt);
9467e4b17023SJohn Marino stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list);
9468e4b17023SJohn Marino list = push_stmt_list ();
9469e4b17023SJohn Marino TREE_OPERAND (stmt, 0) = list;
9470e4b17023SJohn Marino STATEMENT_LIST_STMT_EXPR (list) = stmt_expr;
9471e4b17023SJohn Marino }
9472e4b17023SJohn Marino
9473e4b17023SJohn Marino /* Convert scalar to vector for the range of operations. */
9474e4b17023SJohn Marino static enum stv_conv
scalar_to_vector(location_t loc,enum tree_code code,tree op0,tree op1)9475e4b17023SJohn Marino scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1)
9476e4b17023SJohn Marino {
9477e4b17023SJohn Marino tree type0 = TREE_TYPE (op0);
9478e4b17023SJohn Marino tree type1 = TREE_TYPE (op1);
9479e4b17023SJohn Marino bool integer_only_op = false;
9480e4b17023SJohn Marino enum stv_conv ret = stv_firstarg;
9481e4b17023SJohn Marino
9482e4b17023SJohn Marino gcc_assert (TREE_CODE (type0) == VECTOR_TYPE
9483e4b17023SJohn Marino || TREE_CODE (type1) == VECTOR_TYPE);
9484e4b17023SJohn Marino switch (code)
9485e4b17023SJohn Marino {
9486e4b17023SJohn Marino case RSHIFT_EXPR:
9487e4b17023SJohn Marino case LSHIFT_EXPR:
9488e4b17023SJohn Marino if (TREE_CODE (type0) == INTEGER_TYPE
9489e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
9490e4b17023SJohn Marino {
9491e4b17023SJohn Marino if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
9492e4b17023SJohn Marino {
9493e4b17023SJohn Marino error_at (loc, "conversion of scalar to vector "
9494e4b17023SJohn Marino "involves truncation");
9495e4b17023SJohn Marino return stv_error;
9496e4b17023SJohn Marino }
9497e4b17023SJohn Marino else
9498e4b17023SJohn Marino return stv_firstarg;
9499e4b17023SJohn Marino }
9500e4b17023SJohn Marino break;
9501e4b17023SJohn Marino
9502e4b17023SJohn Marino case BIT_IOR_EXPR:
9503e4b17023SJohn Marino case BIT_XOR_EXPR:
9504e4b17023SJohn Marino case BIT_AND_EXPR:
9505e4b17023SJohn Marino integer_only_op = true;
9506e4b17023SJohn Marino /* ... fall through ... */
9507e4b17023SJohn Marino
9508e4b17023SJohn Marino case PLUS_EXPR:
9509e4b17023SJohn Marino case MINUS_EXPR:
9510e4b17023SJohn Marino case MULT_EXPR:
9511e4b17023SJohn Marino case TRUNC_DIV_EXPR:
9512e4b17023SJohn Marino case TRUNC_MOD_EXPR:
9513e4b17023SJohn Marino case RDIV_EXPR:
9514e4b17023SJohn Marino if (TREE_CODE (type0) == VECTOR_TYPE)
9515e4b17023SJohn Marino {
9516e4b17023SJohn Marino tree tmp;
9517e4b17023SJohn Marino ret = stv_secondarg;
9518e4b17023SJohn Marino /* Swap TYPE0 with TYPE1 and OP0 with OP1 */
9519e4b17023SJohn Marino tmp = type0; type0 = type1; type1 = tmp;
9520e4b17023SJohn Marino tmp = op0; op0 = op1; op1 = tmp;
9521e4b17023SJohn Marino }
9522e4b17023SJohn Marino
9523e4b17023SJohn Marino if (TREE_CODE (type0) == INTEGER_TYPE
9524e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
9525e4b17023SJohn Marino {
9526e4b17023SJohn Marino if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
9527e4b17023SJohn Marino {
9528e4b17023SJohn Marino error_at (loc, "conversion of scalar to vector "
9529e4b17023SJohn Marino "involves truncation");
9530e4b17023SJohn Marino return stv_error;
9531e4b17023SJohn Marino }
9532e4b17023SJohn Marino return ret;
9533e4b17023SJohn Marino }
9534e4b17023SJohn Marino else if (!integer_only_op
9535e4b17023SJohn Marino /* Allow integer --> real conversion if safe. */
9536e4b17023SJohn Marino && (TREE_CODE (type0) == REAL_TYPE
9537e4b17023SJohn Marino || TREE_CODE (type0) == INTEGER_TYPE)
9538e4b17023SJohn Marino && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1)))
9539e4b17023SJohn Marino {
9540e4b17023SJohn Marino if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
9541e4b17023SJohn Marino {
9542e4b17023SJohn Marino error_at (loc, "conversion of scalar to vector "
9543e4b17023SJohn Marino "involves truncation");
9544e4b17023SJohn Marino return stv_error;
9545e4b17023SJohn Marino }
9546e4b17023SJohn Marino return ret;
9547e4b17023SJohn Marino }
9548e4b17023SJohn Marino default:
9549e4b17023SJohn Marino break;
9550e4b17023SJohn Marino }
9551e4b17023SJohn Marino
9552e4b17023SJohn Marino return stv_nothing;
9553e4b17023SJohn Marino }
9554e4b17023SJohn Marino
9555e4b17023SJohn Marino /* Build a binary-operation expression without default conversions.
9556e4b17023SJohn Marino CODE is the kind of expression to build.
9557e4b17023SJohn Marino LOCATION is the operator's location.
9558e4b17023SJohn Marino This function differs from `build' in several ways:
9559e4b17023SJohn Marino the data type of the result is computed and recorded in it,
9560e4b17023SJohn Marino warnings are generated if arg data types are invalid,
9561e4b17023SJohn Marino special handling for addition and subtraction of pointers is known,
9562e4b17023SJohn Marino and some optimization is done (operations on narrow ints
9563e4b17023SJohn Marino are done in the narrower type when that gives the same result).
9564e4b17023SJohn Marino Constant folding is also done before the result is returned.
9565e4b17023SJohn Marino
9566e4b17023SJohn Marino Note that the operands will never have enumeral types, or function
9567e4b17023SJohn Marino or array types, because either they will have the default conversions
9568e4b17023SJohn Marino performed or they have both just been converted to some other type in which
9569e4b17023SJohn Marino the arithmetic is to be done. */
9570e4b17023SJohn Marino
9571e4b17023SJohn Marino tree
build_binary_op(location_t location,enum tree_code code,tree orig_op0,tree orig_op1,int convert_p)9572e4b17023SJohn Marino build_binary_op (location_t location, enum tree_code code,
9573e4b17023SJohn Marino tree orig_op0, tree orig_op1, int convert_p)
9574e4b17023SJohn Marino {
9575e4b17023SJohn Marino tree type0, type1, orig_type0, orig_type1;
9576e4b17023SJohn Marino tree eptype;
9577e4b17023SJohn Marino enum tree_code code0, code1;
9578e4b17023SJohn Marino tree op0, op1;
9579e4b17023SJohn Marino tree ret = error_mark_node;
9580e4b17023SJohn Marino const char *invalid_op_diag;
9581e4b17023SJohn Marino bool op0_int_operands, op1_int_operands;
9582e4b17023SJohn Marino bool int_const, int_const_or_overflow, int_operands;
9583e4b17023SJohn Marino
9584e4b17023SJohn Marino /* Expression code to give to the expression when it is built.
9585e4b17023SJohn Marino Normally this is CODE, which is what the caller asked for,
9586e4b17023SJohn Marino but in some special cases we change it. */
9587e4b17023SJohn Marino enum tree_code resultcode = code;
9588e4b17023SJohn Marino
9589e4b17023SJohn Marino /* Data type in which the computation is to be performed.
9590e4b17023SJohn Marino In the simplest cases this is the common type of the arguments. */
9591e4b17023SJohn Marino tree result_type = NULL;
9592e4b17023SJohn Marino
9593e4b17023SJohn Marino /* When the computation is in excess precision, the type of the
9594e4b17023SJohn Marino final EXCESS_PRECISION_EXPR. */
9595e4b17023SJohn Marino tree semantic_result_type = NULL;
9596e4b17023SJohn Marino
9597e4b17023SJohn Marino /* Nonzero means operands have already been type-converted
9598e4b17023SJohn Marino in whatever way is necessary.
9599e4b17023SJohn Marino Zero means they need to be converted to RESULT_TYPE. */
9600e4b17023SJohn Marino int converted = 0;
9601e4b17023SJohn Marino
9602e4b17023SJohn Marino /* Nonzero means create the expression with this type, rather than
9603e4b17023SJohn Marino RESULT_TYPE. */
9604e4b17023SJohn Marino tree build_type = 0;
9605e4b17023SJohn Marino
9606e4b17023SJohn Marino /* Nonzero means after finally constructing the expression
9607e4b17023SJohn Marino convert it to this type. */
9608e4b17023SJohn Marino tree final_type = 0;
9609e4b17023SJohn Marino
9610e4b17023SJohn Marino /* Nonzero if this is an operation like MIN or MAX which can
9611e4b17023SJohn Marino safely be computed in short if both args are promoted shorts.
9612e4b17023SJohn Marino Also implies COMMON.
9613e4b17023SJohn Marino -1 indicates a bitwise operation; this makes a difference
9614e4b17023SJohn Marino in the exact conditions for when it is safe to do the operation
9615e4b17023SJohn Marino in a narrower mode. */
9616e4b17023SJohn Marino int shorten = 0;
9617e4b17023SJohn Marino
9618e4b17023SJohn Marino /* Nonzero if this is a comparison operation;
9619e4b17023SJohn Marino if both args are promoted shorts, compare the original shorts.
9620e4b17023SJohn Marino Also implies COMMON. */
9621e4b17023SJohn Marino int short_compare = 0;
9622e4b17023SJohn Marino
9623e4b17023SJohn Marino /* Nonzero if this is a right-shift operation, which can be computed on the
9624e4b17023SJohn Marino original short and then promoted if the operand is a promoted short. */
9625e4b17023SJohn Marino int short_shift = 0;
9626e4b17023SJohn Marino
9627e4b17023SJohn Marino /* Nonzero means set RESULT_TYPE to the common type of the args. */
9628e4b17023SJohn Marino int common = 0;
9629e4b17023SJohn Marino
9630e4b17023SJohn Marino /* True means types are compatible as far as ObjC is concerned. */
9631e4b17023SJohn Marino bool objc_ok;
9632e4b17023SJohn Marino
9633e4b17023SJohn Marino /* True means this is an arithmetic operation that may need excess
9634e4b17023SJohn Marino precision. */
9635e4b17023SJohn Marino bool may_need_excess_precision;
9636e4b17023SJohn Marino
9637e4b17023SJohn Marino /* True means this is a boolean operation that converts both its
9638e4b17023SJohn Marino operands to truth-values. */
9639e4b17023SJohn Marino bool boolean_op = false;
9640e4b17023SJohn Marino
9641e4b17023SJohn Marino if (location == UNKNOWN_LOCATION)
9642e4b17023SJohn Marino location = input_location;
9643e4b17023SJohn Marino
9644e4b17023SJohn Marino op0 = orig_op0;
9645e4b17023SJohn Marino op1 = orig_op1;
9646e4b17023SJohn Marino
9647e4b17023SJohn Marino op0_int_operands = EXPR_INT_CONST_OPERANDS (orig_op0);
9648e4b17023SJohn Marino if (op0_int_operands)
9649e4b17023SJohn Marino op0 = remove_c_maybe_const_expr (op0);
9650e4b17023SJohn Marino op1_int_operands = EXPR_INT_CONST_OPERANDS (orig_op1);
9651e4b17023SJohn Marino if (op1_int_operands)
9652e4b17023SJohn Marino op1 = remove_c_maybe_const_expr (op1);
9653e4b17023SJohn Marino int_operands = (op0_int_operands && op1_int_operands);
9654e4b17023SJohn Marino if (int_operands)
9655e4b17023SJohn Marino {
9656e4b17023SJohn Marino int_const_or_overflow = (TREE_CODE (orig_op0) == INTEGER_CST
9657e4b17023SJohn Marino && TREE_CODE (orig_op1) == INTEGER_CST);
9658e4b17023SJohn Marino int_const = (int_const_or_overflow
9659e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op0)
9660e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op1));
9661e4b17023SJohn Marino }
9662e4b17023SJohn Marino else
9663e4b17023SJohn Marino int_const = int_const_or_overflow = false;
9664e4b17023SJohn Marino
9665e4b17023SJohn Marino /* Do not apply default conversion in mixed vector/scalar expression. */
9666e4b17023SJohn Marino if (convert_p
9667e4b17023SJohn Marino && !((TREE_CODE (TREE_TYPE (op0)) == VECTOR_TYPE)
9668e4b17023SJohn Marino != (TREE_CODE (TREE_TYPE (op1)) == VECTOR_TYPE)))
9669e4b17023SJohn Marino {
9670e4b17023SJohn Marino op0 = default_conversion (op0);
9671e4b17023SJohn Marino op1 = default_conversion (op1);
9672e4b17023SJohn Marino }
9673e4b17023SJohn Marino
9674e4b17023SJohn Marino orig_type0 = type0 = TREE_TYPE (op0);
9675e4b17023SJohn Marino orig_type1 = type1 = TREE_TYPE (op1);
9676e4b17023SJohn Marino
9677e4b17023SJohn Marino /* The expression codes of the data types of the arguments tell us
9678e4b17023SJohn Marino whether the arguments are integers, floating, pointers, etc. */
9679e4b17023SJohn Marino code0 = TREE_CODE (type0);
9680e4b17023SJohn Marino code1 = TREE_CODE (type1);
9681e4b17023SJohn Marino
9682e4b17023SJohn Marino /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
9683e4b17023SJohn Marino STRIP_TYPE_NOPS (op0);
9684e4b17023SJohn Marino STRIP_TYPE_NOPS (op1);
9685e4b17023SJohn Marino
9686e4b17023SJohn Marino /* If an error was already reported for one of the arguments,
9687e4b17023SJohn Marino avoid reporting another error. */
9688e4b17023SJohn Marino
9689e4b17023SJohn Marino if (code0 == ERROR_MARK || code1 == ERROR_MARK)
9690e4b17023SJohn Marino return error_mark_node;
9691e4b17023SJohn Marino
9692e4b17023SJohn Marino if ((invalid_op_diag
9693e4b17023SJohn Marino = targetm.invalid_binary_op (code, type0, type1)))
9694e4b17023SJohn Marino {
9695e4b17023SJohn Marino error_at (location, invalid_op_diag);
9696e4b17023SJohn Marino return error_mark_node;
9697e4b17023SJohn Marino }
9698e4b17023SJohn Marino
9699e4b17023SJohn Marino switch (code)
9700e4b17023SJohn Marino {
9701e4b17023SJohn Marino case PLUS_EXPR:
9702e4b17023SJohn Marino case MINUS_EXPR:
9703e4b17023SJohn Marino case MULT_EXPR:
9704e4b17023SJohn Marino case TRUNC_DIV_EXPR:
9705e4b17023SJohn Marino case CEIL_DIV_EXPR:
9706e4b17023SJohn Marino case FLOOR_DIV_EXPR:
9707e4b17023SJohn Marino case ROUND_DIV_EXPR:
9708e4b17023SJohn Marino case EXACT_DIV_EXPR:
9709e4b17023SJohn Marino may_need_excess_precision = true;
9710e4b17023SJohn Marino break;
9711e4b17023SJohn Marino default:
9712e4b17023SJohn Marino may_need_excess_precision = false;
9713e4b17023SJohn Marino break;
9714e4b17023SJohn Marino }
9715e4b17023SJohn Marino if (TREE_CODE (op0) == EXCESS_PRECISION_EXPR)
9716e4b17023SJohn Marino {
9717e4b17023SJohn Marino op0 = TREE_OPERAND (op0, 0);
9718e4b17023SJohn Marino type0 = TREE_TYPE (op0);
9719e4b17023SJohn Marino }
9720e4b17023SJohn Marino else if (may_need_excess_precision
9721e4b17023SJohn Marino && (eptype = excess_precision_type (type0)) != NULL_TREE)
9722e4b17023SJohn Marino {
9723e4b17023SJohn Marino type0 = eptype;
9724e4b17023SJohn Marino op0 = convert (eptype, op0);
9725e4b17023SJohn Marino }
9726e4b17023SJohn Marino if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
9727e4b17023SJohn Marino {
9728e4b17023SJohn Marino op1 = TREE_OPERAND (op1, 0);
9729e4b17023SJohn Marino type1 = TREE_TYPE (op1);
9730e4b17023SJohn Marino }
9731e4b17023SJohn Marino else if (may_need_excess_precision
9732e4b17023SJohn Marino && (eptype = excess_precision_type (type1)) != NULL_TREE)
9733e4b17023SJohn Marino {
9734e4b17023SJohn Marino type1 = eptype;
9735e4b17023SJohn Marino op1 = convert (eptype, op1);
9736e4b17023SJohn Marino }
9737e4b17023SJohn Marino
9738e4b17023SJohn Marino objc_ok = objc_compare_types (type0, type1, -3, NULL_TREE);
9739e4b17023SJohn Marino
9740e4b17023SJohn Marino /* In case when one of the operands of the binary operation is
9741e4b17023SJohn Marino a vector and another is a scalar -- convert scalar to vector. */
9742e4b17023SJohn Marino if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
9743e4b17023SJohn Marino {
9744e4b17023SJohn Marino enum stv_conv convert_flag = scalar_to_vector (location, code, op0, op1);
9745e4b17023SJohn Marino
9746e4b17023SJohn Marino switch (convert_flag)
9747e4b17023SJohn Marino {
9748e4b17023SJohn Marino case stv_error:
9749e4b17023SJohn Marino return error_mark_node;
9750e4b17023SJohn Marino case stv_firstarg:
9751e4b17023SJohn Marino {
9752e4b17023SJohn Marino bool maybe_const = true;
9753e4b17023SJohn Marino tree sc;
9754e4b17023SJohn Marino sc = c_fully_fold (op0, false, &maybe_const);
9755e4b17023SJohn Marino sc = save_expr (sc);
9756e4b17023SJohn Marino sc = convert (TREE_TYPE (type1), sc);
9757e4b17023SJohn Marino op0 = build_vector_from_val (type1, sc);
9758e4b17023SJohn Marino if (!maybe_const)
9759e4b17023SJohn Marino op0 = c_wrap_maybe_const (op0, true);
9760e4b17023SJohn Marino orig_type0 = type0 = TREE_TYPE (op0);
9761e4b17023SJohn Marino code0 = TREE_CODE (type0);
9762e4b17023SJohn Marino converted = 1;
9763e4b17023SJohn Marino break;
9764e4b17023SJohn Marino }
9765e4b17023SJohn Marino case stv_secondarg:
9766e4b17023SJohn Marino {
9767e4b17023SJohn Marino bool maybe_const = true;
9768e4b17023SJohn Marino tree sc;
9769e4b17023SJohn Marino sc = c_fully_fold (op1, false, &maybe_const);
9770e4b17023SJohn Marino sc = save_expr (sc);
9771e4b17023SJohn Marino sc = convert (TREE_TYPE (type0), sc);
9772e4b17023SJohn Marino op1 = build_vector_from_val (type0, sc);
9773e4b17023SJohn Marino if (!maybe_const)
9774e4b17023SJohn Marino op1 = c_wrap_maybe_const (op1, true);
9775e4b17023SJohn Marino orig_type1 = type1 = TREE_TYPE (op1);
9776e4b17023SJohn Marino code1 = TREE_CODE (type1);
9777e4b17023SJohn Marino converted = 1;
9778e4b17023SJohn Marino break;
9779e4b17023SJohn Marino }
9780e4b17023SJohn Marino default:
9781e4b17023SJohn Marino break;
9782e4b17023SJohn Marino }
9783e4b17023SJohn Marino }
9784e4b17023SJohn Marino
9785e4b17023SJohn Marino switch (code)
9786e4b17023SJohn Marino {
9787e4b17023SJohn Marino case PLUS_EXPR:
9788e4b17023SJohn Marino /* Handle the pointer + int case. */
9789e4b17023SJohn Marino if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
9790e4b17023SJohn Marino {
9791e4b17023SJohn Marino ret = pointer_int_sum (location, PLUS_EXPR, op0, op1);
9792e4b17023SJohn Marino goto return_build_binary_op;
9793e4b17023SJohn Marino }
9794e4b17023SJohn Marino else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
9795e4b17023SJohn Marino {
9796e4b17023SJohn Marino ret = pointer_int_sum (location, PLUS_EXPR, op1, op0);
9797e4b17023SJohn Marino goto return_build_binary_op;
9798e4b17023SJohn Marino }
9799e4b17023SJohn Marino else
9800e4b17023SJohn Marino common = 1;
9801e4b17023SJohn Marino break;
9802e4b17023SJohn Marino
9803e4b17023SJohn Marino case MINUS_EXPR:
9804e4b17023SJohn Marino /* Subtraction of two similar pointers.
9805e4b17023SJohn Marino We must subtract them as integers, then divide by object size. */
9806e4b17023SJohn Marino if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
9807e4b17023SJohn Marino && comp_target_types (location, type0, type1))
9808e4b17023SJohn Marino {
9809e4b17023SJohn Marino ret = pointer_diff (location, op0, op1);
9810e4b17023SJohn Marino goto return_build_binary_op;
9811e4b17023SJohn Marino }
9812e4b17023SJohn Marino /* Handle pointer minus int. Just like pointer plus int. */
9813e4b17023SJohn Marino else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
9814e4b17023SJohn Marino {
9815e4b17023SJohn Marino ret = pointer_int_sum (location, MINUS_EXPR, op0, op1);
9816e4b17023SJohn Marino goto return_build_binary_op;
9817e4b17023SJohn Marino }
9818e4b17023SJohn Marino else
9819e4b17023SJohn Marino common = 1;
9820e4b17023SJohn Marino break;
9821e4b17023SJohn Marino
9822e4b17023SJohn Marino case MULT_EXPR:
9823e4b17023SJohn Marino common = 1;
9824e4b17023SJohn Marino break;
9825e4b17023SJohn Marino
9826e4b17023SJohn Marino case TRUNC_DIV_EXPR:
9827e4b17023SJohn Marino case CEIL_DIV_EXPR:
9828e4b17023SJohn Marino case FLOOR_DIV_EXPR:
9829e4b17023SJohn Marino case ROUND_DIV_EXPR:
9830e4b17023SJohn Marino case EXACT_DIV_EXPR:
9831e4b17023SJohn Marino warn_for_div_by_zero (location, op1);
9832e4b17023SJohn Marino
9833e4b17023SJohn Marino if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
9834e4b17023SJohn Marino || code0 == FIXED_POINT_TYPE
9835e4b17023SJohn Marino || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
9836e4b17023SJohn Marino && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
9837e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE
9838e4b17023SJohn Marino || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
9839e4b17023SJohn Marino {
9840e4b17023SJohn Marino enum tree_code tcode0 = code0, tcode1 = code1;
9841e4b17023SJohn Marino
9842e4b17023SJohn Marino if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
9843e4b17023SJohn Marino tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
9844e4b17023SJohn Marino if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
9845e4b17023SJohn Marino tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
9846e4b17023SJohn Marino
9847e4b17023SJohn Marino if (!((tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE)
9848e4b17023SJohn Marino || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE)))
9849e4b17023SJohn Marino resultcode = RDIV_EXPR;
9850e4b17023SJohn Marino else
9851e4b17023SJohn Marino /* Although it would be tempting to shorten always here, that
9852e4b17023SJohn Marino loses on some targets, since the modulo instruction is
9853e4b17023SJohn Marino undefined if the quotient can't be represented in the
9854e4b17023SJohn Marino computation mode. We shorten only if unsigned or if
9855e4b17023SJohn Marino dividing by something we know != -1. */
9856e4b17023SJohn Marino shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
9857e4b17023SJohn Marino || (TREE_CODE (op1) == INTEGER_CST
9858e4b17023SJohn Marino && !integer_all_onesp (op1)));
9859e4b17023SJohn Marino common = 1;
9860e4b17023SJohn Marino }
9861e4b17023SJohn Marino break;
9862e4b17023SJohn Marino
9863e4b17023SJohn Marino case BIT_AND_EXPR:
9864e4b17023SJohn Marino case BIT_IOR_EXPR:
9865e4b17023SJohn Marino case BIT_XOR_EXPR:
9866e4b17023SJohn Marino if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
9867e4b17023SJohn Marino shorten = -1;
9868e4b17023SJohn Marino /* Allow vector types which are not floating point types. */
9869e4b17023SJohn Marino else if (code0 == VECTOR_TYPE
9870e4b17023SJohn Marino && code1 == VECTOR_TYPE
9871e4b17023SJohn Marino && !VECTOR_FLOAT_TYPE_P (type0)
9872e4b17023SJohn Marino && !VECTOR_FLOAT_TYPE_P (type1))
9873e4b17023SJohn Marino common = 1;
9874e4b17023SJohn Marino break;
9875e4b17023SJohn Marino
9876e4b17023SJohn Marino case TRUNC_MOD_EXPR:
9877e4b17023SJohn Marino case FLOOR_MOD_EXPR:
9878e4b17023SJohn Marino warn_for_div_by_zero (location, op1);
9879e4b17023SJohn Marino
9880e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
9881e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
9882e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
9883e4b17023SJohn Marino common = 1;
9884e4b17023SJohn Marino else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
9885e4b17023SJohn Marino {
9886e4b17023SJohn Marino /* Although it would be tempting to shorten always here, that loses
9887e4b17023SJohn Marino on some targets, since the modulo instruction is undefined if the
9888e4b17023SJohn Marino quotient can't be represented in the computation mode. We shorten
9889e4b17023SJohn Marino only if unsigned or if dividing by something we know != -1. */
9890e4b17023SJohn Marino shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
9891e4b17023SJohn Marino || (TREE_CODE (op1) == INTEGER_CST
9892e4b17023SJohn Marino && !integer_all_onesp (op1)));
9893e4b17023SJohn Marino common = 1;
9894e4b17023SJohn Marino }
9895e4b17023SJohn Marino break;
9896e4b17023SJohn Marino
9897e4b17023SJohn Marino case TRUTH_ANDIF_EXPR:
9898e4b17023SJohn Marino case TRUTH_ORIF_EXPR:
9899e4b17023SJohn Marino case TRUTH_AND_EXPR:
9900e4b17023SJohn Marino case TRUTH_OR_EXPR:
9901e4b17023SJohn Marino case TRUTH_XOR_EXPR:
9902e4b17023SJohn Marino if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
9903e4b17023SJohn Marino || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
9904e4b17023SJohn Marino || code0 == FIXED_POINT_TYPE)
9905e4b17023SJohn Marino && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
9906e4b17023SJohn Marino || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
9907e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE))
9908e4b17023SJohn Marino {
9909e4b17023SJohn Marino /* Result of these operations is always an int,
9910e4b17023SJohn Marino but that does not mean the operands should be
9911e4b17023SJohn Marino converted to ints! */
9912e4b17023SJohn Marino result_type = integer_type_node;
99135ce9237cSJohn Marino if (op0_int_operands)
99145ce9237cSJohn Marino {
99155ce9237cSJohn Marino op0 = c_objc_common_truthvalue_conversion (location, orig_op0);
99165ce9237cSJohn Marino op0 = remove_c_maybe_const_expr (op0);
99175ce9237cSJohn Marino }
99185ce9237cSJohn Marino else
99195ce9237cSJohn Marino op0 = c_objc_common_truthvalue_conversion (location, op0);
99205ce9237cSJohn Marino if (op1_int_operands)
99215ce9237cSJohn Marino {
99225ce9237cSJohn Marino op1 = c_objc_common_truthvalue_conversion (location, orig_op1);
99235ce9237cSJohn Marino op1 = remove_c_maybe_const_expr (op1);
99245ce9237cSJohn Marino }
99255ce9237cSJohn Marino else
99265ce9237cSJohn Marino op1 = c_objc_common_truthvalue_conversion (location, op1);
9927e4b17023SJohn Marino converted = 1;
9928e4b17023SJohn Marino boolean_op = true;
9929e4b17023SJohn Marino }
9930e4b17023SJohn Marino if (code == TRUTH_ANDIF_EXPR)
9931e4b17023SJohn Marino {
9932e4b17023SJohn Marino int_const_or_overflow = (int_operands
9933e4b17023SJohn Marino && TREE_CODE (orig_op0) == INTEGER_CST
9934e4b17023SJohn Marino && (op0 == truthvalue_false_node
9935e4b17023SJohn Marino || TREE_CODE (orig_op1) == INTEGER_CST));
9936e4b17023SJohn Marino int_const = (int_const_or_overflow
9937e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op0)
9938e4b17023SJohn Marino && (op0 == truthvalue_false_node
9939e4b17023SJohn Marino || !TREE_OVERFLOW (orig_op1)));
9940e4b17023SJohn Marino }
9941e4b17023SJohn Marino else if (code == TRUTH_ORIF_EXPR)
9942e4b17023SJohn Marino {
9943e4b17023SJohn Marino int_const_or_overflow = (int_operands
9944e4b17023SJohn Marino && TREE_CODE (orig_op0) == INTEGER_CST
9945e4b17023SJohn Marino && (op0 == truthvalue_true_node
9946e4b17023SJohn Marino || TREE_CODE (orig_op1) == INTEGER_CST));
9947e4b17023SJohn Marino int_const = (int_const_or_overflow
9948e4b17023SJohn Marino && !TREE_OVERFLOW (orig_op0)
9949e4b17023SJohn Marino && (op0 == truthvalue_true_node
9950e4b17023SJohn Marino || !TREE_OVERFLOW (orig_op1)));
9951e4b17023SJohn Marino }
9952e4b17023SJohn Marino break;
9953e4b17023SJohn Marino
9954e4b17023SJohn Marino /* Shift operations: result has same type as first operand;
9955e4b17023SJohn Marino always convert second operand to int.
9956e4b17023SJohn Marino Also set SHORT_SHIFT if shifting rightward. */
9957e4b17023SJohn Marino
9958e4b17023SJohn Marino case RSHIFT_EXPR:
9959e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
9960e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
9961e4b17023SJohn Marino {
9962e4b17023SJohn Marino result_type = type0;
9963e4b17023SJohn Marino converted = 1;
9964e4b17023SJohn Marino }
9965e4b17023SJohn Marino else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
9966e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
9967e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
9968e4b17023SJohn Marino && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
9969e4b17023SJohn Marino {
9970e4b17023SJohn Marino result_type = type0;
9971e4b17023SJohn Marino converted = 1;
9972e4b17023SJohn Marino }
9973e4b17023SJohn Marino else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
9974e4b17023SJohn Marino && code1 == INTEGER_TYPE)
9975e4b17023SJohn Marino {
9976e4b17023SJohn Marino if (TREE_CODE (op1) == INTEGER_CST)
9977e4b17023SJohn Marino {
9978e4b17023SJohn Marino if (tree_int_cst_sgn (op1) < 0)
9979e4b17023SJohn Marino {
9980e4b17023SJohn Marino int_const = false;
9981e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
9982e4b17023SJohn Marino warning (0, "right shift count is negative");
9983e4b17023SJohn Marino }
9984e4b17023SJohn Marino else
9985e4b17023SJohn Marino {
9986e4b17023SJohn Marino if (!integer_zerop (op1))
9987e4b17023SJohn Marino short_shift = 1;
9988e4b17023SJohn Marino
9989e4b17023SJohn Marino if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
9990e4b17023SJohn Marino {
9991e4b17023SJohn Marino int_const = false;
9992e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
9993e4b17023SJohn Marino warning (0, "right shift count >= width of type");
9994e4b17023SJohn Marino }
9995e4b17023SJohn Marino }
9996e4b17023SJohn Marino }
9997e4b17023SJohn Marino
9998e4b17023SJohn Marino /* Use the type of the value to be shifted. */
9999e4b17023SJohn Marino result_type = type0;
10000e4b17023SJohn Marino /* Convert the non vector shift-count to an integer, regardless
10001e4b17023SJohn Marino of size of value being shifted. */
10002e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
10003e4b17023SJohn Marino && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
10004e4b17023SJohn Marino op1 = convert (integer_type_node, op1);
10005e4b17023SJohn Marino /* Avoid converting op1 to result_type later. */
10006e4b17023SJohn Marino converted = 1;
10007e4b17023SJohn Marino }
10008e4b17023SJohn Marino break;
10009e4b17023SJohn Marino
10010e4b17023SJohn Marino case LSHIFT_EXPR:
10011e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == INTEGER_TYPE
10012e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
10013e4b17023SJohn Marino {
10014e4b17023SJohn Marino result_type = type0;
10015e4b17023SJohn Marino converted = 1;
10016e4b17023SJohn Marino }
10017e4b17023SJohn Marino else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
10018e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
10019e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
10020e4b17023SJohn Marino && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
10021e4b17023SJohn Marino {
10022e4b17023SJohn Marino result_type = type0;
10023e4b17023SJohn Marino converted = 1;
10024e4b17023SJohn Marino }
10025e4b17023SJohn Marino else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
10026e4b17023SJohn Marino && code1 == INTEGER_TYPE)
10027e4b17023SJohn Marino {
10028e4b17023SJohn Marino if (TREE_CODE (op1) == INTEGER_CST)
10029e4b17023SJohn Marino {
10030e4b17023SJohn Marino if (tree_int_cst_sgn (op1) < 0)
10031e4b17023SJohn Marino {
10032e4b17023SJohn Marino int_const = false;
10033e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
10034e4b17023SJohn Marino warning (0, "left shift count is negative");
10035e4b17023SJohn Marino }
10036e4b17023SJohn Marino
10037e4b17023SJohn Marino else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
10038e4b17023SJohn Marino {
10039e4b17023SJohn Marino int_const = false;
10040e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
10041e4b17023SJohn Marino warning (0, "left shift count >= width of type");
10042e4b17023SJohn Marino }
10043e4b17023SJohn Marino }
10044e4b17023SJohn Marino
10045e4b17023SJohn Marino /* Use the type of the value to be shifted. */
10046e4b17023SJohn Marino result_type = type0;
10047e4b17023SJohn Marino /* Convert the non vector shift-count to an integer, regardless
10048e4b17023SJohn Marino of size of value being shifted. */
10049e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE
10050e4b17023SJohn Marino && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
10051e4b17023SJohn Marino op1 = convert (integer_type_node, op1);
10052e4b17023SJohn Marino /* Avoid converting op1 to result_type later. */
10053e4b17023SJohn Marino converted = 1;
10054e4b17023SJohn Marino }
10055e4b17023SJohn Marino break;
10056e4b17023SJohn Marino
10057e4b17023SJohn Marino case EQ_EXPR:
10058e4b17023SJohn Marino case NE_EXPR:
10059e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
10060e4b17023SJohn Marino {
10061e4b17023SJohn Marino tree intt;
10062e4b17023SJohn Marino if (TREE_TYPE (type0) != TREE_TYPE (type1))
10063e4b17023SJohn Marino {
10064e4b17023SJohn Marino error_at (location, "comparing vectors with different "
10065e4b17023SJohn Marino "element types");
10066e4b17023SJohn Marino return error_mark_node;
10067e4b17023SJohn Marino }
10068e4b17023SJohn Marino
10069e4b17023SJohn Marino if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1))
10070e4b17023SJohn Marino {
10071e4b17023SJohn Marino error_at (location, "comparing vectors with different "
10072e4b17023SJohn Marino "number of elements");
10073e4b17023SJohn Marino return error_mark_node;
10074e4b17023SJohn Marino }
10075e4b17023SJohn Marino
10076e4b17023SJohn Marino /* Always construct signed integer vector type. */
10077e4b17023SJohn Marino intt = c_common_type_for_size (GET_MODE_BITSIZE
10078e4b17023SJohn Marino (TYPE_MODE (TREE_TYPE (type0))), 0);
10079e4b17023SJohn Marino result_type = build_opaque_vector_type (intt,
10080e4b17023SJohn Marino TYPE_VECTOR_SUBPARTS (type0));
10081e4b17023SJohn Marino converted = 1;
10082e4b17023SJohn Marino break;
10083e4b17023SJohn Marino }
10084e4b17023SJohn Marino if (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1))
10085e4b17023SJohn Marino warning_at (location,
10086e4b17023SJohn Marino OPT_Wfloat_equal,
10087e4b17023SJohn Marino "comparing floating point with == or != is unsafe");
10088e4b17023SJohn Marino /* Result of comparison is always int,
10089e4b17023SJohn Marino but don't convert the args to int! */
10090e4b17023SJohn Marino build_type = integer_type_node;
10091e4b17023SJohn Marino if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
10092e4b17023SJohn Marino || code0 == FIXED_POINT_TYPE || code0 == COMPLEX_TYPE)
10093e4b17023SJohn Marino && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
10094e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE))
10095e4b17023SJohn Marino short_compare = 1;
10096e4b17023SJohn Marino else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
10097e4b17023SJohn Marino {
10098e4b17023SJohn Marino if (TREE_CODE (op0) == ADDR_EXPR
10099e4b17023SJohn Marino && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
10100e4b17023SJohn Marino {
10101e4b17023SJohn Marino if (code == EQ_EXPR)
10102e4b17023SJohn Marino warning_at (location,
10103e4b17023SJohn Marino OPT_Waddress,
10104e4b17023SJohn Marino "the comparison will always evaluate as %<false%> "
10105e4b17023SJohn Marino "for the address of %qD will never be NULL",
10106e4b17023SJohn Marino TREE_OPERAND (op0, 0));
10107e4b17023SJohn Marino else
10108e4b17023SJohn Marino warning_at (location,
10109e4b17023SJohn Marino OPT_Waddress,
10110e4b17023SJohn Marino "the comparison will always evaluate as %<true%> "
10111e4b17023SJohn Marino "for the address of %qD will never be NULL",
10112e4b17023SJohn Marino TREE_OPERAND (op0, 0));
10113e4b17023SJohn Marino }
10114e4b17023SJohn Marino result_type = type0;
10115e4b17023SJohn Marino }
10116e4b17023SJohn Marino else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
10117e4b17023SJohn Marino {
10118e4b17023SJohn Marino if (TREE_CODE (op1) == ADDR_EXPR
10119e4b17023SJohn Marino && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
10120e4b17023SJohn Marino {
10121e4b17023SJohn Marino if (code == EQ_EXPR)
10122e4b17023SJohn Marino warning_at (location,
10123e4b17023SJohn Marino OPT_Waddress,
10124e4b17023SJohn Marino "the comparison will always evaluate as %<false%> "
10125e4b17023SJohn Marino "for the address of %qD will never be NULL",
10126e4b17023SJohn Marino TREE_OPERAND (op1, 0));
10127e4b17023SJohn Marino else
10128e4b17023SJohn Marino warning_at (location,
10129e4b17023SJohn Marino OPT_Waddress,
10130e4b17023SJohn Marino "the comparison will always evaluate as %<true%> "
10131e4b17023SJohn Marino "for the address of %qD will never be NULL",
10132e4b17023SJohn Marino TREE_OPERAND (op1, 0));
10133e4b17023SJohn Marino }
10134e4b17023SJohn Marino result_type = type1;
10135e4b17023SJohn Marino }
10136e4b17023SJohn Marino else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
10137e4b17023SJohn Marino {
10138e4b17023SJohn Marino tree tt0 = TREE_TYPE (type0);
10139e4b17023SJohn Marino tree tt1 = TREE_TYPE (type1);
10140e4b17023SJohn Marino addr_space_t as0 = TYPE_ADDR_SPACE (tt0);
10141e4b17023SJohn Marino addr_space_t as1 = TYPE_ADDR_SPACE (tt1);
10142e4b17023SJohn Marino addr_space_t as_common = ADDR_SPACE_GENERIC;
10143e4b17023SJohn Marino
10144e4b17023SJohn Marino /* Anything compares with void *. void * compares with anything.
10145e4b17023SJohn Marino Otherwise, the targets must be compatible
10146e4b17023SJohn Marino and both must be object or both incomplete. */
10147e4b17023SJohn Marino if (comp_target_types (location, type0, type1))
10148e4b17023SJohn Marino result_type = common_pointer_type (type0, type1);
10149e4b17023SJohn Marino else if (!addr_space_superset (as0, as1, &as_common))
10150e4b17023SJohn Marino {
10151e4b17023SJohn Marino error_at (location, "comparison of pointers to "
10152e4b17023SJohn Marino "disjoint address spaces");
10153e4b17023SJohn Marino return error_mark_node;
10154e4b17023SJohn Marino }
10155e4b17023SJohn Marino else if (VOID_TYPE_P (tt0))
10156e4b17023SJohn Marino {
10157e4b17023SJohn Marino if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE)
10158e4b17023SJohn Marino pedwarn (location, OPT_pedantic, "ISO C forbids "
10159e4b17023SJohn Marino "comparison of %<void *%> with function pointer");
10160e4b17023SJohn Marino }
10161e4b17023SJohn Marino else if (VOID_TYPE_P (tt1))
10162e4b17023SJohn Marino {
10163e4b17023SJohn Marino if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE)
10164e4b17023SJohn Marino pedwarn (location, OPT_pedantic, "ISO C forbids "
10165e4b17023SJohn Marino "comparison of %<void *%> with function pointer");
10166e4b17023SJohn Marino }
10167e4b17023SJohn Marino else
10168e4b17023SJohn Marino /* Avoid warning about the volatile ObjC EH puts on decls. */
10169e4b17023SJohn Marino if (!objc_ok)
10170e4b17023SJohn Marino pedwarn (location, 0,
10171e4b17023SJohn Marino "comparison of distinct pointer types lacks a cast");
10172e4b17023SJohn Marino
10173e4b17023SJohn Marino if (result_type == NULL_TREE)
10174e4b17023SJohn Marino {
10175e4b17023SJohn Marino int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
10176e4b17023SJohn Marino result_type = build_pointer_type
10177e4b17023SJohn Marino (build_qualified_type (void_type_node, qual));
10178e4b17023SJohn Marino }
10179e4b17023SJohn Marino }
10180e4b17023SJohn Marino else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
10181e4b17023SJohn Marino {
10182e4b17023SJohn Marino result_type = type0;
10183e4b17023SJohn Marino pedwarn (location, 0, "comparison between pointer and integer");
10184e4b17023SJohn Marino }
10185e4b17023SJohn Marino else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
10186e4b17023SJohn Marino {
10187e4b17023SJohn Marino result_type = type1;
10188e4b17023SJohn Marino pedwarn (location, 0, "comparison between pointer and integer");
10189e4b17023SJohn Marino }
10190e4b17023SJohn Marino break;
10191e4b17023SJohn Marino
10192e4b17023SJohn Marino case LE_EXPR:
10193e4b17023SJohn Marino case GE_EXPR:
10194e4b17023SJohn Marino case LT_EXPR:
10195e4b17023SJohn Marino case GT_EXPR:
10196e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
10197e4b17023SJohn Marino {
10198e4b17023SJohn Marino tree intt;
10199e4b17023SJohn Marino if (TREE_TYPE (type0) != TREE_TYPE (type1))
10200e4b17023SJohn Marino {
10201e4b17023SJohn Marino error_at (location, "comparing vectors with different "
10202e4b17023SJohn Marino "element types");
10203e4b17023SJohn Marino return error_mark_node;
10204e4b17023SJohn Marino }
10205e4b17023SJohn Marino
10206e4b17023SJohn Marino if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1))
10207e4b17023SJohn Marino {
10208e4b17023SJohn Marino error_at (location, "comparing vectors with different "
10209e4b17023SJohn Marino "number of elements");
10210e4b17023SJohn Marino return error_mark_node;
10211e4b17023SJohn Marino }
10212e4b17023SJohn Marino
10213e4b17023SJohn Marino /* Always construct signed integer vector type. */
10214e4b17023SJohn Marino intt = c_common_type_for_size (GET_MODE_BITSIZE
10215e4b17023SJohn Marino (TYPE_MODE (TREE_TYPE (type0))), 0);
10216e4b17023SJohn Marino result_type = build_opaque_vector_type (intt,
10217e4b17023SJohn Marino TYPE_VECTOR_SUBPARTS (type0));
10218e4b17023SJohn Marino converted = 1;
10219e4b17023SJohn Marino break;
10220e4b17023SJohn Marino }
10221e4b17023SJohn Marino build_type = integer_type_node;
10222e4b17023SJohn Marino if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
10223e4b17023SJohn Marino || code0 == FIXED_POINT_TYPE)
10224e4b17023SJohn Marino && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
10225e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE))
10226e4b17023SJohn Marino short_compare = 1;
10227e4b17023SJohn Marino else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
10228e4b17023SJohn Marino {
10229e4b17023SJohn Marino addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (type0));
10230e4b17023SJohn Marino addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (type1));
10231e4b17023SJohn Marino addr_space_t as_common;
10232e4b17023SJohn Marino
10233e4b17023SJohn Marino if (comp_target_types (location, type0, type1))
10234e4b17023SJohn Marino {
10235e4b17023SJohn Marino result_type = common_pointer_type (type0, type1);
10236e4b17023SJohn Marino if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
10237e4b17023SJohn Marino != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
10238e4b17023SJohn Marino pedwarn (location, 0,
10239e4b17023SJohn Marino "comparison of complete and incomplete pointers");
10240e4b17023SJohn Marino else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
10241e4b17023SJohn Marino pedwarn (location, OPT_pedantic, "ISO C forbids "
10242e4b17023SJohn Marino "ordered comparisons of pointers to functions");
10243e4b17023SJohn Marino else if (null_pointer_constant_p (orig_op0)
10244e4b17023SJohn Marino || null_pointer_constant_p (orig_op1))
10245e4b17023SJohn Marino warning_at (location, OPT_Wextra,
10246e4b17023SJohn Marino "ordered comparison of pointer with null pointer");
10247e4b17023SJohn Marino
10248e4b17023SJohn Marino }
10249e4b17023SJohn Marino else if (!addr_space_superset (as0, as1, &as_common))
10250e4b17023SJohn Marino {
10251e4b17023SJohn Marino error_at (location, "comparison of pointers to "
10252e4b17023SJohn Marino "disjoint address spaces");
10253e4b17023SJohn Marino return error_mark_node;
10254e4b17023SJohn Marino }
10255e4b17023SJohn Marino else
10256e4b17023SJohn Marino {
10257e4b17023SJohn Marino int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
10258e4b17023SJohn Marino result_type = build_pointer_type
10259e4b17023SJohn Marino (build_qualified_type (void_type_node, qual));
10260e4b17023SJohn Marino pedwarn (location, 0,
10261e4b17023SJohn Marino "comparison of distinct pointer types lacks a cast");
10262e4b17023SJohn Marino }
10263e4b17023SJohn Marino }
10264e4b17023SJohn Marino else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
10265e4b17023SJohn Marino {
10266e4b17023SJohn Marino result_type = type0;
10267e4b17023SJohn Marino if (pedantic)
10268e4b17023SJohn Marino pedwarn (location, OPT_pedantic,
10269e4b17023SJohn Marino "ordered comparison of pointer with integer zero");
10270e4b17023SJohn Marino else if (extra_warnings)
10271e4b17023SJohn Marino warning_at (location, OPT_Wextra,
10272e4b17023SJohn Marino "ordered comparison of pointer with integer zero");
10273e4b17023SJohn Marino }
10274e4b17023SJohn Marino else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
10275e4b17023SJohn Marino {
10276e4b17023SJohn Marino result_type = type1;
10277e4b17023SJohn Marino if (pedantic)
10278e4b17023SJohn Marino pedwarn (location, OPT_pedantic,
10279e4b17023SJohn Marino "ordered comparison of pointer with integer zero");
10280e4b17023SJohn Marino else if (extra_warnings)
10281e4b17023SJohn Marino warning_at (location, OPT_Wextra,
10282e4b17023SJohn Marino "ordered comparison of pointer with integer zero");
10283e4b17023SJohn Marino }
10284e4b17023SJohn Marino else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
10285e4b17023SJohn Marino {
10286e4b17023SJohn Marino result_type = type0;
10287e4b17023SJohn Marino pedwarn (location, 0, "comparison between pointer and integer");
10288e4b17023SJohn Marino }
10289e4b17023SJohn Marino else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
10290e4b17023SJohn Marino {
10291e4b17023SJohn Marino result_type = type1;
10292e4b17023SJohn Marino pedwarn (location, 0, "comparison between pointer and integer");
10293e4b17023SJohn Marino }
10294e4b17023SJohn Marino break;
10295e4b17023SJohn Marino
10296e4b17023SJohn Marino default:
10297e4b17023SJohn Marino gcc_unreachable ();
10298e4b17023SJohn Marino }
10299e4b17023SJohn Marino
10300e4b17023SJohn Marino if (code0 == ERROR_MARK || code1 == ERROR_MARK)
10301e4b17023SJohn Marino return error_mark_node;
10302e4b17023SJohn Marino
10303e4b17023SJohn Marino if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
10304e4b17023SJohn Marino && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
10305e4b17023SJohn Marino || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
10306e4b17023SJohn Marino TREE_TYPE (type1))))
10307e4b17023SJohn Marino {
10308e4b17023SJohn Marino binary_op_error (location, code, type0, type1);
10309e4b17023SJohn Marino return error_mark_node;
10310e4b17023SJohn Marino }
10311e4b17023SJohn Marino
10312e4b17023SJohn Marino if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
10313e4b17023SJohn Marino || code0 == FIXED_POINT_TYPE || code0 == VECTOR_TYPE)
10314e4b17023SJohn Marino &&
10315e4b17023SJohn Marino (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
10316e4b17023SJohn Marino || code1 == FIXED_POINT_TYPE || code1 == VECTOR_TYPE))
10317e4b17023SJohn Marino {
10318e4b17023SJohn Marino bool first_complex = (code0 == COMPLEX_TYPE);
10319e4b17023SJohn Marino bool second_complex = (code1 == COMPLEX_TYPE);
10320e4b17023SJohn Marino int none_complex = (!first_complex && !second_complex);
10321e4b17023SJohn Marino
10322e4b17023SJohn Marino if (shorten || common || short_compare)
10323e4b17023SJohn Marino {
10324e4b17023SJohn Marino result_type = c_common_type (type0, type1);
10325e4b17023SJohn Marino do_warn_double_promotion (result_type, type0, type1,
10326e4b17023SJohn Marino "implicit conversion from %qT to %qT "
10327e4b17023SJohn Marino "to match other operand of binary "
10328e4b17023SJohn Marino "expression",
10329e4b17023SJohn Marino location);
10330e4b17023SJohn Marino if (result_type == error_mark_node)
10331e4b17023SJohn Marino return error_mark_node;
10332e4b17023SJohn Marino }
10333e4b17023SJohn Marino
10334e4b17023SJohn Marino if (first_complex != second_complex
10335e4b17023SJohn Marino && (code == PLUS_EXPR
10336e4b17023SJohn Marino || code == MINUS_EXPR
10337e4b17023SJohn Marino || code == MULT_EXPR
10338e4b17023SJohn Marino || (code == TRUNC_DIV_EXPR && first_complex))
10339e4b17023SJohn Marino && TREE_CODE (TREE_TYPE (result_type)) == REAL_TYPE
10340e4b17023SJohn Marino && flag_signed_zeros)
10341e4b17023SJohn Marino {
10342e4b17023SJohn Marino /* An operation on mixed real/complex operands must be
10343e4b17023SJohn Marino handled specially, but the language-independent code can
10344e4b17023SJohn Marino more easily optimize the plain complex arithmetic if
10345e4b17023SJohn Marino -fno-signed-zeros. */
10346e4b17023SJohn Marino tree real_type = TREE_TYPE (result_type);
10347e4b17023SJohn Marino tree real, imag;
10348e4b17023SJohn Marino if (type0 != orig_type0 || type1 != orig_type1)
10349e4b17023SJohn Marino {
10350e4b17023SJohn Marino gcc_assert (may_need_excess_precision && common);
10351e4b17023SJohn Marino semantic_result_type = c_common_type (orig_type0, orig_type1);
10352e4b17023SJohn Marino }
10353e4b17023SJohn Marino if (first_complex)
10354e4b17023SJohn Marino {
10355e4b17023SJohn Marino if (TREE_TYPE (op0) != result_type)
10356e4b17023SJohn Marino op0 = convert_and_check (result_type, op0);
10357e4b17023SJohn Marino if (TREE_TYPE (op1) != real_type)
10358e4b17023SJohn Marino op1 = convert_and_check (real_type, op1);
10359e4b17023SJohn Marino }
10360e4b17023SJohn Marino else
10361e4b17023SJohn Marino {
10362e4b17023SJohn Marino if (TREE_TYPE (op0) != real_type)
10363e4b17023SJohn Marino op0 = convert_and_check (real_type, op0);
10364e4b17023SJohn Marino if (TREE_TYPE (op1) != result_type)
10365e4b17023SJohn Marino op1 = convert_and_check (result_type, op1);
10366e4b17023SJohn Marino }
10367e4b17023SJohn Marino if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
10368e4b17023SJohn Marino return error_mark_node;
10369e4b17023SJohn Marino if (first_complex)
10370e4b17023SJohn Marino {
10371e4b17023SJohn Marino op0 = c_save_expr (op0);
10372e4b17023SJohn Marino real = build_unary_op (EXPR_LOCATION (orig_op0), REALPART_EXPR,
10373e4b17023SJohn Marino op0, 1);
10374e4b17023SJohn Marino imag = build_unary_op (EXPR_LOCATION (orig_op0), IMAGPART_EXPR,
10375e4b17023SJohn Marino op0, 1);
10376e4b17023SJohn Marino switch (code)
10377e4b17023SJohn Marino {
10378e4b17023SJohn Marino case MULT_EXPR:
10379e4b17023SJohn Marino case TRUNC_DIV_EXPR:
10380e4b17023SJohn Marino op1 = c_save_expr (op1);
10381e4b17023SJohn Marino imag = build2 (resultcode, real_type, imag, op1);
10382e4b17023SJohn Marino /* Fall through. */
10383e4b17023SJohn Marino case PLUS_EXPR:
10384e4b17023SJohn Marino case MINUS_EXPR:
10385e4b17023SJohn Marino real = build2 (resultcode, real_type, real, op1);
10386e4b17023SJohn Marino break;
10387e4b17023SJohn Marino default:
10388e4b17023SJohn Marino gcc_unreachable();
10389e4b17023SJohn Marino }
10390e4b17023SJohn Marino }
10391e4b17023SJohn Marino else
10392e4b17023SJohn Marino {
10393e4b17023SJohn Marino op1 = c_save_expr (op1);
10394e4b17023SJohn Marino real = build_unary_op (EXPR_LOCATION (orig_op1), REALPART_EXPR,
10395e4b17023SJohn Marino op1, 1);
10396e4b17023SJohn Marino imag = build_unary_op (EXPR_LOCATION (orig_op1), IMAGPART_EXPR,
10397e4b17023SJohn Marino op1, 1);
10398e4b17023SJohn Marino switch (code)
10399e4b17023SJohn Marino {
10400e4b17023SJohn Marino case MULT_EXPR:
10401e4b17023SJohn Marino op0 = c_save_expr (op0);
10402e4b17023SJohn Marino imag = build2 (resultcode, real_type, op0, imag);
10403e4b17023SJohn Marino /* Fall through. */
10404e4b17023SJohn Marino case PLUS_EXPR:
10405e4b17023SJohn Marino real = build2 (resultcode, real_type, op0, real);
10406e4b17023SJohn Marino break;
10407e4b17023SJohn Marino case MINUS_EXPR:
10408e4b17023SJohn Marino real = build2 (resultcode, real_type, op0, real);
10409e4b17023SJohn Marino imag = build1 (NEGATE_EXPR, real_type, imag);
10410e4b17023SJohn Marino break;
10411e4b17023SJohn Marino default:
10412e4b17023SJohn Marino gcc_unreachable();
10413e4b17023SJohn Marino }
10414e4b17023SJohn Marino }
10415e4b17023SJohn Marino ret = build2 (COMPLEX_EXPR, result_type, real, imag);
10416e4b17023SJohn Marino goto return_build_binary_op;
10417e4b17023SJohn Marino }
10418e4b17023SJohn Marino
10419e4b17023SJohn Marino /* For certain operations (which identify themselves by shorten != 0)
10420e4b17023SJohn Marino if both args were extended from the same smaller type,
10421e4b17023SJohn Marino do the arithmetic in that type and then extend.
10422e4b17023SJohn Marino
10423e4b17023SJohn Marino shorten !=0 and !=1 indicates a bitwise operation.
10424e4b17023SJohn Marino For them, this optimization is safe only if
10425e4b17023SJohn Marino both args are zero-extended or both are sign-extended.
10426e4b17023SJohn Marino Otherwise, we might change the result.
10427e4b17023SJohn Marino Eg, (short)-1 | (unsigned short)-1 is (int)-1
10428e4b17023SJohn Marino but calculated in (unsigned short) it would be (unsigned short)-1. */
10429e4b17023SJohn Marino
10430e4b17023SJohn Marino if (shorten && none_complex)
10431e4b17023SJohn Marino {
10432e4b17023SJohn Marino final_type = result_type;
10433e4b17023SJohn Marino result_type = shorten_binary_op (result_type, op0, op1,
10434e4b17023SJohn Marino shorten == -1);
10435e4b17023SJohn Marino }
10436e4b17023SJohn Marino
10437e4b17023SJohn Marino /* Shifts can be shortened if shifting right. */
10438e4b17023SJohn Marino
10439e4b17023SJohn Marino if (short_shift)
10440e4b17023SJohn Marino {
10441e4b17023SJohn Marino int unsigned_arg;
10442e4b17023SJohn Marino tree arg0 = get_narrower (op0, &unsigned_arg);
10443e4b17023SJohn Marino
10444e4b17023SJohn Marino final_type = result_type;
10445e4b17023SJohn Marino
10446e4b17023SJohn Marino if (arg0 == op0 && final_type == TREE_TYPE (op0))
10447e4b17023SJohn Marino unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
10448e4b17023SJohn Marino
10449e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
10450e4b17023SJohn Marino && tree_int_cst_sgn (op1) > 0
10451e4b17023SJohn Marino /* We can shorten only if the shift count is less than the
10452e4b17023SJohn Marino number of bits in the smaller type size. */
10453e4b17023SJohn Marino && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
10454e4b17023SJohn Marino /* We cannot drop an unsigned shift after sign-extension. */
10455e4b17023SJohn Marino && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
10456e4b17023SJohn Marino {
10457e4b17023SJohn Marino /* Do an unsigned shift if the operand was zero-extended. */
10458e4b17023SJohn Marino result_type
10459e4b17023SJohn Marino = c_common_signed_or_unsigned_type (unsigned_arg,
10460e4b17023SJohn Marino TREE_TYPE (arg0));
10461e4b17023SJohn Marino /* Convert value-to-be-shifted to that type. */
10462e4b17023SJohn Marino if (TREE_TYPE (op0) != result_type)
10463e4b17023SJohn Marino op0 = convert (result_type, op0);
10464e4b17023SJohn Marino converted = 1;
10465e4b17023SJohn Marino }
10466e4b17023SJohn Marino }
10467e4b17023SJohn Marino
10468e4b17023SJohn Marino /* Comparison operations are shortened too but differently.
10469e4b17023SJohn Marino They identify themselves by setting short_compare = 1. */
10470e4b17023SJohn Marino
10471e4b17023SJohn Marino if (short_compare)
10472e4b17023SJohn Marino {
10473e4b17023SJohn Marino /* Don't write &op0, etc., because that would prevent op0
10474e4b17023SJohn Marino from being kept in a register.
10475e4b17023SJohn Marino Instead, make copies of the our local variables and
10476e4b17023SJohn Marino pass the copies by reference, then copy them back afterward. */
10477e4b17023SJohn Marino tree xop0 = op0, xop1 = op1, xresult_type = result_type;
10478e4b17023SJohn Marino enum tree_code xresultcode = resultcode;
10479e4b17023SJohn Marino tree val
10480e4b17023SJohn Marino = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
10481e4b17023SJohn Marino
10482e4b17023SJohn Marino if (val != 0)
10483e4b17023SJohn Marino {
10484e4b17023SJohn Marino ret = val;
10485e4b17023SJohn Marino goto return_build_binary_op;
10486e4b17023SJohn Marino }
10487e4b17023SJohn Marino
10488e4b17023SJohn Marino op0 = xop0, op1 = xop1;
10489e4b17023SJohn Marino converted = 1;
10490e4b17023SJohn Marino resultcode = xresultcode;
10491e4b17023SJohn Marino
10492e4b17023SJohn Marino if (c_inhibit_evaluation_warnings == 0)
10493e4b17023SJohn Marino {
10494e4b17023SJohn Marino bool op0_maybe_const = true;
10495e4b17023SJohn Marino bool op1_maybe_const = true;
10496e4b17023SJohn Marino tree orig_op0_folded, orig_op1_folded;
10497e4b17023SJohn Marino
10498e4b17023SJohn Marino if (in_late_binary_op)
10499e4b17023SJohn Marino {
10500e4b17023SJohn Marino orig_op0_folded = orig_op0;
10501e4b17023SJohn Marino orig_op1_folded = orig_op1;
10502e4b17023SJohn Marino }
10503e4b17023SJohn Marino else
10504e4b17023SJohn Marino {
10505e4b17023SJohn Marino /* Fold for the sake of possible warnings, as in
10506e4b17023SJohn Marino build_conditional_expr. This requires the
10507e4b17023SJohn Marino "original" values to be folded, not just op0 and
10508e4b17023SJohn Marino op1. */
10509e4b17023SJohn Marino c_inhibit_evaluation_warnings++;
10510e4b17023SJohn Marino op0 = c_fully_fold (op0, require_constant_value,
10511e4b17023SJohn Marino &op0_maybe_const);
10512e4b17023SJohn Marino op1 = c_fully_fold (op1, require_constant_value,
10513e4b17023SJohn Marino &op1_maybe_const);
10514e4b17023SJohn Marino c_inhibit_evaluation_warnings--;
10515e4b17023SJohn Marino orig_op0_folded = c_fully_fold (orig_op0,
10516e4b17023SJohn Marino require_constant_value,
10517e4b17023SJohn Marino NULL);
10518e4b17023SJohn Marino orig_op1_folded = c_fully_fold (orig_op1,
10519e4b17023SJohn Marino require_constant_value,
10520e4b17023SJohn Marino NULL);
10521e4b17023SJohn Marino }
10522e4b17023SJohn Marino
10523e4b17023SJohn Marino if (warn_sign_compare)
10524e4b17023SJohn Marino warn_for_sign_compare (location, orig_op0_folded,
10525e4b17023SJohn Marino orig_op1_folded, op0, op1,
10526e4b17023SJohn Marino result_type, resultcode);
10527e4b17023SJohn Marino if (!in_late_binary_op && !int_operands)
10528e4b17023SJohn Marino {
10529e4b17023SJohn Marino if (!op0_maybe_const || TREE_CODE (op0) != INTEGER_CST)
10530e4b17023SJohn Marino op0 = c_wrap_maybe_const (op0, !op0_maybe_const);
10531e4b17023SJohn Marino if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
10532e4b17023SJohn Marino op1 = c_wrap_maybe_const (op1, !op1_maybe_const);
10533e4b17023SJohn Marino }
10534e4b17023SJohn Marino }
10535e4b17023SJohn Marino }
10536e4b17023SJohn Marino }
10537e4b17023SJohn Marino
10538e4b17023SJohn Marino /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
10539e4b17023SJohn Marino If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
10540e4b17023SJohn Marino Then the expression will be built.
10541e4b17023SJohn Marino It will be given type FINAL_TYPE if that is nonzero;
10542e4b17023SJohn Marino otherwise, it will be given type RESULT_TYPE. */
10543e4b17023SJohn Marino
10544e4b17023SJohn Marino if (!result_type)
10545e4b17023SJohn Marino {
10546e4b17023SJohn Marino binary_op_error (location, code, TREE_TYPE (op0), TREE_TYPE (op1));
10547e4b17023SJohn Marino return error_mark_node;
10548e4b17023SJohn Marino }
10549e4b17023SJohn Marino
10550e4b17023SJohn Marino if (build_type == NULL_TREE)
10551e4b17023SJohn Marino {
10552e4b17023SJohn Marino build_type = result_type;
10553e4b17023SJohn Marino if ((type0 != orig_type0 || type1 != orig_type1)
10554e4b17023SJohn Marino && !boolean_op)
10555e4b17023SJohn Marino {
10556e4b17023SJohn Marino gcc_assert (may_need_excess_precision && common);
10557e4b17023SJohn Marino semantic_result_type = c_common_type (orig_type0, orig_type1);
10558e4b17023SJohn Marino }
10559e4b17023SJohn Marino }
10560e4b17023SJohn Marino
10561e4b17023SJohn Marino if (!converted)
10562e4b17023SJohn Marino {
10563e4b17023SJohn Marino op0 = ep_convert_and_check (result_type, op0, semantic_result_type);
10564e4b17023SJohn Marino op1 = ep_convert_and_check (result_type, op1, semantic_result_type);
10565e4b17023SJohn Marino
10566e4b17023SJohn Marino /* This can happen if one operand has a vector type, and the other
10567e4b17023SJohn Marino has a different type. */
10568e4b17023SJohn Marino if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
10569e4b17023SJohn Marino return error_mark_node;
10570e4b17023SJohn Marino }
10571e4b17023SJohn Marino
10572e4b17023SJohn Marino /* Treat expressions in initializers specially as they can't trap. */
10573e4b17023SJohn Marino if (int_const_or_overflow)
10574e4b17023SJohn Marino ret = (require_constant_value
10575e4b17023SJohn Marino ? fold_build2_initializer_loc (location, resultcode, build_type,
10576e4b17023SJohn Marino op0, op1)
10577e4b17023SJohn Marino : fold_build2_loc (location, resultcode, build_type, op0, op1));
10578e4b17023SJohn Marino else
10579e4b17023SJohn Marino ret = build2 (resultcode, build_type, op0, op1);
10580e4b17023SJohn Marino if (final_type != 0)
10581e4b17023SJohn Marino ret = convert (final_type, ret);
10582e4b17023SJohn Marino
10583e4b17023SJohn Marino return_build_binary_op:
10584e4b17023SJohn Marino gcc_assert (ret != error_mark_node);
10585e4b17023SJohn Marino if (TREE_CODE (ret) == INTEGER_CST && !TREE_OVERFLOW (ret) && !int_const)
10586e4b17023SJohn Marino ret = (int_operands
10587e4b17023SJohn Marino ? note_integer_operands (ret)
10588e4b17023SJohn Marino : build1 (NOP_EXPR, TREE_TYPE (ret), ret));
10589e4b17023SJohn Marino else if (TREE_CODE (ret) != INTEGER_CST && int_operands
10590e4b17023SJohn Marino && !in_late_binary_op)
10591e4b17023SJohn Marino ret = note_integer_operands (ret);
10592e4b17023SJohn Marino if (semantic_result_type)
10593e4b17023SJohn Marino ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret);
10594e4b17023SJohn Marino protected_set_expr_location (ret, location);
10595e4b17023SJohn Marino return ret;
10596e4b17023SJohn Marino }
10597e4b17023SJohn Marino
10598e4b17023SJohn Marino
10599e4b17023SJohn Marino /* Convert EXPR to be a truth-value, validating its type for this
10600e4b17023SJohn Marino purpose. LOCATION is the source location for the expression. */
10601e4b17023SJohn Marino
10602e4b17023SJohn Marino tree
c_objc_common_truthvalue_conversion(location_t location,tree expr)10603e4b17023SJohn Marino c_objc_common_truthvalue_conversion (location_t location, tree expr)
10604e4b17023SJohn Marino {
10605e4b17023SJohn Marino bool int_const, int_operands;
10606e4b17023SJohn Marino
10607e4b17023SJohn Marino switch (TREE_CODE (TREE_TYPE (expr)))
10608e4b17023SJohn Marino {
10609e4b17023SJohn Marino case ARRAY_TYPE:
10610e4b17023SJohn Marino error_at (location, "used array that cannot be converted to pointer where scalar is required");
10611e4b17023SJohn Marino return error_mark_node;
10612e4b17023SJohn Marino
10613e4b17023SJohn Marino case RECORD_TYPE:
10614e4b17023SJohn Marino error_at (location, "used struct type value where scalar is required");
10615e4b17023SJohn Marino return error_mark_node;
10616e4b17023SJohn Marino
10617e4b17023SJohn Marino case UNION_TYPE:
10618e4b17023SJohn Marino error_at (location, "used union type value where scalar is required");
10619e4b17023SJohn Marino return error_mark_node;
10620e4b17023SJohn Marino
10621e4b17023SJohn Marino case VOID_TYPE:
10622e4b17023SJohn Marino error_at (location, "void value not ignored as it ought to be");
10623e4b17023SJohn Marino return error_mark_node;
10624e4b17023SJohn Marino
10625e4b17023SJohn Marino case FUNCTION_TYPE:
10626e4b17023SJohn Marino gcc_unreachable ();
10627e4b17023SJohn Marino
10628e4b17023SJohn Marino case VECTOR_TYPE:
10629e4b17023SJohn Marino error_at (location, "used vector type where scalar is required");
10630e4b17023SJohn Marino return error_mark_node;
10631e4b17023SJohn Marino
10632e4b17023SJohn Marino default:
10633e4b17023SJohn Marino break;
10634e4b17023SJohn Marino }
10635e4b17023SJohn Marino
10636e4b17023SJohn Marino int_const = (TREE_CODE (expr) == INTEGER_CST && !TREE_OVERFLOW (expr));
10637e4b17023SJohn Marino int_operands = EXPR_INT_CONST_OPERANDS (expr);
106385ce9237cSJohn Marino if (int_operands && TREE_CODE (expr) != INTEGER_CST)
106395ce9237cSJohn Marino {
10640e4b17023SJohn Marino expr = remove_c_maybe_const_expr (expr);
106415ce9237cSJohn Marino expr = build2 (NE_EXPR, integer_type_node, expr,
106425ce9237cSJohn Marino convert (TREE_TYPE (expr), integer_zero_node));
106435ce9237cSJohn Marino expr = note_integer_operands (expr);
106445ce9237cSJohn Marino }
106455ce9237cSJohn Marino else
10646e4b17023SJohn Marino /* ??? Should we also give an error for vectors rather than leaving
10647e4b17023SJohn Marino those to give errors later? */
10648e4b17023SJohn Marino expr = c_common_truthvalue_conversion (location, expr);
10649e4b17023SJohn Marino
10650e4b17023SJohn Marino if (TREE_CODE (expr) == INTEGER_CST && int_operands && !int_const)
10651e4b17023SJohn Marino {
10652e4b17023SJohn Marino if (TREE_OVERFLOW (expr))
10653e4b17023SJohn Marino return expr;
10654e4b17023SJohn Marino else
10655e4b17023SJohn Marino return note_integer_operands (expr);
10656e4b17023SJohn Marino }
10657e4b17023SJohn Marino if (TREE_CODE (expr) == INTEGER_CST && !int_const)
10658e4b17023SJohn Marino return build1 (NOP_EXPR, TREE_TYPE (expr), expr);
10659e4b17023SJohn Marino return expr;
10660e4b17023SJohn Marino }
10661e4b17023SJohn Marino
10662e4b17023SJohn Marino
10663e4b17023SJohn Marino /* Convert EXPR to a contained DECL, updating *TC, *TI and *SE as
10664e4b17023SJohn Marino required. */
10665e4b17023SJohn Marino
10666e4b17023SJohn Marino tree
c_expr_to_decl(tree expr,bool * tc ATTRIBUTE_UNUSED,bool * se)10667e4b17023SJohn Marino c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED, bool *se)
10668e4b17023SJohn Marino {
10669e4b17023SJohn Marino if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
10670e4b17023SJohn Marino {
10671e4b17023SJohn Marino tree decl = COMPOUND_LITERAL_EXPR_DECL (expr);
10672e4b17023SJohn Marino /* Executing a compound literal inside a function reinitializes
10673e4b17023SJohn Marino it. */
10674e4b17023SJohn Marino if (!TREE_STATIC (decl))
10675e4b17023SJohn Marino *se = true;
10676e4b17023SJohn Marino return decl;
10677e4b17023SJohn Marino }
10678e4b17023SJohn Marino else
10679e4b17023SJohn Marino return expr;
10680e4b17023SJohn Marino }
10681e4b17023SJohn Marino
10682e4b17023SJohn Marino /* Like c_begin_compound_stmt, except force the retention of the BLOCK. */
10683e4b17023SJohn Marino
10684e4b17023SJohn Marino tree
c_begin_omp_parallel(void)10685e4b17023SJohn Marino c_begin_omp_parallel (void)
10686e4b17023SJohn Marino {
10687e4b17023SJohn Marino tree block;
10688e4b17023SJohn Marino
10689e4b17023SJohn Marino keep_next_level ();
10690e4b17023SJohn Marino block = c_begin_compound_stmt (true);
10691e4b17023SJohn Marino
10692e4b17023SJohn Marino return block;
10693e4b17023SJohn Marino }
10694e4b17023SJohn Marino
10695e4b17023SJohn Marino /* Generate OMP_PARALLEL, with CLAUSES and BLOCK as its compound
10696e4b17023SJohn Marino statement. LOC is the location of the OMP_PARALLEL. */
10697e4b17023SJohn Marino
10698e4b17023SJohn Marino tree
c_finish_omp_parallel(location_t loc,tree clauses,tree block)10699e4b17023SJohn Marino c_finish_omp_parallel (location_t loc, tree clauses, tree block)
10700e4b17023SJohn Marino {
10701e4b17023SJohn Marino tree stmt;
10702e4b17023SJohn Marino
10703e4b17023SJohn Marino block = c_end_compound_stmt (loc, block, true);
10704e4b17023SJohn Marino
10705e4b17023SJohn Marino stmt = make_node (OMP_PARALLEL);
10706e4b17023SJohn Marino TREE_TYPE (stmt) = void_type_node;
10707e4b17023SJohn Marino OMP_PARALLEL_CLAUSES (stmt) = clauses;
10708e4b17023SJohn Marino OMP_PARALLEL_BODY (stmt) = block;
10709e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, loc);
10710e4b17023SJohn Marino
10711e4b17023SJohn Marino return add_stmt (stmt);
10712e4b17023SJohn Marino }
10713e4b17023SJohn Marino
10714e4b17023SJohn Marino /* Like c_begin_compound_stmt, except force the retention of the BLOCK. */
10715e4b17023SJohn Marino
10716e4b17023SJohn Marino tree
c_begin_omp_task(void)10717e4b17023SJohn Marino c_begin_omp_task (void)
10718e4b17023SJohn Marino {
10719e4b17023SJohn Marino tree block;
10720e4b17023SJohn Marino
10721e4b17023SJohn Marino keep_next_level ();
10722e4b17023SJohn Marino block = c_begin_compound_stmt (true);
10723e4b17023SJohn Marino
10724e4b17023SJohn Marino return block;
10725e4b17023SJohn Marino }
10726e4b17023SJohn Marino
10727e4b17023SJohn Marino /* Generate OMP_TASK, with CLAUSES and BLOCK as its compound
10728e4b17023SJohn Marino statement. LOC is the location of the #pragma. */
10729e4b17023SJohn Marino
10730e4b17023SJohn Marino tree
c_finish_omp_task(location_t loc,tree clauses,tree block)10731e4b17023SJohn Marino c_finish_omp_task (location_t loc, tree clauses, tree block)
10732e4b17023SJohn Marino {
10733e4b17023SJohn Marino tree stmt;
10734e4b17023SJohn Marino
10735e4b17023SJohn Marino block = c_end_compound_stmt (loc, block, true);
10736e4b17023SJohn Marino
10737e4b17023SJohn Marino stmt = make_node (OMP_TASK);
10738e4b17023SJohn Marino TREE_TYPE (stmt) = void_type_node;
10739e4b17023SJohn Marino OMP_TASK_CLAUSES (stmt) = clauses;
10740e4b17023SJohn Marino OMP_TASK_BODY (stmt) = block;
10741e4b17023SJohn Marino SET_EXPR_LOCATION (stmt, loc);
10742e4b17023SJohn Marino
10743e4b17023SJohn Marino return add_stmt (stmt);
10744e4b17023SJohn Marino }
10745e4b17023SJohn Marino
10746e4b17023SJohn Marino /* For all elements of CLAUSES, validate them vs OpenMP constraints.
10747e4b17023SJohn Marino Remove any elements from the list that are invalid. */
10748e4b17023SJohn Marino
10749e4b17023SJohn Marino tree
c_finish_omp_clauses(tree clauses)10750e4b17023SJohn Marino c_finish_omp_clauses (tree clauses)
10751e4b17023SJohn Marino {
10752e4b17023SJohn Marino bitmap_head generic_head, firstprivate_head, lastprivate_head;
10753e4b17023SJohn Marino tree c, t, *pc = &clauses;
10754e4b17023SJohn Marino const char *name;
10755e4b17023SJohn Marino
10756e4b17023SJohn Marino bitmap_obstack_initialize (NULL);
10757e4b17023SJohn Marino bitmap_initialize (&generic_head, &bitmap_default_obstack);
10758e4b17023SJohn Marino bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
10759e4b17023SJohn Marino bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
10760e4b17023SJohn Marino
10761e4b17023SJohn Marino for (pc = &clauses, c = clauses; c ; c = *pc)
10762e4b17023SJohn Marino {
10763e4b17023SJohn Marino bool remove = false;
10764e4b17023SJohn Marino bool need_complete = false;
10765e4b17023SJohn Marino bool need_implicitly_determined = false;
10766e4b17023SJohn Marino
10767e4b17023SJohn Marino switch (OMP_CLAUSE_CODE (c))
10768e4b17023SJohn Marino {
10769e4b17023SJohn Marino case OMP_CLAUSE_SHARED:
10770e4b17023SJohn Marino name = "shared";
10771e4b17023SJohn Marino need_implicitly_determined = true;
10772e4b17023SJohn Marino goto check_dup_generic;
10773e4b17023SJohn Marino
10774e4b17023SJohn Marino case OMP_CLAUSE_PRIVATE:
10775e4b17023SJohn Marino name = "private";
10776e4b17023SJohn Marino need_complete = true;
10777e4b17023SJohn Marino need_implicitly_determined = true;
10778e4b17023SJohn Marino goto check_dup_generic;
10779e4b17023SJohn Marino
10780e4b17023SJohn Marino case OMP_CLAUSE_REDUCTION:
10781e4b17023SJohn Marino name = "reduction";
10782e4b17023SJohn Marino need_implicitly_determined = true;
10783e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10784e4b17023SJohn Marino if (AGGREGATE_TYPE_P (TREE_TYPE (t))
10785e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (t)))
10786e4b17023SJohn Marino {
10787e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10788e4b17023SJohn Marino "%qE has invalid type for %<reduction%>", t);
10789e4b17023SJohn Marino remove = true;
10790e4b17023SJohn Marino }
10791e4b17023SJohn Marino else if (FLOAT_TYPE_P (TREE_TYPE (t)))
10792e4b17023SJohn Marino {
10793e4b17023SJohn Marino enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
10794e4b17023SJohn Marino const char *r_name = NULL;
10795e4b17023SJohn Marino
10796e4b17023SJohn Marino switch (r_code)
10797e4b17023SJohn Marino {
10798e4b17023SJohn Marino case PLUS_EXPR:
10799e4b17023SJohn Marino case MULT_EXPR:
10800e4b17023SJohn Marino case MINUS_EXPR:
10801e4b17023SJohn Marino case MIN_EXPR:
10802e4b17023SJohn Marino case MAX_EXPR:
10803e4b17023SJohn Marino break;
10804e4b17023SJohn Marino case BIT_AND_EXPR:
10805e4b17023SJohn Marino r_name = "&";
10806e4b17023SJohn Marino break;
10807e4b17023SJohn Marino case BIT_XOR_EXPR:
10808e4b17023SJohn Marino r_name = "^";
10809e4b17023SJohn Marino break;
10810e4b17023SJohn Marino case BIT_IOR_EXPR:
10811e4b17023SJohn Marino r_name = "|";
10812e4b17023SJohn Marino break;
10813e4b17023SJohn Marino case TRUTH_ANDIF_EXPR:
10814e4b17023SJohn Marino r_name = "&&";
10815e4b17023SJohn Marino break;
10816e4b17023SJohn Marino case TRUTH_ORIF_EXPR:
10817e4b17023SJohn Marino r_name = "||";
10818e4b17023SJohn Marino break;
10819e4b17023SJohn Marino default:
10820e4b17023SJohn Marino gcc_unreachable ();
10821e4b17023SJohn Marino }
10822e4b17023SJohn Marino if (r_name)
10823e4b17023SJohn Marino {
10824e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10825e4b17023SJohn Marino "%qE has invalid type for %<reduction(%s)%>",
10826e4b17023SJohn Marino t, r_name);
10827e4b17023SJohn Marino remove = true;
10828e4b17023SJohn Marino }
10829e4b17023SJohn Marino }
10830e4b17023SJohn Marino goto check_dup_generic;
10831e4b17023SJohn Marino
10832e4b17023SJohn Marino case OMP_CLAUSE_COPYPRIVATE:
10833e4b17023SJohn Marino name = "copyprivate";
10834e4b17023SJohn Marino goto check_dup_generic;
10835e4b17023SJohn Marino
10836e4b17023SJohn Marino case OMP_CLAUSE_COPYIN:
10837e4b17023SJohn Marino name = "copyin";
10838e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10839e4b17023SJohn Marino if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t))
10840e4b17023SJohn Marino {
10841e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10842e4b17023SJohn Marino "%qE must be %<threadprivate%> for %<copyin%>", t);
10843e4b17023SJohn Marino remove = true;
10844e4b17023SJohn Marino }
10845e4b17023SJohn Marino goto check_dup_generic;
10846e4b17023SJohn Marino
10847e4b17023SJohn Marino check_dup_generic:
10848e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10849e4b17023SJohn Marino if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
10850e4b17023SJohn Marino {
10851e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10852e4b17023SJohn Marino "%qE is not a variable in clause %qs", t, name);
10853e4b17023SJohn Marino remove = true;
10854e4b17023SJohn Marino }
10855e4b17023SJohn Marino else if (bitmap_bit_p (&generic_head, DECL_UID (t))
10856e4b17023SJohn Marino || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
10857e4b17023SJohn Marino || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
10858e4b17023SJohn Marino {
10859e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10860e4b17023SJohn Marino "%qE appears more than once in data clauses", t);
10861e4b17023SJohn Marino remove = true;
10862e4b17023SJohn Marino }
10863e4b17023SJohn Marino else
10864e4b17023SJohn Marino bitmap_set_bit (&generic_head, DECL_UID (t));
10865e4b17023SJohn Marino break;
10866e4b17023SJohn Marino
10867e4b17023SJohn Marino case OMP_CLAUSE_FIRSTPRIVATE:
10868e4b17023SJohn Marino name = "firstprivate";
10869e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10870e4b17023SJohn Marino need_complete = true;
10871e4b17023SJohn Marino need_implicitly_determined = true;
10872e4b17023SJohn Marino if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
10873e4b17023SJohn Marino {
10874e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10875e4b17023SJohn Marino "%qE is not a variable in clause %<firstprivate%>", t);
10876e4b17023SJohn Marino remove = true;
10877e4b17023SJohn Marino }
10878e4b17023SJohn Marino else if (bitmap_bit_p (&generic_head, DECL_UID (t))
10879e4b17023SJohn Marino || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
10880e4b17023SJohn Marino {
10881e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10882e4b17023SJohn Marino "%qE appears more than once in data clauses", t);
10883e4b17023SJohn Marino remove = true;
10884e4b17023SJohn Marino }
10885e4b17023SJohn Marino else
10886e4b17023SJohn Marino bitmap_set_bit (&firstprivate_head, DECL_UID (t));
10887e4b17023SJohn Marino break;
10888e4b17023SJohn Marino
10889e4b17023SJohn Marino case OMP_CLAUSE_LASTPRIVATE:
10890e4b17023SJohn Marino name = "lastprivate";
10891e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10892e4b17023SJohn Marino need_complete = true;
10893e4b17023SJohn Marino need_implicitly_determined = true;
10894e4b17023SJohn Marino if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
10895e4b17023SJohn Marino {
10896e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10897e4b17023SJohn Marino "%qE is not a variable in clause %<lastprivate%>", t);
10898e4b17023SJohn Marino remove = true;
10899e4b17023SJohn Marino }
10900e4b17023SJohn Marino else if (bitmap_bit_p (&generic_head, DECL_UID (t))
10901e4b17023SJohn Marino || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
10902e4b17023SJohn Marino {
10903e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10904e4b17023SJohn Marino "%qE appears more than once in data clauses", t);
10905e4b17023SJohn Marino remove = true;
10906e4b17023SJohn Marino }
10907e4b17023SJohn Marino else
10908e4b17023SJohn Marino bitmap_set_bit (&lastprivate_head, DECL_UID (t));
10909e4b17023SJohn Marino break;
10910e4b17023SJohn Marino
10911e4b17023SJohn Marino case OMP_CLAUSE_IF:
10912e4b17023SJohn Marino case OMP_CLAUSE_NUM_THREADS:
10913e4b17023SJohn Marino case OMP_CLAUSE_SCHEDULE:
10914e4b17023SJohn Marino case OMP_CLAUSE_NOWAIT:
10915e4b17023SJohn Marino case OMP_CLAUSE_ORDERED:
10916e4b17023SJohn Marino case OMP_CLAUSE_DEFAULT:
10917e4b17023SJohn Marino case OMP_CLAUSE_UNTIED:
10918e4b17023SJohn Marino case OMP_CLAUSE_COLLAPSE:
10919e4b17023SJohn Marino case OMP_CLAUSE_FINAL:
10920e4b17023SJohn Marino case OMP_CLAUSE_MERGEABLE:
10921e4b17023SJohn Marino pc = &OMP_CLAUSE_CHAIN (c);
10922e4b17023SJohn Marino continue;
10923e4b17023SJohn Marino
10924e4b17023SJohn Marino default:
10925e4b17023SJohn Marino gcc_unreachable ();
10926e4b17023SJohn Marino }
10927e4b17023SJohn Marino
10928e4b17023SJohn Marino if (!remove)
10929e4b17023SJohn Marino {
10930e4b17023SJohn Marino t = OMP_CLAUSE_DECL (c);
10931e4b17023SJohn Marino
10932e4b17023SJohn Marino if (need_complete)
10933e4b17023SJohn Marino {
10934e4b17023SJohn Marino t = require_complete_type (t);
10935e4b17023SJohn Marino if (t == error_mark_node)
10936e4b17023SJohn Marino remove = true;
10937e4b17023SJohn Marino }
10938e4b17023SJohn Marino
10939e4b17023SJohn Marino if (need_implicitly_determined)
10940e4b17023SJohn Marino {
10941e4b17023SJohn Marino const char *share_name = NULL;
10942e4b17023SJohn Marino
10943e4b17023SJohn Marino if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
10944e4b17023SJohn Marino share_name = "threadprivate";
10945e4b17023SJohn Marino else switch (c_omp_predetermined_sharing (t))
10946e4b17023SJohn Marino {
10947e4b17023SJohn Marino case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
10948e4b17023SJohn Marino break;
10949e4b17023SJohn Marino case OMP_CLAUSE_DEFAULT_SHARED:
10950e4b17023SJohn Marino /* const vars may be specified in firstprivate clause. */
10951e4b17023SJohn Marino if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10952e4b17023SJohn Marino && TREE_READONLY (t))
10953e4b17023SJohn Marino break;
10954e4b17023SJohn Marino share_name = "shared";
10955e4b17023SJohn Marino break;
10956e4b17023SJohn Marino case OMP_CLAUSE_DEFAULT_PRIVATE:
10957e4b17023SJohn Marino share_name = "private";
10958e4b17023SJohn Marino break;
10959e4b17023SJohn Marino default:
10960e4b17023SJohn Marino gcc_unreachable ();
10961e4b17023SJohn Marino }
10962e4b17023SJohn Marino if (share_name)
10963e4b17023SJohn Marino {
10964e4b17023SJohn Marino error_at (OMP_CLAUSE_LOCATION (c),
10965e4b17023SJohn Marino "%qE is predetermined %qs for %qs",
10966e4b17023SJohn Marino t, share_name, name);
10967e4b17023SJohn Marino remove = true;
10968e4b17023SJohn Marino }
10969e4b17023SJohn Marino }
10970e4b17023SJohn Marino }
10971e4b17023SJohn Marino
10972e4b17023SJohn Marino if (remove)
10973e4b17023SJohn Marino *pc = OMP_CLAUSE_CHAIN (c);
10974e4b17023SJohn Marino else
10975e4b17023SJohn Marino pc = &OMP_CLAUSE_CHAIN (c);
10976e4b17023SJohn Marino }
10977e4b17023SJohn Marino
10978e4b17023SJohn Marino bitmap_obstack_release (NULL);
10979e4b17023SJohn Marino return clauses;
10980e4b17023SJohn Marino }
10981e4b17023SJohn Marino
10982e4b17023SJohn Marino /* Create a transaction node. */
10983e4b17023SJohn Marino
10984e4b17023SJohn Marino tree
c_finish_transaction(location_t loc,tree block,int flags)10985e4b17023SJohn Marino c_finish_transaction (location_t loc, tree block, int flags)
10986e4b17023SJohn Marino {
10987e4b17023SJohn Marino tree stmt = build_stmt (loc, TRANSACTION_EXPR, block);
10988e4b17023SJohn Marino if (flags & TM_STMT_ATTR_OUTER)
10989e4b17023SJohn Marino TRANSACTION_EXPR_OUTER (stmt) = 1;
10990e4b17023SJohn Marino if (flags & TM_STMT_ATTR_RELAXED)
10991e4b17023SJohn Marino TRANSACTION_EXPR_RELAXED (stmt) = 1;
10992e4b17023SJohn Marino return add_stmt (stmt);
10993e4b17023SJohn Marino }
10994e4b17023SJohn Marino
10995e4b17023SJohn Marino /* Make a variant type in the proper way for C/C++, propagating qualifiers
10996e4b17023SJohn Marino down to the element type of an array. */
10997e4b17023SJohn Marino
10998e4b17023SJohn Marino tree
c_build_qualified_type(tree type,int type_quals)10999e4b17023SJohn Marino c_build_qualified_type (tree type, int type_quals)
11000e4b17023SJohn Marino {
11001e4b17023SJohn Marino if (type == error_mark_node)
11002e4b17023SJohn Marino return type;
11003e4b17023SJohn Marino
11004e4b17023SJohn Marino if (TREE_CODE (type) == ARRAY_TYPE)
11005e4b17023SJohn Marino {
11006e4b17023SJohn Marino tree t;
11007e4b17023SJohn Marino tree element_type = c_build_qualified_type (TREE_TYPE (type),
11008e4b17023SJohn Marino type_quals);
11009e4b17023SJohn Marino
11010e4b17023SJohn Marino /* See if we already have an identically qualified type. */
11011e4b17023SJohn Marino for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
11012e4b17023SJohn Marino {
11013e4b17023SJohn Marino if (TYPE_QUALS (strip_array_types (t)) == type_quals
11014e4b17023SJohn Marino && TYPE_NAME (t) == TYPE_NAME (type)
11015e4b17023SJohn Marino && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
11016e4b17023SJohn Marino && attribute_list_equal (TYPE_ATTRIBUTES (t),
11017e4b17023SJohn Marino TYPE_ATTRIBUTES (type)))
11018e4b17023SJohn Marino break;
11019e4b17023SJohn Marino }
11020e4b17023SJohn Marino if (!t)
11021e4b17023SJohn Marino {
11022e4b17023SJohn Marino tree domain = TYPE_DOMAIN (type);
11023e4b17023SJohn Marino
11024e4b17023SJohn Marino t = build_variant_type_copy (type);
11025e4b17023SJohn Marino TREE_TYPE (t) = element_type;
11026e4b17023SJohn Marino
11027e4b17023SJohn Marino if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
11028e4b17023SJohn Marino || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
11029e4b17023SJohn Marino SET_TYPE_STRUCTURAL_EQUALITY (t);
11030e4b17023SJohn Marino else if (TYPE_CANONICAL (element_type) != element_type
11031e4b17023SJohn Marino || (domain && TYPE_CANONICAL (domain) != domain))
11032e4b17023SJohn Marino {
11033e4b17023SJohn Marino tree unqualified_canon
11034e4b17023SJohn Marino = build_array_type (TYPE_CANONICAL (element_type),
11035e4b17023SJohn Marino domain? TYPE_CANONICAL (domain)
11036e4b17023SJohn Marino : NULL_TREE);
11037e4b17023SJohn Marino TYPE_CANONICAL (t)
11038e4b17023SJohn Marino = c_build_qualified_type (unqualified_canon, type_quals);
11039e4b17023SJohn Marino }
11040e4b17023SJohn Marino else
11041e4b17023SJohn Marino TYPE_CANONICAL (t) = t;
11042e4b17023SJohn Marino }
11043e4b17023SJohn Marino return t;
11044e4b17023SJohn Marino }
11045e4b17023SJohn Marino
11046e4b17023SJohn Marino /* A restrict-qualified pointer type must be a pointer to object or
11047e4b17023SJohn Marino incomplete type. Note that the use of POINTER_TYPE_P also allows
11048e4b17023SJohn Marino REFERENCE_TYPEs, which is appropriate for C++. */
11049e4b17023SJohn Marino if ((type_quals & TYPE_QUAL_RESTRICT)
11050e4b17023SJohn Marino && (!POINTER_TYPE_P (type)
11051e4b17023SJohn Marino || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
11052e4b17023SJohn Marino {
11053e4b17023SJohn Marino error ("invalid use of %<restrict%>");
11054e4b17023SJohn Marino type_quals &= ~TYPE_QUAL_RESTRICT;
11055e4b17023SJohn Marino }
11056e4b17023SJohn Marino
11057e4b17023SJohn Marino return build_qualified_type (type, type_quals);
11058e4b17023SJohn Marino }
11059e4b17023SJohn Marino
11060e4b17023SJohn Marino /* Build a VA_ARG_EXPR for the C parser. */
11061e4b17023SJohn Marino
11062e4b17023SJohn Marino tree
c_build_va_arg(location_t loc,tree expr,tree type)11063e4b17023SJohn Marino c_build_va_arg (location_t loc, tree expr, tree type)
11064e4b17023SJohn Marino {
11065e4b17023SJohn Marino if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE)
11066e4b17023SJohn Marino warning_at (loc, OPT_Wc___compat,
11067e4b17023SJohn Marino "C++ requires promoted type, not enum type, in %<va_arg%>");
11068e4b17023SJohn Marino return build_va_arg (loc, expr, type);
11069e4b17023SJohn Marino }
11070