xref: /openbsd/gnu/gcc/gcc/c-typeck.c (revision 64bcbf86)
1404b540aSrobert /* Build expressions with type checking for C compiler.
2404b540aSrobert    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3404b540aSrobert    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4404b540aSrobert    Free Software Foundation, Inc.
5404b540aSrobert 
6404b540aSrobert This file is part of GCC.
7404b540aSrobert 
8404b540aSrobert GCC is free software; you can redistribute it and/or modify it under
9404b540aSrobert the terms of the GNU General Public License as published by the Free
10404b540aSrobert Software Foundation; either version 2, or (at your option) any later
11404b540aSrobert version.
12404b540aSrobert 
13404b540aSrobert GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14404b540aSrobert WARRANTY; without even the implied warranty of MERCHANTABILITY or
15404b540aSrobert FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16404b540aSrobert for more details.
17404b540aSrobert 
18404b540aSrobert You should have received a copy of the GNU General Public License
19404b540aSrobert along with GCC; see the file COPYING.  If not, write to the Free
20404b540aSrobert Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21404b540aSrobert 02110-1301, USA.  */
22404b540aSrobert 
23404b540aSrobert 
24404b540aSrobert /* This file is part of the C front end.
25404b540aSrobert    It contains routines to build C expressions given their operands,
26404b540aSrobert    including computing the types of the result, C-specific error checks,
27404b540aSrobert    and some optimization.  */
28404b540aSrobert 
29404b540aSrobert #include "config.h"
30404b540aSrobert #include "system.h"
31404b540aSrobert #include "coretypes.h"
32404b540aSrobert #include "tm.h"
33404b540aSrobert #include "rtl.h"
34404b540aSrobert #include "tree.h"
35404b540aSrobert #include "langhooks.h"
36404b540aSrobert #include "c-tree.h"
37404b540aSrobert #include "tm_p.h"
38404b540aSrobert #include "flags.h"
39404b540aSrobert #include "output.h"
40404b540aSrobert #include "expr.h"
41404b540aSrobert #include "toplev.h"
42404b540aSrobert #include "intl.h"
43404b540aSrobert #include "ggc.h"
44404b540aSrobert #include "target.h"
45404b540aSrobert #include "tree-iterator.h"
46404b540aSrobert #include "tree-gimple.h"
47404b540aSrobert #include "tree-flow.h"
48404b540aSrobert 
49404b540aSrobert /* Possible cases of implicit bad conversions.  Used to select
50404b540aSrobert    diagnostic messages in convert_for_assignment.  */
51404b540aSrobert enum impl_conv {
52404b540aSrobert   ic_argpass,
53404b540aSrobert   ic_argpass_nonproto,
54404b540aSrobert   ic_assign,
55404b540aSrobert   ic_init,
56404b540aSrobert   ic_return
57404b540aSrobert };
58404b540aSrobert 
59404b540aSrobert /* The level of nesting inside "__alignof__".  */
60404b540aSrobert int in_alignof;
61404b540aSrobert 
62404b540aSrobert /* The level of nesting inside "sizeof".  */
63404b540aSrobert int in_sizeof;
64404b540aSrobert 
65404b540aSrobert /* The level of nesting inside "typeof".  */
66404b540aSrobert int in_typeof;
67404b540aSrobert 
68404b540aSrobert struct c_label_context_se *label_context_stack_se;
69404b540aSrobert struct c_label_context_vm *label_context_stack_vm;
70404b540aSrobert 
71404b540aSrobert /* Nonzero if we've already printed a "missing braces around initializer"
72404b540aSrobert    message within this initializer.  */
73404b540aSrobert static int missing_braces_mentioned;
74404b540aSrobert 
75404b540aSrobert static int require_constant_value;
76404b540aSrobert static int require_constant_elements;
77404b540aSrobert 
78404b540aSrobert static bool null_pointer_constant_p (tree);
79404b540aSrobert static tree qualify_type (tree, tree);
80404b540aSrobert static int tagged_types_tu_compatible_p (tree, tree);
81404b540aSrobert static int comp_target_types (tree, tree);
82404b540aSrobert static int function_types_compatible_p (tree, tree);
83404b540aSrobert static int type_lists_compatible_p (tree, tree);
84404b540aSrobert static tree decl_constant_value_for_broken_optimization (tree);
85404b540aSrobert static tree lookup_field (tree, tree);
86404b540aSrobert static tree convert_arguments (tree, tree, tree, tree);
87404b540aSrobert static tree pointer_diff (tree, tree);
88404b540aSrobert static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
89404b540aSrobert 				    int);
90404b540aSrobert static tree valid_compound_expr_initializer (tree, tree);
91404b540aSrobert static void push_string (const char *);
92404b540aSrobert static void push_member_name (tree);
93404b540aSrobert static int spelling_length (void);
94404b540aSrobert static char *print_spelling (char *);
95404b540aSrobert static void warning_init (const char *);
96404b540aSrobert static tree digest_init (tree, tree, bool, int);
97404b540aSrobert static void output_init_element (tree, bool, tree, tree, int);
98404b540aSrobert static void output_pending_init_elements (int);
99404b540aSrobert static int set_designator (int);
100404b540aSrobert static void push_range_stack (tree);
101404b540aSrobert static void add_pending_init (tree, tree);
102404b540aSrobert static void set_nonincremental_init (void);
103404b540aSrobert static void set_nonincremental_init_from_string (tree);
104404b540aSrobert static tree find_init_member (tree);
105404b540aSrobert static void readonly_error (tree, enum lvalue_use);
106404b540aSrobert static int lvalue_or_else (tree, enum lvalue_use);
107404b540aSrobert static int lvalue_p (tree);
108404b540aSrobert static void record_maybe_used_decl (tree);
109404b540aSrobert static int comptypes_internal (tree, tree);
110404b540aSrobert 
111404b540aSrobert /* Return true if EXP is a null pointer constant, false otherwise.  */
112404b540aSrobert 
113404b540aSrobert static bool
null_pointer_constant_p(tree expr)114404b540aSrobert null_pointer_constant_p (tree expr)
115404b540aSrobert {
116404b540aSrobert   /* This should really operate on c_expr structures, but they aren't
117404b540aSrobert      yet available everywhere required.  */
118404b540aSrobert   tree type = TREE_TYPE (expr);
119404b540aSrobert   return (TREE_CODE (expr) == INTEGER_CST
120404b540aSrobert 	  && !TREE_CONSTANT_OVERFLOW (expr)
121404b540aSrobert 	  && integer_zerop (expr)
122404b540aSrobert 	  && (INTEGRAL_TYPE_P (type)
123404b540aSrobert 	      || (TREE_CODE (type) == POINTER_TYPE
124404b540aSrobert 		  && VOID_TYPE_P (TREE_TYPE (type))
125404b540aSrobert 		  && TYPE_QUALS (TREE_TYPE (type)) == TYPE_UNQUALIFIED)));
126404b540aSrobert }
127404b540aSrobert /* This is a cache to hold if two types are compatible or not.  */
128404b540aSrobert 
129404b540aSrobert struct tagged_tu_seen_cache {
130404b540aSrobert   const struct tagged_tu_seen_cache * next;
131404b540aSrobert   tree t1;
132404b540aSrobert   tree t2;
133404b540aSrobert   /* The return value of tagged_types_tu_compatible_p if we had seen
134404b540aSrobert      these two types already.  */
135404b540aSrobert   int val;
136404b540aSrobert };
137404b540aSrobert 
138404b540aSrobert static const struct tagged_tu_seen_cache * tagged_tu_seen_base;
139404b540aSrobert static void free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *);
140404b540aSrobert 
141404b540aSrobert /* Do `exp = require_complete_type (exp);' to make sure exp
142404b540aSrobert    does not have an incomplete type.  (That includes void types.)  */
143404b540aSrobert 
144404b540aSrobert tree
require_complete_type(tree value)145404b540aSrobert require_complete_type (tree value)
146404b540aSrobert {
147404b540aSrobert   tree type = TREE_TYPE (value);
148404b540aSrobert 
149404b540aSrobert   if (value == error_mark_node || type == error_mark_node)
150404b540aSrobert     return error_mark_node;
151404b540aSrobert 
152404b540aSrobert   /* First, detect a valid value with a complete type.  */
153404b540aSrobert   if (COMPLETE_TYPE_P (type))
154404b540aSrobert     return value;
155404b540aSrobert 
156404b540aSrobert   c_incomplete_type_error (value, type);
157404b540aSrobert   return error_mark_node;
158404b540aSrobert }
159404b540aSrobert 
160404b540aSrobert /* Print an error message for invalid use of an incomplete type.
161404b540aSrobert    VALUE is the expression that was used (or 0 if that isn't known)
162404b540aSrobert    and TYPE is the type that was invalid.  */
163404b540aSrobert 
164404b540aSrobert void
c_incomplete_type_error(tree value,tree type)165404b540aSrobert c_incomplete_type_error (tree value, tree type)
166404b540aSrobert {
167404b540aSrobert   const char *type_code_string;
168404b540aSrobert 
169404b540aSrobert   /* Avoid duplicate error message.  */
170404b540aSrobert   if (TREE_CODE (type) == ERROR_MARK)
171404b540aSrobert     return;
172404b540aSrobert 
173404b540aSrobert   if (value != 0 && (TREE_CODE (value) == VAR_DECL
174404b540aSrobert 		     || TREE_CODE (value) == PARM_DECL))
175404b540aSrobert     error ("%qD has an incomplete type", value);
176404b540aSrobert   else
177404b540aSrobert     {
178404b540aSrobert     retry:
179404b540aSrobert       /* We must print an error message.  Be clever about what it says.  */
180404b540aSrobert 
181404b540aSrobert       switch (TREE_CODE (type))
182404b540aSrobert 	{
183404b540aSrobert 	case RECORD_TYPE:
184404b540aSrobert 	  type_code_string = "struct";
185404b540aSrobert 	  break;
186404b540aSrobert 
187404b540aSrobert 	case UNION_TYPE:
188404b540aSrobert 	  type_code_string = "union";
189404b540aSrobert 	  break;
190404b540aSrobert 
191404b540aSrobert 	case ENUMERAL_TYPE:
192404b540aSrobert 	  type_code_string = "enum";
193404b540aSrobert 	  break;
194404b540aSrobert 
195404b540aSrobert 	case VOID_TYPE:
196404b540aSrobert 	  error ("invalid use of void expression");
197404b540aSrobert 	  return;
198404b540aSrobert 
199404b540aSrobert 	case ARRAY_TYPE:
200404b540aSrobert 	  if (TYPE_DOMAIN (type))
201404b540aSrobert 	    {
202404b540aSrobert 	      if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
203404b540aSrobert 		{
204404b540aSrobert 		  error ("invalid use of flexible array member");
205404b540aSrobert 		  return;
206404b540aSrobert 		}
207404b540aSrobert 	      type = TREE_TYPE (type);
208404b540aSrobert 	      goto retry;
209404b540aSrobert 	    }
210404b540aSrobert 	  error ("invalid use of array with unspecified bounds");
211404b540aSrobert 	  return;
212404b540aSrobert 
213404b540aSrobert 	default:
214404b540aSrobert 	  gcc_unreachable ();
215404b540aSrobert 	}
216404b540aSrobert 
217404b540aSrobert       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
218404b540aSrobert 	error ("invalid use of undefined type %<%s %E%>",
219404b540aSrobert 	       type_code_string, TYPE_NAME (type));
220404b540aSrobert       else
221404b540aSrobert 	/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
222404b540aSrobert 	error ("invalid use of incomplete typedef %qD", TYPE_NAME (type));
223404b540aSrobert     }
224404b540aSrobert }
225404b540aSrobert 
226404b540aSrobert /* Given a type, apply default promotions wrt unnamed function
227404b540aSrobert    arguments and return the new type.  */
228404b540aSrobert 
229404b540aSrobert tree
c_type_promotes_to(tree type)230404b540aSrobert c_type_promotes_to (tree type)
231404b540aSrobert {
232404b540aSrobert   if (TYPE_MAIN_VARIANT (type) == float_type_node)
233404b540aSrobert     return double_type_node;
234404b540aSrobert 
235404b540aSrobert   if (c_promoting_integer_type_p (type))
236404b540aSrobert     {
237404b540aSrobert       /* Preserve unsignedness if not really getting any wider.  */
238404b540aSrobert       if (TYPE_UNSIGNED (type)
239404b540aSrobert 	  && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
240404b540aSrobert 	return unsigned_type_node;
241404b540aSrobert       return integer_type_node;
242404b540aSrobert     }
243404b540aSrobert 
244404b540aSrobert   return type;
245404b540aSrobert }
246404b540aSrobert 
247404b540aSrobert /* Return a variant of TYPE which has all the type qualifiers of LIKE
248404b540aSrobert    as well as those of TYPE.  */
249404b540aSrobert 
250404b540aSrobert static tree
qualify_type(tree type,tree like)251404b540aSrobert qualify_type (tree type, tree like)
252404b540aSrobert {
253404b540aSrobert   return c_build_qualified_type (type,
254404b540aSrobert 				 TYPE_QUALS (type) | TYPE_QUALS (like));
255404b540aSrobert }
256404b540aSrobert 
257404b540aSrobert /* Return true iff the given tree T is a variable length array.  */
258404b540aSrobert 
259404b540aSrobert bool
c_vla_type_p(tree t)260404b540aSrobert c_vla_type_p (tree t)
261404b540aSrobert {
262404b540aSrobert   if (TREE_CODE (t) == ARRAY_TYPE
263404b540aSrobert       && C_TYPE_VARIABLE_SIZE (t))
264404b540aSrobert     return true;
265404b540aSrobert   return false;
266404b540aSrobert }
267404b540aSrobert 
268404b540aSrobert /* Return the composite type of two compatible types.
269404b540aSrobert 
270404b540aSrobert    We assume that comptypes has already been done and returned
271404b540aSrobert    nonzero; if that isn't so, this may crash.  In particular, we
272404b540aSrobert    assume that qualifiers match.  */
273404b540aSrobert 
274404b540aSrobert tree
composite_type(tree t1,tree t2)275404b540aSrobert composite_type (tree t1, tree t2)
276404b540aSrobert {
277404b540aSrobert   enum tree_code code1;
278404b540aSrobert   enum tree_code code2;
279404b540aSrobert   tree attributes;
280404b540aSrobert 
281404b540aSrobert   /* Save time if the two types are the same.  */
282404b540aSrobert 
283404b540aSrobert   if (t1 == t2) return t1;
284404b540aSrobert 
285404b540aSrobert   /* If one type is nonsense, use the other.  */
286404b540aSrobert   if (t1 == error_mark_node)
287404b540aSrobert     return t2;
288404b540aSrobert   if (t2 == error_mark_node)
289404b540aSrobert     return t1;
290404b540aSrobert 
291404b540aSrobert   code1 = TREE_CODE (t1);
292404b540aSrobert   code2 = TREE_CODE (t2);
293404b540aSrobert 
294404b540aSrobert   /* Merge the attributes.  */
295404b540aSrobert   attributes = targetm.merge_type_attributes (t1, t2);
296404b540aSrobert 
297404b540aSrobert   /* If one is an enumerated type and the other is the compatible
298404b540aSrobert      integer type, the composite type might be either of the two
299404b540aSrobert      (DR#013 question 3).  For consistency, use the enumerated type as
300404b540aSrobert      the composite type.  */
301404b540aSrobert 
302404b540aSrobert   if (code1 == ENUMERAL_TYPE && code2 == INTEGER_TYPE)
303404b540aSrobert     return t1;
304404b540aSrobert   if (code2 == ENUMERAL_TYPE && code1 == INTEGER_TYPE)
305404b540aSrobert     return t2;
306404b540aSrobert 
307404b540aSrobert   gcc_assert (code1 == code2);
308404b540aSrobert 
309404b540aSrobert   switch (code1)
310404b540aSrobert     {
311404b540aSrobert     case POINTER_TYPE:
312404b540aSrobert       /* For two pointers, do this recursively on the target type.  */
313404b540aSrobert       {
314404b540aSrobert 	tree pointed_to_1 = TREE_TYPE (t1);
315404b540aSrobert 	tree pointed_to_2 = TREE_TYPE (t2);
316404b540aSrobert 	tree target = composite_type (pointed_to_1, pointed_to_2);
317404b540aSrobert 	t1 = build_pointer_type (target);
318404b540aSrobert 	t1 = build_type_attribute_variant (t1, attributes);
319404b540aSrobert 	return qualify_type (t1, t2);
320404b540aSrobert       }
321404b540aSrobert 
322404b540aSrobert     case ARRAY_TYPE:
323404b540aSrobert       {
324404b540aSrobert 	tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
325404b540aSrobert 	int quals;
326404b540aSrobert 	tree unqual_elt;
327404b540aSrobert 	tree d1 = TYPE_DOMAIN (t1);
328404b540aSrobert 	tree d2 = TYPE_DOMAIN (t2);
329404b540aSrobert 	bool d1_variable, d2_variable;
330404b540aSrobert 	bool d1_zero, d2_zero;
331404b540aSrobert 
332404b540aSrobert 	/* We should not have any type quals on arrays at all.  */
333404b540aSrobert 	gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
334404b540aSrobert 
335404b540aSrobert 	d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1);
336404b540aSrobert 	d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2);
337404b540aSrobert 
338404b540aSrobert 	d1_variable = (!d1_zero
339404b540aSrobert 		       && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
340404b540aSrobert 			   || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
341404b540aSrobert 	d2_variable = (!d2_zero
342404b540aSrobert 		       && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
343404b540aSrobert 			   || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
344404b540aSrobert 	d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
345404b540aSrobert 	d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
346404b540aSrobert 
347404b540aSrobert 	/* Save space: see if the result is identical to one of the args.  */
348404b540aSrobert 	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)
349404b540aSrobert 	    && (d2_variable || d2_zero || !d1_variable))
350404b540aSrobert 	  return build_type_attribute_variant (t1, attributes);
351404b540aSrobert 	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)
352404b540aSrobert 	    && (d1_variable || d1_zero || !d2_variable))
353404b540aSrobert 	  return build_type_attribute_variant (t2, attributes);
354404b540aSrobert 
355404b540aSrobert 	if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
356404b540aSrobert 	  return build_type_attribute_variant (t1, attributes);
357404b540aSrobert 	if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
358404b540aSrobert 	  return build_type_attribute_variant (t2, attributes);
359404b540aSrobert 
360404b540aSrobert 	/* Merge the element types, and have a size if either arg has
361404b540aSrobert 	   one.  We may have qualifiers on the element types.  To set
362404b540aSrobert 	   up TYPE_MAIN_VARIANT correctly, we need to form the
363404b540aSrobert 	   composite of the unqualified types and add the qualifiers
364404b540aSrobert 	   back at the end.  */
365404b540aSrobert 	quals = TYPE_QUALS (strip_array_types (elt));
366404b540aSrobert 	unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
367404b540aSrobert 	t1 = build_array_type (unqual_elt,
368404b540aSrobert 			       TYPE_DOMAIN ((TYPE_DOMAIN (t1)
369404b540aSrobert 					     && (d2_variable
370404b540aSrobert 						 || d2_zero
371404b540aSrobert 						 || !d1_variable))
372404b540aSrobert 					    ? t1
373404b540aSrobert 					    : t2));
374404b540aSrobert 	t1 = c_build_qualified_type (t1, quals);
375404b540aSrobert 	return build_type_attribute_variant (t1, attributes);
376404b540aSrobert       }
377404b540aSrobert 
378404b540aSrobert     case ENUMERAL_TYPE:
379404b540aSrobert     case RECORD_TYPE:
380404b540aSrobert     case UNION_TYPE:
381404b540aSrobert       if (attributes != NULL)
382404b540aSrobert 	{
383404b540aSrobert 	  /* Try harder not to create a new aggregate type.  */
384404b540aSrobert 	  if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
385404b540aSrobert 	    return t1;
386404b540aSrobert 	  if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
387404b540aSrobert 	    return t2;
388404b540aSrobert 	}
389404b540aSrobert       return build_type_attribute_variant (t1, attributes);
390404b540aSrobert 
391404b540aSrobert     case FUNCTION_TYPE:
392404b540aSrobert       /* Function types: prefer the one that specified arg types.
393404b540aSrobert 	 If both do, merge the arg types.  Also merge the return types.  */
394404b540aSrobert       {
395404b540aSrobert 	tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
396404b540aSrobert 	tree p1 = TYPE_ARG_TYPES (t1);
397404b540aSrobert 	tree p2 = TYPE_ARG_TYPES (t2);
398404b540aSrobert 	int len;
399404b540aSrobert 	tree newargs, n;
400404b540aSrobert 	int i;
401404b540aSrobert 
402404b540aSrobert 	/* Save space: see if the result is identical to one of the args.  */
403404b540aSrobert 	if (valtype == TREE_TYPE (t1) && !TYPE_ARG_TYPES (t2))
404404b540aSrobert 	  return build_type_attribute_variant (t1, attributes);
405404b540aSrobert 	if (valtype == TREE_TYPE (t2) && !TYPE_ARG_TYPES (t1))
406404b540aSrobert 	  return build_type_attribute_variant (t2, attributes);
407404b540aSrobert 
408404b540aSrobert 	/* Simple way if one arg fails to specify argument types.  */
409404b540aSrobert 	if (TYPE_ARG_TYPES (t1) == 0)
410404b540aSrobert 	 {
411404b540aSrobert 	    t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2));
412404b540aSrobert 	    t1 = build_type_attribute_variant (t1, attributes);
413404b540aSrobert 	    return qualify_type (t1, t2);
414404b540aSrobert 	 }
415404b540aSrobert 	if (TYPE_ARG_TYPES (t2) == 0)
416404b540aSrobert 	 {
417404b540aSrobert 	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1));
418404b540aSrobert 	   t1 = build_type_attribute_variant (t1, attributes);
419404b540aSrobert 	   return qualify_type (t1, t2);
420404b540aSrobert 	 }
421404b540aSrobert 
422404b540aSrobert 	/* If both args specify argument types, we must merge the two
423404b540aSrobert 	   lists, argument by argument.  */
424404b540aSrobert 	/* Tell global_bindings_p to return false so that variable_size
425404b540aSrobert 	   doesn't die on VLAs in parameter types.  */
426404b540aSrobert 	c_override_global_bindings_to_false = true;
427404b540aSrobert 
428404b540aSrobert 	len = list_length (p1);
429404b540aSrobert 	newargs = 0;
430404b540aSrobert 
431404b540aSrobert 	for (i = 0; i < len; i++)
432404b540aSrobert 	  newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
433404b540aSrobert 
434404b540aSrobert 	n = newargs;
435404b540aSrobert 
436404b540aSrobert 	for (; p1;
437404b540aSrobert 	     p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
438404b540aSrobert 	  {
439404b540aSrobert 	    /* A null type means arg type is not specified.
440404b540aSrobert 	       Take whatever the other function type has.  */
441404b540aSrobert 	    if (TREE_VALUE (p1) == 0)
442404b540aSrobert 	      {
443404b540aSrobert 		TREE_VALUE (n) = TREE_VALUE (p2);
444404b540aSrobert 		goto parm_done;
445404b540aSrobert 	      }
446404b540aSrobert 	    if (TREE_VALUE (p2) == 0)
447404b540aSrobert 	      {
448404b540aSrobert 		TREE_VALUE (n) = TREE_VALUE (p1);
449404b540aSrobert 		goto parm_done;
450404b540aSrobert 	      }
451404b540aSrobert 
452404b540aSrobert 	    /* Given  wait (union {union wait *u; int *i} *)
453404b540aSrobert 	       and  wait (union wait *),
454404b540aSrobert 	       prefer  union wait *  as type of parm.  */
455404b540aSrobert 	    if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
456404b540aSrobert 		&& TREE_VALUE (p1) != TREE_VALUE (p2))
457404b540aSrobert 	      {
458404b540aSrobert 		tree memb;
459404b540aSrobert 		tree mv2 = TREE_VALUE (p2);
460404b540aSrobert 		if (mv2 && mv2 != error_mark_node
461404b540aSrobert 		    && TREE_CODE (mv2) != ARRAY_TYPE)
462404b540aSrobert 		  mv2 = TYPE_MAIN_VARIANT (mv2);
463404b540aSrobert 		for (memb = TYPE_FIELDS (TREE_VALUE (p1));
464404b540aSrobert 		     memb; memb = TREE_CHAIN (memb))
465404b540aSrobert 		  {
466404b540aSrobert 		    tree mv3 = TREE_TYPE (memb);
467404b540aSrobert 		    if (mv3 && mv3 != error_mark_node
468404b540aSrobert 			&& TREE_CODE (mv3) != ARRAY_TYPE)
469404b540aSrobert 		      mv3 = TYPE_MAIN_VARIANT (mv3);
470404b540aSrobert 		    if (comptypes (mv3, mv2))
471404b540aSrobert 		      {
472404b540aSrobert 			TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
473404b540aSrobert 							 TREE_VALUE (p2));
474404b540aSrobert 			if (pedantic)
475404b540aSrobert 			  pedwarn ("function types not truly compatible in ISO C");
476404b540aSrobert 			goto parm_done;
477404b540aSrobert 		      }
478404b540aSrobert 		  }
479404b540aSrobert 	      }
480404b540aSrobert 	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
481404b540aSrobert 		&& TREE_VALUE (p2) != TREE_VALUE (p1))
482404b540aSrobert 	      {
483404b540aSrobert 		tree memb;
484404b540aSrobert 		tree mv1 = TREE_VALUE (p1);
485404b540aSrobert 		if (mv1 && mv1 != error_mark_node
486404b540aSrobert 		    && TREE_CODE (mv1) != ARRAY_TYPE)
487404b540aSrobert 		  mv1 = TYPE_MAIN_VARIANT (mv1);
488404b540aSrobert 		for (memb = TYPE_FIELDS (TREE_VALUE (p2));
489404b540aSrobert 		     memb; memb = TREE_CHAIN (memb))
490404b540aSrobert 		  {
491404b540aSrobert 		    tree mv3 = TREE_TYPE (memb);
492404b540aSrobert 		    if (mv3 && mv3 != error_mark_node
493404b540aSrobert 			&& TREE_CODE (mv3) != ARRAY_TYPE)
494404b540aSrobert 		      mv3 = TYPE_MAIN_VARIANT (mv3);
495404b540aSrobert 		    if (comptypes (mv3, mv1))
496404b540aSrobert 		      {
497404b540aSrobert 			TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
498404b540aSrobert 							 TREE_VALUE (p1));
499404b540aSrobert 			if (pedantic)
500404b540aSrobert 			  pedwarn ("function types not truly compatible in ISO C");
501404b540aSrobert 			goto parm_done;
502404b540aSrobert 		      }
503404b540aSrobert 		  }
504404b540aSrobert 	      }
505404b540aSrobert 	    TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
506404b540aSrobert 	  parm_done: ;
507404b540aSrobert 	  }
508404b540aSrobert 
509404b540aSrobert 	c_override_global_bindings_to_false = false;
510404b540aSrobert 	t1 = build_function_type (valtype, newargs);
511404b540aSrobert 	t1 = qualify_type (t1, t2);
512404b540aSrobert 	/* ... falls through ...  */
513404b540aSrobert       }
514404b540aSrobert 
515404b540aSrobert     default:
516404b540aSrobert       return build_type_attribute_variant (t1, attributes);
517404b540aSrobert     }
518404b540aSrobert 
519404b540aSrobert }
520404b540aSrobert 
521404b540aSrobert /* Return the type of a conditional expression between pointers to
522404b540aSrobert    possibly differently qualified versions of compatible types.
523404b540aSrobert 
524404b540aSrobert    We assume that comp_target_types has already been done and returned
525404b540aSrobert    nonzero; if that isn't so, this may crash.  */
526404b540aSrobert 
527404b540aSrobert static tree
common_pointer_type(tree t1,tree t2)528404b540aSrobert common_pointer_type (tree t1, tree t2)
529404b540aSrobert {
530404b540aSrobert   tree attributes;
531404b540aSrobert   tree pointed_to_1, mv1;
532404b540aSrobert   tree pointed_to_2, mv2;
533404b540aSrobert   tree target;
534404b540aSrobert 
535404b540aSrobert   /* Save time if the two types are the same.  */
536404b540aSrobert 
537404b540aSrobert   if (t1 == t2) return t1;
538404b540aSrobert 
539404b540aSrobert   /* If one type is nonsense, use the other.  */
540404b540aSrobert   if (t1 == error_mark_node)
541404b540aSrobert     return t2;
542404b540aSrobert   if (t2 == error_mark_node)
543404b540aSrobert     return t1;
544404b540aSrobert 
545404b540aSrobert   gcc_assert (TREE_CODE (t1) == POINTER_TYPE
546404b540aSrobert 	      && TREE_CODE (t2) == POINTER_TYPE);
547404b540aSrobert 
548404b540aSrobert   /* Merge the attributes.  */
549404b540aSrobert   attributes = targetm.merge_type_attributes (t1, t2);
550404b540aSrobert 
551404b540aSrobert   /* Find the composite type of the target types, and combine the
552404b540aSrobert      qualifiers of the two types' targets.  Do not lose qualifiers on
553404b540aSrobert      array element types by taking the TYPE_MAIN_VARIANT.  */
554404b540aSrobert   mv1 = pointed_to_1 = TREE_TYPE (t1);
555404b540aSrobert   mv2 = pointed_to_2 = TREE_TYPE (t2);
556404b540aSrobert   if (TREE_CODE (mv1) != ARRAY_TYPE)
557404b540aSrobert     mv1 = TYPE_MAIN_VARIANT (pointed_to_1);
558404b540aSrobert   if (TREE_CODE (mv2) != ARRAY_TYPE)
559404b540aSrobert     mv2 = TYPE_MAIN_VARIANT (pointed_to_2);
560404b540aSrobert   target = composite_type (mv1, mv2);
561404b540aSrobert   t1 = build_pointer_type (c_build_qualified_type
562404b540aSrobert 			   (target,
563404b540aSrobert 			    TYPE_QUALS (pointed_to_1) |
564404b540aSrobert 			    TYPE_QUALS (pointed_to_2)));
565404b540aSrobert   return build_type_attribute_variant (t1, attributes);
566404b540aSrobert }
567404b540aSrobert 
568404b540aSrobert /* Return the common type for two arithmetic types under the usual
569404b540aSrobert    arithmetic conversions.  The default conversions have already been
570404b540aSrobert    applied, and enumerated types converted to their compatible integer
571404b540aSrobert    types.  The resulting type is unqualified and has no attributes.
572404b540aSrobert 
573404b540aSrobert    This is the type for the result of most arithmetic operations
574404b540aSrobert    if the operands have the given two types.  */
575404b540aSrobert 
576404b540aSrobert static tree
c_common_type(tree t1,tree t2)577404b540aSrobert c_common_type (tree t1, tree t2)
578404b540aSrobert {
579404b540aSrobert   enum tree_code code1;
580404b540aSrobert   enum tree_code code2;
581404b540aSrobert 
582404b540aSrobert   /* If one type is nonsense, use the other.  */
583404b540aSrobert   if (t1 == error_mark_node)
584404b540aSrobert     return t2;
585404b540aSrobert   if (t2 == error_mark_node)
586404b540aSrobert     return t1;
587404b540aSrobert 
588404b540aSrobert   if (TYPE_QUALS (t1) != TYPE_UNQUALIFIED)
589404b540aSrobert     t1 = TYPE_MAIN_VARIANT (t1);
590404b540aSrobert 
591404b540aSrobert   if (TYPE_QUALS (t2) != TYPE_UNQUALIFIED)
592404b540aSrobert     t2 = TYPE_MAIN_VARIANT (t2);
593404b540aSrobert 
594404b540aSrobert   if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
595404b540aSrobert     t1 = build_type_attribute_variant (t1, NULL_TREE);
596404b540aSrobert 
597404b540aSrobert   if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
598404b540aSrobert     t2 = build_type_attribute_variant (t2, NULL_TREE);
599404b540aSrobert 
600404b540aSrobert   /* Save time if the two types are the same.  */
601404b540aSrobert 
602404b540aSrobert   if (t1 == t2) return t1;
603404b540aSrobert 
604404b540aSrobert   code1 = TREE_CODE (t1);
605404b540aSrobert   code2 = TREE_CODE (t2);
606404b540aSrobert 
607404b540aSrobert   gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE
608404b540aSrobert 	      || code1 == REAL_TYPE || code1 == INTEGER_TYPE);
609404b540aSrobert   gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
610404b540aSrobert 	      || code2 == REAL_TYPE || code2 == INTEGER_TYPE);
611404b540aSrobert 
612404b540aSrobert   /* When one operand is a decimal float type, the other operand cannot be
613404b540aSrobert      a generic float type or a complex type.  We also disallow vector types
614404b540aSrobert      here.  */
615404b540aSrobert   if ((DECIMAL_FLOAT_TYPE_P (t1) || DECIMAL_FLOAT_TYPE_P (t2))
616404b540aSrobert       && !(DECIMAL_FLOAT_TYPE_P (t1) && DECIMAL_FLOAT_TYPE_P (t2)))
617404b540aSrobert     {
618404b540aSrobert       if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE)
619404b540aSrobert 	{
620404b540aSrobert 	  error ("can%'t mix operands of decimal float and vector types");
621404b540aSrobert 	  return error_mark_node;
622404b540aSrobert 	}
623404b540aSrobert       if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
624404b540aSrobert 	{
625404b540aSrobert 	  error ("can%'t mix operands of decimal float and complex types");
626404b540aSrobert 	  return error_mark_node;
627404b540aSrobert 	}
628404b540aSrobert       if (code1 == REAL_TYPE && code2 == REAL_TYPE)
629404b540aSrobert 	{
630404b540aSrobert 	  error ("can%'t mix operands of decimal float and other float types");
631404b540aSrobert 	  return error_mark_node;
632404b540aSrobert 	}
633404b540aSrobert     }
634404b540aSrobert 
635404b540aSrobert   /* If one type is a vector type, return that type.  (How the usual
636404b540aSrobert      arithmetic conversions apply to the vector types extension is not
637404b540aSrobert      precisely specified.)  */
638404b540aSrobert   if (code1 == VECTOR_TYPE)
639404b540aSrobert     return t1;
640404b540aSrobert 
641404b540aSrobert   if (code2 == VECTOR_TYPE)
642404b540aSrobert     return t2;
643404b540aSrobert 
644404b540aSrobert   /* If one type is complex, form the common type of the non-complex
645404b540aSrobert      components, then make that complex.  Use T1 or T2 if it is the
646404b540aSrobert      required type.  */
647404b540aSrobert   if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
648404b540aSrobert     {
649404b540aSrobert       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
650404b540aSrobert       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
651404b540aSrobert       tree subtype = c_common_type (subtype1, subtype2);
652404b540aSrobert 
653404b540aSrobert       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
654404b540aSrobert 	return t1;
655404b540aSrobert       else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
656404b540aSrobert 	return t2;
657404b540aSrobert       else
658404b540aSrobert 	return build_complex_type (subtype);
659404b540aSrobert     }
660404b540aSrobert 
661404b540aSrobert   /* If only one is real, use it as the result.  */
662404b540aSrobert 
663404b540aSrobert   if (code1 == REAL_TYPE && code2 != REAL_TYPE)
664404b540aSrobert     return t1;
665404b540aSrobert 
666404b540aSrobert   if (code2 == REAL_TYPE && code1 != REAL_TYPE)
667404b540aSrobert     return t2;
668404b540aSrobert 
669404b540aSrobert   /* If both are real and either are decimal floating point types, use
670404b540aSrobert      the decimal floating point type with the greater precision. */
671404b540aSrobert 
672404b540aSrobert   if (code1 == REAL_TYPE && code2 == REAL_TYPE)
673404b540aSrobert     {
674404b540aSrobert       if (TYPE_MAIN_VARIANT (t1) == dfloat128_type_node
675404b540aSrobert 	  || TYPE_MAIN_VARIANT (t2) == dfloat128_type_node)
676404b540aSrobert 	return dfloat128_type_node;
677404b540aSrobert       else if (TYPE_MAIN_VARIANT (t1) == dfloat64_type_node
678404b540aSrobert 	       || TYPE_MAIN_VARIANT (t2) == dfloat64_type_node)
679404b540aSrobert 	return dfloat64_type_node;
680404b540aSrobert       else if (TYPE_MAIN_VARIANT (t1) == dfloat32_type_node
681404b540aSrobert 	       || TYPE_MAIN_VARIANT (t2) == dfloat32_type_node)
682404b540aSrobert 	return dfloat32_type_node;
683404b540aSrobert     }
684404b540aSrobert 
685404b540aSrobert   /* Both real or both integers; use the one with greater precision.  */
686404b540aSrobert 
687404b540aSrobert   if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
688404b540aSrobert     return t1;
689404b540aSrobert   else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
690404b540aSrobert     return t2;
691404b540aSrobert 
692404b540aSrobert   /* Same precision.  Prefer long longs to longs to ints when the
693404b540aSrobert      same precision, following the C99 rules on integer type rank
694404b540aSrobert      (which are equivalent to the C90 rules for C90 types).  */
695404b540aSrobert 
696404b540aSrobert   if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
697404b540aSrobert       || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
698404b540aSrobert     return long_long_unsigned_type_node;
699404b540aSrobert 
700404b540aSrobert   if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
701404b540aSrobert       || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
702404b540aSrobert     {
703404b540aSrobert       if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
704404b540aSrobert 	return long_long_unsigned_type_node;
705404b540aSrobert       else
706404b540aSrobert 	return long_long_integer_type_node;
707404b540aSrobert     }
708404b540aSrobert 
709404b540aSrobert   if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
710404b540aSrobert       || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
711404b540aSrobert     return long_unsigned_type_node;
712404b540aSrobert 
713404b540aSrobert   if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
714404b540aSrobert       || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
715404b540aSrobert     {
716404b540aSrobert       /* But preserve unsignedness from the other type,
717404b540aSrobert 	 since long cannot hold all the values of an unsigned int.  */
718404b540aSrobert       if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
719404b540aSrobert 	return long_unsigned_type_node;
720404b540aSrobert       else
721404b540aSrobert 	return long_integer_type_node;
722404b540aSrobert     }
723404b540aSrobert 
724404b540aSrobert   /* Likewise, prefer long double to double even if same size.  */
725404b540aSrobert   if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
726404b540aSrobert       || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
727404b540aSrobert     return long_double_type_node;
728404b540aSrobert 
729404b540aSrobert   /* Otherwise prefer the unsigned one.  */
730404b540aSrobert 
731404b540aSrobert   if (TYPE_UNSIGNED (t1))
732404b540aSrobert     return t1;
733404b540aSrobert   else
734404b540aSrobert     return t2;
735404b540aSrobert }
736404b540aSrobert 
737404b540aSrobert /* Wrapper around c_common_type that is used by c-common.c and other
738404b540aSrobert    front end optimizations that remove promotions.  ENUMERAL_TYPEs
739404b540aSrobert    are allowed here and are converted to their compatible integer types.
740404b540aSrobert    BOOLEAN_TYPEs are allowed here and return either boolean_type_node or
741404b540aSrobert    preferably a non-Boolean type as the common type.  */
742404b540aSrobert tree
common_type(tree t1,tree t2)743404b540aSrobert common_type (tree t1, tree t2)
744404b540aSrobert {
745404b540aSrobert   if (TREE_CODE (t1) == ENUMERAL_TYPE)
746404b540aSrobert     t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
747404b540aSrobert   if (TREE_CODE (t2) == ENUMERAL_TYPE)
748404b540aSrobert     t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
749404b540aSrobert 
750404b540aSrobert   /* If both types are BOOLEAN_TYPE, then return boolean_type_node.  */
751404b540aSrobert   if (TREE_CODE (t1) == BOOLEAN_TYPE
752404b540aSrobert       && TREE_CODE (t2) == BOOLEAN_TYPE)
753404b540aSrobert     return boolean_type_node;
754404b540aSrobert 
755404b540aSrobert   /* If either type is BOOLEAN_TYPE, then return the other.  */
756404b540aSrobert   if (TREE_CODE (t1) == BOOLEAN_TYPE)
757404b540aSrobert     return t2;
758404b540aSrobert   if (TREE_CODE (t2) == BOOLEAN_TYPE)
759404b540aSrobert     return t1;
760404b540aSrobert 
761404b540aSrobert   return c_common_type (t1, t2);
762404b540aSrobert }
763404b540aSrobert 
764404b540aSrobert /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
765404b540aSrobert    or various other operations.  Return 2 if they are compatible
766404b540aSrobert    but a warning may be needed if you use them together.  */
767404b540aSrobert 
768404b540aSrobert int
comptypes(tree type1,tree type2)769404b540aSrobert comptypes (tree type1, tree type2)
770404b540aSrobert {
771404b540aSrobert   const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
772404b540aSrobert   int val;
773404b540aSrobert 
774404b540aSrobert   val = comptypes_internal (type1, type2);
775404b540aSrobert   free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
776404b540aSrobert 
777404b540aSrobert   return val;
778404b540aSrobert }
779404b540aSrobert 
780404b540aSrobert /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
781404b540aSrobert    or various other operations.  Return 2 if they are compatible
782404b540aSrobert    but a warning may be needed if you use them together.  This
783404b540aSrobert    differs from comptypes, in that we don't free the seen types.  */
784404b540aSrobert 
785404b540aSrobert static int
comptypes_internal(tree type1,tree type2)786404b540aSrobert comptypes_internal (tree type1, tree type2)
787404b540aSrobert {
788404b540aSrobert   tree t1 = type1;
789404b540aSrobert   tree t2 = type2;
790404b540aSrobert   int attrval, val;
791404b540aSrobert 
792404b540aSrobert   /* Suppress errors caused by previously reported errors.  */
793404b540aSrobert 
794404b540aSrobert   if (t1 == t2 || !t1 || !t2
795404b540aSrobert       || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
796404b540aSrobert     return 1;
797404b540aSrobert 
798404b540aSrobert   /* If either type is the internal version of sizetype, return the
799404b540aSrobert      language version.  */
800404b540aSrobert   if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
801404b540aSrobert       && TYPE_ORIG_SIZE_TYPE (t1))
802404b540aSrobert     t1 = TYPE_ORIG_SIZE_TYPE (t1);
803404b540aSrobert 
804404b540aSrobert   if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
805404b540aSrobert       && TYPE_ORIG_SIZE_TYPE (t2))
806404b540aSrobert     t2 = TYPE_ORIG_SIZE_TYPE (t2);
807404b540aSrobert 
808404b540aSrobert 
809404b540aSrobert   /* Enumerated types are compatible with integer types, but this is
810404b540aSrobert      not transitive: two enumerated types in the same translation unit
811404b540aSrobert      are compatible with each other only if they are the same type.  */
812404b540aSrobert 
813404b540aSrobert   if (TREE_CODE (t1) == ENUMERAL_TYPE && TREE_CODE (t2) != ENUMERAL_TYPE)
814404b540aSrobert     t1 = c_common_type_for_size (TYPE_PRECISION (t1), TYPE_UNSIGNED (t1));
815404b540aSrobert   else if (TREE_CODE (t2) == ENUMERAL_TYPE && TREE_CODE (t1) != ENUMERAL_TYPE)
816404b540aSrobert     t2 = c_common_type_for_size (TYPE_PRECISION (t2), TYPE_UNSIGNED (t2));
817404b540aSrobert 
818404b540aSrobert   if (t1 == t2)
819404b540aSrobert     return 1;
820404b540aSrobert 
821404b540aSrobert   /* Different classes of types can't be compatible.  */
822404b540aSrobert 
823404b540aSrobert   if (TREE_CODE (t1) != TREE_CODE (t2))
824404b540aSrobert     return 0;
825404b540aSrobert 
826404b540aSrobert   /* Qualifiers must match. C99 6.7.3p9 */
827404b540aSrobert 
828404b540aSrobert   if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
829404b540aSrobert     return 0;
830404b540aSrobert 
831404b540aSrobert   /* Allow for two different type nodes which have essentially the same
832404b540aSrobert      definition.  Note that we already checked for equality of the type
833404b540aSrobert      qualifiers (just above).  */
834404b540aSrobert 
835404b540aSrobert   if (TREE_CODE (t1) != ARRAY_TYPE
836404b540aSrobert       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
837404b540aSrobert     return 1;
838404b540aSrobert 
839404b540aSrobert   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
840404b540aSrobert   if (!(attrval = targetm.comp_type_attributes (t1, t2)))
841404b540aSrobert      return 0;
842404b540aSrobert 
843404b540aSrobert   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
844404b540aSrobert   val = 0;
845404b540aSrobert 
846404b540aSrobert   switch (TREE_CODE (t1))
847404b540aSrobert     {
848404b540aSrobert     case POINTER_TYPE:
849404b540aSrobert       /* Do not remove mode or aliasing information.  */
850404b540aSrobert       if (TYPE_MODE (t1) != TYPE_MODE (t2)
851404b540aSrobert 	  || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
852404b540aSrobert 	break;
853404b540aSrobert       val = (TREE_TYPE (t1) == TREE_TYPE (t2)
854404b540aSrobert 	     ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2)));
855404b540aSrobert       break;
856404b540aSrobert 
857404b540aSrobert     case FUNCTION_TYPE:
858404b540aSrobert       val = function_types_compatible_p (t1, t2);
859404b540aSrobert       break;
860404b540aSrobert 
861404b540aSrobert     case ARRAY_TYPE:
862404b540aSrobert       {
863404b540aSrobert 	tree d1 = TYPE_DOMAIN (t1);
864404b540aSrobert 	tree d2 = TYPE_DOMAIN (t2);
865404b540aSrobert 	bool d1_variable, d2_variable;
866404b540aSrobert 	bool d1_zero, d2_zero;
867404b540aSrobert 	val = 1;
868404b540aSrobert 
869404b540aSrobert 	/* Target types must match incl. qualifiers.  */
870404b540aSrobert 	if (TREE_TYPE (t1) != TREE_TYPE (t2)
871404b540aSrobert 	    && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2))))
872404b540aSrobert 	  return 0;
873404b540aSrobert 
874404b540aSrobert 	/* Sizes must match unless one is missing or variable.  */
875404b540aSrobert 	if (d1 == 0 || d2 == 0 || d1 == d2)
876404b540aSrobert 	  break;
877404b540aSrobert 
878404b540aSrobert 	d1_zero = !TYPE_MAX_VALUE (d1);
879404b540aSrobert 	d2_zero = !TYPE_MAX_VALUE (d2);
880404b540aSrobert 
881404b540aSrobert 	d1_variable = (!d1_zero
882404b540aSrobert 		       && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
883404b540aSrobert 			   || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
884404b540aSrobert 	d2_variable = (!d2_zero
885404b540aSrobert 		       && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
886404b540aSrobert 			   || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
887404b540aSrobert 	d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
888404b540aSrobert 	d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
889404b540aSrobert 
890404b540aSrobert 	if (d1_variable || d2_variable)
891404b540aSrobert 	  break;
892404b540aSrobert 	if (d1_zero && d2_zero)
893404b540aSrobert 	  break;
894404b540aSrobert 	if (d1_zero || d2_zero
895404b540aSrobert 	    || !tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
896404b540aSrobert 	    || !tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
897404b540aSrobert 	  val = 0;
898404b540aSrobert 
899404b540aSrobert 	break;
900404b540aSrobert       }
901404b540aSrobert 
902404b540aSrobert     case ENUMERAL_TYPE:
903404b540aSrobert     case RECORD_TYPE:
904404b540aSrobert     case UNION_TYPE:
905404b540aSrobert       if (val != 1 && !same_translation_unit_p (t1, t2))
906404b540aSrobert 	{
907404b540aSrobert 	  tree a1 = TYPE_ATTRIBUTES (t1);
908404b540aSrobert 	  tree a2 = TYPE_ATTRIBUTES (t2);
909404b540aSrobert 
910404b540aSrobert 	  if (! attribute_list_contained (a1, a2)
911404b540aSrobert 	      && ! attribute_list_contained (a2, a1))
912404b540aSrobert 	    break;
913404b540aSrobert 
914404b540aSrobert 	  if (attrval != 2)
915404b540aSrobert 	    return tagged_types_tu_compatible_p (t1, t2);
916404b540aSrobert 	  val = tagged_types_tu_compatible_p (t1, t2);
917404b540aSrobert 	}
918404b540aSrobert       break;
919404b540aSrobert 
920404b540aSrobert     case VECTOR_TYPE:
921404b540aSrobert       val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
922404b540aSrobert 	    && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2));
923404b540aSrobert       break;
924404b540aSrobert 
925404b540aSrobert     default:
926404b540aSrobert       break;
927404b540aSrobert     }
928404b540aSrobert   return attrval == 2 && val == 1 ? 2 : val;
929404b540aSrobert }
930404b540aSrobert 
931404b540aSrobert /* Return 1 if TTL and TTR are pointers to types that are equivalent,
932404b540aSrobert    ignoring their qualifiers.  */
933404b540aSrobert 
934404b540aSrobert static int
comp_target_types(tree ttl,tree ttr)935404b540aSrobert comp_target_types (tree ttl, tree ttr)
936404b540aSrobert {
937404b540aSrobert   int val;
938404b540aSrobert   tree mvl, mvr;
939404b540aSrobert 
940404b540aSrobert   /* Do not lose qualifiers on element types of array types that are
941404b540aSrobert      pointer targets by taking their TYPE_MAIN_VARIANT.  */
942404b540aSrobert   mvl = TREE_TYPE (ttl);
943404b540aSrobert   mvr = TREE_TYPE (ttr);
944404b540aSrobert   if (TREE_CODE (mvl) != ARRAY_TYPE)
945404b540aSrobert     mvl = TYPE_MAIN_VARIANT (mvl);
946404b540aSrobert   if (TREE_CODE (mvr) != ARRAY_TYPE)
947404b540aSrobert     mvr = TYPE_MAIN_VARIANT (mvr);
948404b540aSrobert   val = comptypes (mvl, mvr);
949404b540aSrobert 
950404b540aSrobert   if (val == 2 && pedantic)
951404b540aSrobert     pedwarn ("types are not quite compatible");
952404b540aSrobert   return val;
953404b540aSrobert }
954404b540aSrobert 
955404b540aSrobert /* Subroutines of `comptypes'.  */
956404b540aSrobert 
957404b540aSrobert /* Determine whether two trees derive from the same translation unit.
958404b540aSrobert    If the CONTEXT chain ends in a null, that tree's context is still
959404b540aSrobert    being parsed, so if two trees have context chains ending in null,
960404b540aSrobert    they're in the same translation unit.  */
961404b540aSrobert int
same_translation_unit_p(tree t1,tree t2)962404b540aSrobert same_translation_unit_p (tree t1, tree t2)
963404b540aSrobert {
964404b540aSrobert   while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
965404b540aSrobert     switch (TREE_CODE_CLASS (TREE_CODE (t1)))
966404b540aSrobert       {
967404b540aSrobert       case tcc_declaration:
968404b540aSrobert 	t1 = DECL_CONTEXT (t1); break;
969404b540aSrobert       case tcc_type:
970404b540aSrobert 	t1 = TYPE_CONTEXT (t1); break;
971404b540aSrobert       case tcc_exceptional:
972404b540aSrobert 	t1 = BLOCK_SUPERCONTEXT (t1); break;  /* assume block */
973404b540aSrobert       default: gcc_unreachable ();
974404b540aSrobert       }
975404b540aSrobert 
976404b540aSrobert   while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
977404b540aSrobert     switch (TREE_CODE_CLASS (TREE_CODE (t2)))
978404b540aSrobert       {
979404b540aSrobert       case tcc_declaration:
980404b540aSrobert 	t2 = DECL_CONTEXT (t2); break;
981404b540aSrobert       case tcc_type:
982404b540aSrobert 	t2 = TYPE_CONTEXT (t2); break;
983404b540aSrobert       case tcc_exceptional:
984404b540aSrobert 	t2 = BLOCK_SUPERCONTEXT (t2); break;  /* assume block */
985404b540aSrobert       default: gcc_unreachable ();
986404b540aSrobert       }
987404b540aSrobert 
988404b540aSrobert   return t1 == t2;
989404b540aSrobert }
990404b540aSrobert 
991404b540aSrobert /* Allocate the seen two types, assuming that they are compatible. */
992404b540aSrobert 
993404b540aSrobert static struct tagged_tu_seen_cache *
alloc_tagged_tu_seen_cache(tree t1,tree t2)994404b540aSrobert alloc_tagged_tu_seen_cache (tree t1, tree t2)
995404b540aSrobert {
996404b540aSrobert   struct tagged_tu_seen_cache *tu = XNEW (struct tagged_tu_seen_cache);
997404b540aSrobert   tu->next = tagged_tu_seen_base;
998404b540aSrobert   tu->t1 = t1;
999404b540aSrobert   tu->t2 = t2;
1000404b540aSrobert 
1001404b540aSrobert   tagged_tu_seen_base = tu;
1002404b540aSrobert 
1003404b540aSrobert   /* The C standard says that two structures in different translation
1004404b540aSrobert      units are compatible with each other only if the types of their
1005404b540aSrobert      fields are compatible (among other things).  We assume that they
1006404b540aSrobert      are compatible until proven otherwise when building the cache.
1007404b540aSrobert      An example where this can occur is:
1008404b540aSrobert      struct a
1009404b540aSrobert      {
1010404b540aSrobert        struct a *next;
1011404b540aSrobert      };
1012404b540aSrobert      If we are comparing this against a similar struct in another TU,
1013404b540aSrobert      and did not assume they were compatible, we end up with an infinite
1014404b540aSrobert      loop.  */
1015404b540aSrobert   tu->val = 1;
1016404b540aSrobert   return tu;
1017404b540aSrobert }
1018404b540aSrobert 
1019404b540aSrobert /* Free the seen types until we get to TU_TIL. */
1020404b540aSrobert 
1021404b540aSrobert static void
free_all_tagged_tu_seen_up_to(const struct tagged_tu_seen_cache * tu_til)1022404b540aSrobert free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *tu_til)
1023404b540aSrobert {
1024404b540aSrobert   const struct tagged_tu_seen_cache *tu = tagged_tu_seen_base;
1025404b540aSrobert   while (tu != tu_til)
1026404b540aSrobert     {
1027404b540aSrobert       struct tagged_tu_seen_cache *tu1 = (struct tagged_tu_seen_cache*)tu;
1028404b540aSrobert       tu = tu1->next;
1029404b540aSrobert       free (tu1);
1030404b540aSrobert     }
1031404b540aSrobert   tagged_tu_seen_base = tu_til;
1032404b540aSrobert }
1033404b540aSrobert 
1034404b540aSrobert /* Return 1 if two 'struct', 'union', or 'enum' types T1 and T2 are
1035404b540aSrobert    compatible.  If the two types are not the same (which has been
1036404b540aSrobert    checked earlier), this can only happen when multiple translation
1037404b540aSrobert    units are being compiled.  See C99 6.2.7 paragraph 1 for the exact
1038404b540aSrobert    rules.  */
1039404b540aSrobert 
1040404b540aSrobert static int
tagged_types_tu_compatible_p(tree t1,tree t2)1041404b540aSrobert tagged_types_tu_compatible_p (tree t1, tree t2)
1042404b540aSrobert {
1043404b540aSrobert   tree s1, s2;
1044404b540aSrobert   bool needs_warning = false;
1045404b540aSrobert 
1046404b540aSrobert   /* We have to verify that the tags of the types are the same.  This
1047404b540aSrobert      is harder than it looks because this may be a typedef, so we have
1048404b540aSrobert      to go look at the original type.  It may even be a typedef of a
1049404b540aSrobert      typedef...
1050404b540aSrobert      In the case of compiler-created builtin structs the TYPE_DECL
1051404b540aSrobert      may be a dummy, with no DECL_ORIGINAL_TYPE.  Don't fault.  */
1052404b540aSrobert   while (TYPE_NAME (t1)
1053404b540aSrobert 	 && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
1054404b540aSrobert 	 && DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
1055404b540aSrobert     t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
1056404b540aSrobert 
1057404b540aSrobert   while (TYPE_NAME (t2)
1058404b540aSrobert 	 && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
1059404b540aSrobert 	 && DECL_ORIGINAL_TYPE (TYPE_NAME (t2)))
1060404b540aSrobert     t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
1061404b540aSrobert 
1062404b540aSrobert   /* C90 didn't have the requirement that the two tags be the same.  */
1063404b540aSrobert   if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
1064404b540aSrobert     return 0;
1065404b540aSrobert 
1066404b540aSrobert   /* C90 didn't say what happened if one or both of the types were
1067404b540aSrobert      incomplete; we choose to follow C99 rules here, which is that they
1068404b540aSrobert      are compatible.  */
1069404b540aSrobert   if (TYPE_SIZE (t1) == NULL
1070404b540aSrobert       || TYPE_SIZE (t2) == NULL)
1071404b540aSrobert     return 1;
1072404b540aSrobert 
1073404b540aSrobert   {
1074404b540aSrobert     const struct tagged_tu_seen_cache * tts_i;
1075404b540aSrobert     for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
1076404b540aSrobert       if (tts_i->t1 == t1 && tts_i->t2 == t2)
1077404b540aSrobert 	return tts_i->val;
1078404b540aSrobert   }
1079404b540aSrobert 
1080404b540aSrobert   switch (TREE_CODE (t1))
1081404b540aSrobert     {
1082404b540aSrobert     case ENUMERAL_TYPE:
1083404b540aSrobert       {
1084404b540aSrobert 	struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1085404b540aSrobert 	/* Speed up the case where the type values are in the same order.  */
1086404b540aSrobert 	tree tv1 = TYPE_VALUES (t1);
1087404b540aSrobert 	tree tv2 = TYPE_VALUES (t2);
1088404b540aSrobert 
1089404b540aSrobert 	if (tv1 == tv2)
1090404b540aSrobert 	  {
1091404b540aSrobert 	    return 1;
1092404b540aSrobert 	  }
1093404b540aSrobert 
1094404b540aSrobert 	for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
1095404b540aSrobert 	  {
1096404b540aSrobert 	    if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
1097404b540aSrobert 	      break;
1098404b540aSrobert 	    if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
1099404b540aSrobert 	      {
1100404b540aSrobert 		tu->val = 0;
1101404b540aSrobert 		return 0;
1102404b540aSrobert 	      }
1103404b540aSrobert 	  }
1104404b540aSrobert 
1105404b540aSrobert 	if (tv1 == NULL_TREE && tv2 == NULL_TREE)
1106404b540aSrobert 	  {
1107404b540aSrobert 	    return 1;
1108404b540aSrobert 	  }
1109404b540aSrobert 	if (tv1 == NULL_TREE || tv2 == NULL_TREE)
1110404b540aSrobert 	  {
1111404b540aSrobert 	    tu->val = 0;
1112404b540aSrobert 	    return 0;
1113404b540aSrobert 	  }
1114404b540aSrobert 
1115404b540aSrobert 	if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
1116404b540aSrobert 	  {
1117404b540aSrobert 	    tu->val = 0;
1118404b540aSrobert 	    return 0;
1119404b540aSrobert 	  }
1120404b540aSrobert 
1121404b540aSrobert 	for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
1122404b540aSrobert 	  {
1123404b540aSrobert 	    s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
1124404b540aSrobert 	    if (s2 == NULL
1125404b540aSrobert 		|| simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1)
1126404b540aSrobert 	      {
1127404b540aSrobert 		tu->val = 0;
1128404b540aSrobert 		return 0;
1129404b540aSrobert 	      }
1130404b540aSrobert 	  }
1131404b540aSrobert 	return 1;
1132404b540aSrobert       }
1133404b540aSrobert 
1134404b540aSrobert     case UNION_TYPE:
1135404b540aSrobert       {
1136404b540aSrobert 	struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1137404b540aSrobert 	if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2)))
1138404b540aSrobert 	  {
1139404b540aSrobert 	    tu->val = 0;
1140404b540aSrobert 	    return 0;
1141404b540aSrobert 	  }
1142404b540aSrobert 
1143404b540aSrobert 	/*  Speed up the common case where the fields are in the same order. */
1144404b540aSrobert 	for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); s1 && s2;
1145404b540aSrobert 	     s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
1146404b540aSrobert 	  {
1147404b540aSrobert 	    int result;
1148404b540aSrobert 
1149404b540aSrobert 
1150404b540aSrobert 	    if (DECL_NAME (s1) == NULL
1151404b540aSrobert 		|| DECL_NAME (s1) != DECL_NAME (s2))
1152404b540aSrobert 	      break;
1153404b540aSrobert 	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
1154404b540aSrobert 	    if (result == 0)
1155404b540aSrobert 	      {
1156404b540aSrobert 		tu->val = 0;
1157404b540aSrobert 		return 0;
1158404b540aSrobert 	      }
1159404b540aSrobert 	    if (result == 2)
1160404b540aSrobert 	      needs_warning = true;
1161404b540aSrobert 
1162404b540aSrobert 	    if (TREE_CODE (s1) == FIELD_DECL
1163404b540aSrobert 		&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1164404b540aSrobert 				     DECL_FIELD_BIT_OFFSET (s2)) != 1)
1165404b540aSrobert 	      {
1166404b540aSrobert 		tu->val = 0;
1167404b540aSrobert 		return 0;
1168404b540aSrobert 	      }
1169404b540aSrobert 	  }
1170404b540aSrobert 	if (!s1 && !s2)
1171404b540aSrobert 	  {
1172404b540aSrobert 	    tu->val = needs_warning ? 2 : 1;
1173404b540aSrobert 	    return tu->val;
1174404b540aSrobert 	  }
1175404b540aSrobert 
1176404b540aSrobert 	for (s1 = TYPE_FIELDS (t1); s1; s1 = TREE_CHAIN (s1))
1177404b540aSrobert 	  {
1178404b540aSrobert 	    bool ok = false;
1179404b540aSrobert 
1180404b540aSrobert 	    if (DECL_NAME (s1) != NULL)
1181404b540aSrobert 	      for (s2 = TYPE_FIELDS (t2); s2; s2 = TREE_CHAIN (s2))
1182404b540aSrobert 		if (DECL_NAME (s1) == DECL_NAME (s2))
1183404b540aSrobert 		  {
1184404b540aSrobert 		    int result;
1185404b540aSrobert 		    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
1186404b540aSrobert 		    if (result == 0)
1187404b540aSrobert 		      {
1188404b540aSrobert 			tu->val = 0;
1189404b540aSrobert 			return 0;
1190404b540aSrobert 		      }
1191404b540aSrobert 		    if (result == 2)
1192404b540aSrobert 		      needs_warning = true;
1193404b540aSrobert 
1194404b540aSrobert 		    if (TREE_CODE (s1) == FIELD_DECL
1195404b540aSrobert 			&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1196404b540aSrobert 					     DECL_FIELD_BIT_OFFSET (s2)) != 1)
1197404b540aSrobert 		      break;
1198404b540aSrobert 
1199404b540aSrobert 		    ok = true;
1200404b540aSrobert 		    break;
1201404b540aSrobert 		  }
1202404b540aSrobert 	    if (!ok)
1203404b540aSrobert 	      {
1204404b540aSrobert 		tu->val = 0;
1205404b540aSrobert 		return 0;
1206404b540aSrobert 	      }
1207404b540aSrobert 	  }
1208404b540aSrobert 	tu->val = needs_warning ? 2 : 10;
1209404b540aSrobert 	return tu->val;
1210404b540aSrobert       }
1211404b540aSrobert 
1212404b540aSrobert     case RECORD_TYPE:
1213404b540aSrobert       {
1214404b540aSrobert 	struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
1215404b540aSrobert 
1216404b540aSrobert 	for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
1217404b540aSrobert 	     s1 && s2;
1218404b540aSrobert 	     s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
1219404b540aSrobert 	  {
1220404b540aSrobert 	    int result;
1221404b540aSrobert 	    if (TREE_CODE (s1) != TREE_CODE (s2)
1222404b540aSrobert 		|| DECL_NAME (s1) != DECL_NAME (s2))
1223404b540aSrobert 	      break;
1224404b540aSrobert 	    result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
1225404b540aSrobert 	    if (result == 0)
1226404b540aSrobert 	      break;
1227404b540aSrobert 	    if (result == 2)
1228404b540aSrobert 	      needs_warning = true;
1229404b540aSrobert 
1230404b540aSrobert 	    if (TREE_CODE (s1) == FIELD_DECL
1231404b540aSrobert 		&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
1232404b540aSrobert 				     DECL_FIELD_BIT_OFFSET (s2)) != 1)
1233404b540aSrobert 	      break;
1234404b540aSrobert 	  }
1235404b540aSrobert 	if (s1 && s2)
1236404b540aSrobert 	  tu->val = 0;
1237404b540aSrobert 	else
1238404b540aSrobert 	  tu->val = needs_warning ? 2 : 1;
1239404b540aSrobert 	return tu->val;
1240404b540aSrobert       }
1241404b540aSrobert 
1242404b540aSrobert     default:
1243404b540aSrobert       gcc_unreachable ();
1244404b540aSrobert     }
1245404b540aSrobert }
1246404b540aSrobert 
1247404b540aSrobert /* Return 1 if two function types F1 and F2 are compatible.
1248404b540aSrobert    If either type specifies no argument types,
1249404b540aSrobert    the other must specify a fixed number of self-promoting arg types.
1250404b540aSrobert    Otherwise, if one type specifies only the number of arguments,
1251404b540aSrobert    the other must specify that number of self-promoting arg types.
1252404b540aSrobert    Otherwise, the argument types must match.  */
1253404b540aSrobert 
1254404b540aSrobert static int
function_types_compatible_p(tree f1,tree f2)1255404b540aSrobert function_types_compatible_p (tree f1, tree f2)
1256404b540aSrobert {
1257404b540aSrobert   tree args1, args2;
1258404b540aSrobert   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
1259404b540aSrobert   int val = 1;
1260404b540aSrobert   int val1;
1261404b540aSrobert   tree ret1, ret2;
1262404b540aSrobert 
1263404b540aSrobert   ret1 = TREE_TYPE (f1);
1264404b540aSrobert   ret2 = TREE_TYPE (f2);
1265404b540aSrobert 
1266404b540aSrobert   /* 'volatile' qualifiers on a function's return type used to mean
1267404b540aSrobert      the function is noreturn.  */
1268404b540aSrobert   if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
1269404b540aSrobert     pedwarn ("function return types not compatible due to %<volatile%>");
1270404b540aSrobert   if (TYPE_VOLATILE (ret1))
1271404b540aSrobert     ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
1272404b540aSrobert 				 TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
1273404b540aSrobert   if (TYPE_VOLATILE (ret2))
1274404b540aSrobert     ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
1275404b540aSrobert 				 TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
1276404b540aSrobert   val = comptypes_internal (ret1, ret2);
1277404b540aSrobert   if (val == 0)
1278404b540aSrobert     return 0;
1279404b540aSrobert 
1280404b540aSrobert   args1 = TYPE_ARG_TYPES (f1);
1281404b540aSrobert   args2 = TYPE_ARG_TYPES (f2);
1282404b540aSrobert 
1283404b540aSrobert   /* An unspecified parmlist matches any specified parmlist
1284404b540aSrobert      whose argument types don't need default promotions.  */
1285404b540aSrobert 
1286404b540aSrobert   if (args1 == 0)
1287404b540aSrobert     {
1288404b540aSrobert       if (!self_promoting_args_p (args2))
1289404b540aSrobert 	return 0;
1290404b540aSrobert       /* If one of these types comes from a non-prototype fn definition,
1291404b540aSrobert 	 compare that with the other type's arglist.
1292404b540aSrobert 	 If they don't match, ask for a warning (but no error).  */
1293404b540aSrobert       if (TYPE_ACTUAL_ARG_TYPES (f1)
1294404b540aSrobert 	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
1295404b540aSrobert 	val = 2;
1296404b540aSrobert       return val;
1297404b540aSrobert     }
1298404b540aSrobert   if (args2 == 0)
1299404b540aSrobert     {
1300404b540aSrobert       if (!self_promoting_args_p (args1))
1301404b540aSrobert 	return 0;
1302404b540aSrobert       if (TYPE_ACTUAL_ARG_TYPES (f2)
1303404b540aSrobert 	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
1304404b540aSrobert 	val = 2;
1305404b540aSrobert       return val;
1306404b540aSrobert     }
1307404b540aSrobert 
1308404b540aSrobert   /* Both types have argument lists: compare them and propagate results.  */
1309404b540aSrobert   val1 = type_lists_compatible_p (args1, args2);
1310404b540aSrobert   return val1 != 1 ? val1 : val;
1311404b540aSrobert }
1312404b540aSrobert 
1313404b540aSrobert /* Check two lists of types for compatibility,
1314404b540aSrobert    returning 0 for incompatible, 1 for compatible,
1315404b540aSrobert    or 2 for compatible with warning.  */
1316404b540aSrobert 
1317404b540aSrobert static int
type_lists_compatible_p(tree args1,tree args2)1318404b540aSrobert type_lists_compatible_p (tree args1, tree args2)
1319404b540aSrobert {
1320404b540aSrobert   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
1321404b540aSrobert   int val = 1;
1322404b540aSrobert   int newval = 0;
1323404b540aSrobert 
1324404b540aSrobert   while (1)
1325404b540aSrobert     {
1326404b540aSrobert       tree a1, mv1, a2, mv2;
1327404b540aSrobert       if (args1 == 0 && args2 == 0)
1328404b540aSrobert 	return val;
1329404b540aSrobert       /* If one list is shorter than the other,
1330404b540aSrobert 	 they fail to match.  */
1331404b540aSrobert       if (args1 == 0 || args2 == 0)
1332404b540aSrobert 	return 0;
1333404b540aSrobert       mv1 = a1 = TREE_VALUE (args1);
1334404b540aSrobert       mv2 = a2 = TREE_VALUE (args2);
1335404b540aSrobert       if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE)
1336404b540aSrobert 	mv1 = TYPE_MAIN_VARIANT (mv1);
1337404b540aSrobert       if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE)
1338404b540aSrobert 	mv2 = TYPE_MAIN_VARIANT (mv2);
1339404b540aSrobert       /* A null pointer instead of a type
1340404b540aSrobert 	 means there is supposed to be an argument
1341404b540aSrobert 	 but nothing is specified about what type it has.
1342404b540aSrobert 	 So match anything that self-promotes.  */
1343404b540aSrobert       if (a1 == 0)
1344404b540aSrobert 	{
1345404b540aSrobert 	  if (c_type_promotes_to (a2) != a2)
1346404b540aSrobert 	    return 0;
1347404b540aSrobert 	}
1348404b540aSrobert       else if (a2 == 0)
1349404b540aSrobert 	{
1350404b540aSrobert 	  if (c_type_promotes_to (a1) != a1)
1351404b540aSrobert 	    return 0;
1352404b540aSrobert 	}
1353404b540aSrobert       /* If one of the lists has an error marker, ignore this arg.  */
1354404b540aSrobert       else if (TREE_CODE (a1) == ERROR_MARK
1355404b540aSrobert 	       || TREE_CODE (a2) == ERROR_MARK)
1356404b540aSrobert 	;
1357404b540aSrobert       else if (!(newval = comptypes_internal (mv1, mv2)))
1358404b540aSrobert 	{
1359404b540aSrobert 	  /* Allow  wait (union {union wait *u; int *i} *)
1360404b540aSrobert 	     and  wait (union wait *)  to be compatible.  */
1361404b540aSrobert 	  if (TREE_CODE (a1) == UNION_TYPE
1362404b540aSrobert 	      && (TYPE_NAME (a1) == 0
1363404b540aSrobert 		  || TYPE_TRANSPARENT_UNION (a1))
1364404b540aSrobert 	      && TREE_CODE (TYPE_SIZE (a1)) == INTEGER_CST
1365404b540aSrobert 	      && tree_int_cst_equal (TYPE_SIZE (a1),
1366404b540aSrobert 				     TYPE_SIZE (a2)))
1367404b540aSrobert 	    {
1368404b540aSrobert 	      tree memb;
1369404b540aSrobert 	      for (memb = TYPE_FIELDS (a1);
1370404b540aSrobert 		   memb; memb = TREE_CHAIN (memb))
1371404b540aSrobert 		{
1372404b540aSrobert 		  tree mv3 = TREE_TYPE (memb);
1373404b540aSrobert 		  if (mv3 && mv3 != error_mark_node
1374404b540aSrobert 		      && TREE_CODE (mv3) != ARRAY_TYPE)
1375404b540aSrobert 		    mv3 = TYPE_MAIN_VARIANT (mv3);
1376404b540aSrobert 		  if (comptypes_internal (mv3, mv2))
1377404b540aSrobert 		    break;
1378404b540aSrobert 		}
1379404b540aSrobert 	      if (memb == 0)
1380404b540aSrobert 		return 0;
1381404b540aSrobert 	    }
1382404b540aSrobert 	  else if (TREE_CODE (a2) == UNION_TYPE
1383404b540aSrobert 		   && (TYPE_NAME (a2) == 0
1384404b540aSrobert 		       || TYPE_TRANSPARENT_UNION (a2))
1385404b540aSrobert 		   && TREE_CODE (TYPE_SIZE (a2)) == INTEGER_CST
1386404b540aSrobert 		   && tree_int_cst_equal (TYPE_SIZE (a2),
1387404b540aSrobert 					  TYPE_SIZE (a1)))
1388404b540aSrobert 	    {
1389404b540aSrobert 	      tree memb;
1390404b540aSrobert 	      for (memb = TYPE_FIELDS (a2);
1391404b540aSrobert 		   memb; memb = TREE_CHAIN (memb))
1392404b540aSrobert 		{
1393404b540aSrobert 		  tree mv3 = TREE_TYPE (memb);
1394404b540aSrobert 		  if (mv3 && mv3 != error_mark_node
1395404b540aSrobert 		      && TREE_CODE (mv3) != ARRAY_TYPE)
1396404b540aSrobert 		    mv3 = TYPE_MAIN_VARIANT (mv3);
1397404b540aSrobert 		  if (comptypes_internal (mv3, mv1))
1398404b540aSrobert 		    break;
1399404b540aSrobert 		}
1400404b540aSrobert 	      if (memb == 0)
1401404b540aSrobert 		return 0;
1402404b540aSrobert 	    }
1403404b540aSrobert 	  else
1404404b540aSrobert 	    return 0;
1405404b540aSrobert 	}
1406404b540aSrobert 
1407404b540aSrobert       /* comptypes said ok, but record if it said to warn.  */
1408404b540aSrobert       if (newval > val)
1409404b540aSrobert 	val = newval;
1410404b540aSrobert 
1411404b540aSrobert       args1 = TREE_CHAIN (args1);
1412404b540aSrobert       args2 = TREE_CHAIN (args2);
1413404b540aSrobert     }
1414404b540aSrobert }
1415404b540aSrobert 
1416404b540aSrobert /* Compute the size to increment a pointer by.  */
1417404b540aSrobert 
1418404b540aSrobert static tree
c_size_in_bytes(tree type)1419404b540aSrobert c_size_in_bytes (tree type)
1420404b540aSrobert {
1421404b540aSrobert   enum tree_code code = TREE_CODE (type);
1422404b540aSrobert 
1423404b540aSrobert   if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
1424404b540aSrobert     return size_one_node;
1425404b540aSrobert 
1426404b540aSrobert   if (!COMPLETE_OR_VOID_TYPE_P (type))
1427404b540aSrobert     {
1428404b540aSrobert       error ("arithmetic on pointer to an incomplete type");
1429404b540aSrobert       return size_one_node;
1430404b540aSrobert     }
1431404b540aSrobert 
1432404b540aSrobert   /* Convert in case a char is more than one unit.  */
1433404b540aSrobert   return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
1434404b540aSrobert 		     size_int (TYPE_PRECISION (char_type_node)
1435404b540aSrobert 			       / BITS_PER_UNIT));
1436404b540aSrobert }
1437404b540aSrobert 
1438404b540aSrobert /* Return either DECL or its known constant value (if it has one).  */
1439404b540aSrobert 
1440404b540aSrobert tree
decl_constant_value(tree decl)1441404b540aSrobert decl_constant_value (tree decl)
1442404b540aSrobert {
1443404b540aSrobert   if (/* Don't change a variable array bound or initial value to a constant
1444404b540aSrobert 	 in a place where a variable is invalid.  Note that DECL_INITIAL
1445404b540aSrobert 	 isn't valid for a PARM_DECL.  */
1446404b540aSrobert       current_function_decl != 0
1447404b540aSrobert       && TREE_CODE (decl) != PARM_DECL
1448404b540aSrobert       && !TREE_THIS_VOLATILE (decl)
1449404b540aSrobert       && TREE_READONLY (decl)
1450404b540aSrobert       && DECL_INITIAL (decl) != 0
1451404b540aSrobert       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
1452404b540aSrobert       /* This is invalid if initial value is not constant.
1453404b540aSrobert 	 If it has either a function call, a memory reference,
1454404b540aSrobert 	 or a variable, then re-evaluating it could give different results.  */
1455404b540aSrobert       && TREE_CONSTANT (DECL_INITIAL (decl))
1456404b540aSrobert       /* Check for cases where this is sub-optimal, even though valid.  */
1457404b540aSrobert       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
1458404b540aSrobert     return DECL_INITIAL (decl);
1459404b540aSrobert   return decl;
1460404b540aSrobert }
1461404b540aSrobert 
1462404b540aSrobert /* Return either DECL or its known constant value (if it has one), but
1463404b540aSrobert    return DECL if pedantic or DECL has mode BLKmode.  This is for
1464404b540aSrobert    bug-compatibility with the old behavior of decl_constant_value
1465404b540aSrobert    (before GCC 3.0); every use of this function is a bug and it should
1466404b540aSrobert    be removed before GCC 3.1.  It is not appropriate to use pedantic
1467404b540aSrobert    in a way that affects optimization, and BLKmode is probably not the
1468404b540aSrobert    right test for avoiding misoptimizations either.  */
1469404b540aSrobert 
1470404b540aSrobert static tree
decl_constant_value_for_broken_optimization(tree decl)1471404b540aSrobert decl_constant_value_for_broken_optimization (tree decl)
1472404b540aSrobert {
1473404b540aSrobert   tree ret;
1474404b540aSrobert 
1475404b540aSrobert   if (pedantic || DECL_MODE (decl) == BLKmode)
1476404b540aSrobert     return decl;
1477404b540aSrobert 
1478404b540aSrobert   ret = decl_constant_value (decl);
1479404b540aSrobert   /* Avoid unwanted tree sharing between the initializer and current
1480404b540aSrobert      function's body where the tree can be modified e.g. by the
1481404b540aSrobert      gimplifier.  */
1482404b540aSrobert   if (ret != decl && TREE_STATIC (decl))
1483404b540aSrobert     ret = unshare_expr (ret);
1484404b540aSrobert   return ret;
1485404b540aSrobert }
1486404b540aSrobert 
1487404b540aSrobert /* Convert the array expression EXP to a pointer.  */
1488404b540aSrobert static tree
array_to_pointer_conversion(tree exp)1489404b540aSrobert array_to_pointer_conversion (tree exp)
1490404b540aSrobert {
1491404b540aSrobert   tree orig_exp = exp;
1492404b540aSrobert   tree type = TREE_TYPE (exp);
1493404b540aSrobert   tree adr;
1494404b540aSrobert   tree restype = TREE_TYPE (type);
1495404b540aSrobert   tree ptrtype;
1496404b540aSrobert 
1497404b540aSrobert   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1498404b540aSrobert 
1499404b540aSrobert   STRIP_TYPE_NOPS (exp);
1500404b540aSrobert 
1501404b540aSrobert   if (TREE_NO_WARNING (orig_exp))
1502404b540aSrobert     TREE_NO_WARNING (exp) = 1;
1503404b540aSrobert 
1504404b540aSrobert   ptrtype = build_pointer_type (restype);
1505404b540aSrobert 
1506404b540aSrobert   if (TREE_CODE (exp) == INDIRECT_REF)
1507404b540aSrobert     return convert (ptrtype, TREE_OPERAND (exp, 0));
1508404b540aSrobert 
1509404b540aSrobert   if (TREE_CODE (exp) == VAR_DECL)
1510404b540aSrobert     {
1511404b540aSrobert       /* We are making an ADDR_EXPR of ptrtype.  This is a valid
1512404b540aSrobert 	 ADDR_EXPR because it's the best way of representing what
1513404b540aSrobert 	 happens in C when we take the address of an array and place
1514404b540aSrobert 	 it in a pointer to the element type.  */
1515404b540aSrobert       adr = build1 (ADDR_EXPR, ptrtype, exp);
1516404b540aSrobert       if (!c_mark_addressable (exp))
1517404b540aSrobert 	return error_mark_node;
1518404b540aSrobert       TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
1519404b540aSrobert       return adr;
1520404b540aSrobert     }
1521404b540aSrobert 
1522404b540aSrobert   /* This way is better for a COMPONENT_REF since it can
1523404b540aSrobert      simplify the offset for a component.  */
1524404b540aSrobert   adr = build_unary_op (ADDR_EXPR, exp, 1);
1525404b540aSrobert   return convert (ptrtype, adr);
1526404b540aSrobert }
1527404b540aSrobert 
1528404b540aSrobert /* Convert the function expression EXP to a pointer.  */
1529404b540aSrobert static tree
function_to_pointer_conversion(tree exp)1530404b540aSrobert function_to_pointer_conversion (tree exp)
1531404b540aSrobert {
1532404b540aSrobert   tree orig_exp = exp;
1533404b540aSrobert 
1534404b540aSrobert   gcc_assert (TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE);
1535404b540aSrobert 
1536404b540aSrobert   STRIP_TYPE_NOPS (exp);
1537404b540aSrobert 
1538404b540aSrobert   if (TREE_NO_WARNING (orig_exp))
1539404b540aSrobert     TREE_NO_WARNING (exp) = 1;
1540404b540aSrobert 
1541404b540aSrobert   return build_unary_op (ADDR_EXPR, exp, 0);
1542404b540aSrobert }
1543404b540aSrobert 
1544404b540aSrobert /* Perform the default conversion of arrays and functions to pointers.
1545404b540aSrobert    Return the result of converting EXP.  For any other expression, just
1546404b540aSrobert    return EXP after removing NOPs.  */
1547404b540aSrobert 
1548404b540aSrobert struct c_expr
default_function_array_conversion(struct c_expr exp)1549404b540aSrobert default_function_array_conversion (struct c_expr exp)
1550404b540aSrobert {
1551404b540aSrobert   tree orig_exp = exp.value;
1552404b540aSrobert   tree type = TREE_TYPE (exp.value);
1553404b540aSrobert   enum tree_code code = TREE_CODE (type);
1554404b540aSrobert 
1555404b540aSrobert   switch (code)
1556404b540aSrobert     {
1557404b540aSrobert     case ARRAY_TYPE:
1558404b540aSrobert       {
1559404b540aSrobert 	bool not_lvalue = false;
1560404b540aSrobert 	bool lvalue_array_p;
1561404b540aSrobert 
1562404b540aSrobert 	while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR
1563404b540aSrobert 		|| TREE_CODE (exp.value) == NOP_EXPR
1564404b540aSrobert 		|| TREE_CODE (exp.value) == CONVERT_EXPR)
1565404b540aSrobert 	       && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type)
1566404b540aSrobert 	  {
1567404b540aSrobert 	    if (TREE_CODE (exp.value) == NON_LVALUE_EXPR)
1568404b540aSrobert 	      not_lvalue = true;
1569404b540aSrobert 	    exp.value = TREE_OPERAND (exp.value, 0);
1570404b540aSrobert 	  }
1571404b540aSrobert 
1572404b540aSrobert 	if (TREE_NO_WARNING (orig_exp))
1573404b540aSrobert 	  TREE_NO_WARNING (exp.value) = 1;
1574404b540aSrobert 
1575404b540aSrobert 	lvalue_array_p = !not_lvalue && lvalue_p (exp.value);
1576404b540aSrobert 	if (!flag_isoc99 && !lvalue_array_p)
1577404b540aSrobert 	  {
1578404b540aSrobert 	    /* Before C99, non-lvalue arrays do not decay to pointers.
1579404b540aSrobert 	       Normally, using such an array would be invalid; but it can
1580404b540aSrobert 	       be used correctly inside sizeof or as a statement expression.
1581404b540aSrobert 	       Thus, do not give an error here; an error will result later.  */
1582404b540aSrobert 	    return exp;
1583404b540aSrobert 	  }
1584404b540aSrobert 
1585404b540aSrobert 	exp.value = array_to_pointer_conversion (exp.value);
1586404b540aSrobert       }
1587404b540aSrobert       break;
1588404b540aSrobert     case FUNCTION_TYPE:
1589404b540aSrobert       exp.value = function_to_pointer_conversion (exp.value);
1590404b540aSrobert       break;
1591404b540aSrobert     default:
1592404b540aSrobert       STRIP_TYPE_NOPS (exp.value);
1593404b540aSrobert       if (TREE_NO_WARNING (orig_exp))
1594404b540aSrobert 	TREE_NO_WARNING (exp.value) = 1;
1595404b540aSrobert       break;
1596404b540aSrobert     }
1597404b540aSrobert 
1598404b540aSrobert   return exp;
1599404b540aSrobert }
1600404b540aSrobert 
1601404b540aSrobert 
1602404b540aSrobert /* EXP is an expression of integer type.  Apply the integer promotions
1603404b540aSrobert    to it and return the promoted value.  */
1604404b540aSrobert 
1605404b540aSrobert tree
perform_integral_promotions(tree exp)1606404b540aSrobert perform_integral_promotions (tree exp)
1607404b540aSrobert {
1608404b540aSrobert   tree type = TREE_TYPE (exp);
1609404b540aSrobert   enum tree_code code = TREE_CODE (type);
1610404b540aSrobert 
1611404b540aSrobert   gcc_assert (INTEGRAL_TYPE_P (type));
1612404b540aSrobert 
1613404b540aSrobert   /* Normally convert enums to int,
1614404b540aSrobert      but convert wide enums to something wider.  */
1615404b540aSrobert   if (code == ENUMERAL_TYPE)
1616404b540aSrobert     {
1617404b540aSrobert       type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
1618404b540aSrobert 					  TYPE_PRECISION (integer_type_node)),
1619404b540aSrobert 				     ((TYPE_PRECISION (type)
1620404b540aSrobert 				       >= TYPE_PRECISION (integer_type_node))
1621404b540aSrobert 				      && TYPE_UNSIGNED (type)));
1622404b540aSrobert 
1623404b540aSrobert       return convert (type, exp);
1624404b540aSrobert     }
1625404b540aSrobert 
1626404b540aSrobert   /* ??? This should no longer be needed now bit-fields have their
1627404b540aSrobert      proper types.  */
1628404b540aSrobert   if (TREE_CODE (exp) == COMPONENT_REF
1629404b540aSrobert       && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
1630404b540aSrobert       /* If it's thinner than an int, promote it like a
1631404b540aSrobert 	 c_promoting_integer_type_p, otherwise leave it alone.  */
1632404b540aSrobert       && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
1633404b540aSrobert 			       TYPE_PRECISION (integer_type_node)))
1634404b540aSrobert     return convert (integer_type_node, exp);
1635404b540aSrobert 
1636404b540aSrobert   if (c_promoting_integer_type_p (type))
1637404b540aSrobert     {
1638404b540aSrobert       /* Preserve unsignedness if not really getting any wider.  */
1639404b540aSrobert       if (TYPE_UNSIGNED (type)
1640404b540aSrobert 	  && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
1641404b540aSrobert 	return convert (unsigned_type_node, exp);
1642404b540aSrobert 
1643404b540aSrobert       return convert (integer_type_node, exp);
1644404b540aSrobert     }
1645404b540aSrobert 
1646404b540aSrobert   return exp;
1647404b540aSrobert }
1648404b540aSrobert 
1649404b540aSrobert 
1650404b540aSrobert /* Perform default promotions for C data used in expressions.
1651404b540aSrobert    Enumeral types or short or char are converted to int.
1652404b540aSrobert    In addition, manifest constants symbols are replaced by their values.  */
1653404b540aSrobert 
1654404b540aSrobert tree
default_conversion(tree exp)1655404b540aSrobert default_conversion (tree exp)
1656404b540aSrobert {
1657404b540aSrobert   tree orig_exp;
1658404b540aSrobert   tree type = TREE_TYPE (exp);
1659404b540aSrobert   enum tree_code code = TREE_CODE (type);
1660404b540aSrobert 
1661404b540aSrobert   /* Functions and arrays have been converted during parsing.  */
1662404b540aSrobert   gcc_assert (code != FUNCTION_TYPE);
1663404b540aSrobert   if (code == ARRAY_TYPE)
1664404b540aSrobert     return exp;
1665404b540aSrobert 
1666404b540aSrobert   /* Constants can be used directly unless they're not loadable.  */
1667404b540aSrobert   if (TREE_CODE (exp) == CONST_DECL)
1668404b540aSrobert     exp = DECL_INITIAL (exp);
1669404b540aSrobert 
1670404b540aSrobert   /* Replace a nonvolatile const static variable with its value unless
1671404b540aSrobert      it is an array, in which case we must be sure that taking the
1672404b540aSrobert      address of the array produces consistent results.  */
1673404b540aSrobert   else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
1674404b540aSrobert     {
1675404b540aSrobert       exp = decl_constant_value_for_broken_optimization (exp);
1676404b540aSrobert       type = TREE_TYPE (exp);
1677404b540aSrobert     }
1678404b540aSrobert 
1679404b540aSrobert   /* Strip no-op conversions.  */
1680404b540aSrobert   orig_exp = exp;
1681404b540aSrobert   STRIP_TYPE_NOPS (exp);
1682404b540aSrobert 
1683404b540aSrobert   if (TREE_NO_WARNING (orig_exp))
1684404b540aSrobert     TREE_NO_WARNING (exp) = 1;
1685404b540aSrobert 
1686404b540aSrobert   if (INTEGRAL_TYPE_P (type))
1687404b540aSrobert     return perform_integral_promotions (exp);
1688404b540aSrobert 
1689404b540aSrobert   if (code == VOID_TYPE)
1690404b540aSrobert     {
1691404b540aSrobert       error ("void value not ignored as it ought to be");
1692404b540aSrobert       return error_mark_node;
1693404b540aSrobert     }
1694404b540aSrobert   return exp;
1695404b540aSrobert }
1696404b540aSrobert 
1697404b540aSrobert /* Look up COMPONENT in a structure or union DECL.
1698404b540aSrobert 
1699404b540aSrobert    If the component name is not found, returns NULL_TREE.  Otherwise,
1700404b540aSrobert    the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL
1701404b540aSrobert    stepping down the chain to the component, which is in the last
1702404b540aSrobert    TREE_VALUE of the list.  Normally the list is of length one, but if
1703404b540aSrobert    the component is embedded within (nested) anonymous structures or
1704404b540aSrobert    unions, the list steps down the chain to the component.  */
1705404b540aSrobert 
1706404b540aSrobert static tree
lookup_field(tree decl,tree component)1707404b540aSrobert lookup_field (tree decl, tree component)
1708404b540aSrobert {
1709404b540aSrobert   tree type = TREE_TYPE (decl);
1710404b540aSrobert   tree field;
1711404b540aSrobert 
1712404b540aSrobert   /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
1713404b540aSrobert      to the field elements.  Use a binary search on this array to quickly
1714404b540aSrobert      find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC
1715404b540aSrobert      will always be set for structures which have many elements.  */
1716404b540aSrobert 
1717404b540aSrobert   if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s)
1718404b540aSrobert     {
1719404b540aSrobert       int bot, top, half;
1720404b540aSrobert       tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0];
1721404b540aSrobert 
1722404b540aSrobert       field = TYPE_FIELDS (type);
1723404b540aSrobert       bot = 0;
1724404b540aSrobert       top = TYPE_LANG_SPECIFIC (type)->s->len;
1725404b540aSrobert       while (top - bot > 1)
1726404b540aSrobert 	{
1727404b540aSrobert 	  half = (top - bot + 1) >> 1;
1728404b540aSrobert 	  field = field_array[bot+half];
1729404b540aSrobert 
1730404b540aSrobert 	  if (DECL_NAME (field) == NULL_TREE)
1731404b540aSrobert 	    {
1732404b540aSrobert 	      /* Step through all anon unions in linear fashion.  */
1733404b540aSrobert 	      while (DECL_NAME (field_array[bot]) == NULL_TREE)
1734404b540aSrobert 		{
1735404b540aSrobert 		  field = field_array[bot++];
1736404b540aSrobert 		  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
1737404b540aSrobert 		      || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
1738404b540aSrobert 		    {
1739404b540aSrobert 		      tree anon = lookup_field (field, component);
1740404b540aSrobert 
1741404b540aSrobert 		      if (anon)
1742404b540aSrobert 			return tree_cons (NULL_TREE, field, anon);
1743404b540aSrobert 		    }
1744404b540aSrobert 		}
1745404b540aSrobert 
1746404b540aSrobert 	      /* Entire record is only anon unions.  */
1747404b540aSrobert 	      if (bot > top)
1748404b540aSrobert 		return NULL_TREE;
1749404b540aSrobert 
1750404b540aSrobert 	      /* Restart the binary search, with new lower bound.  */
1751404b540aSrobert 	      continue;
1752404b540aSrobert 	    }
1753404b540aSrobert 
1754404b540aSrobert 	  if (DECL_NAME (field) == component)
1755404b540aSrobert 	    break;
1756404b540aSrobert 	  if (DECL_NAME (field) < component)
1757404b540aSrobert 	    bot += half;
1758404b540aSrobert 	  else
1759404b540aSrobert 	    top = bot + half;
1760404b540aSrobert 	}
1761404b540aSrobert 
1762404b540aSrobert       if (DECL_NAME (field_array[bot]) == component)
1763404b540aSrobert 	field = field_array[bot];
1764404b540aSrobert       else if (DECL_NAME (field) != component)
1765404b540aSrobert 	return NULL_TREE;
1766404b540aSrobert     }
1767404b540aSrobert   else
1768404b540aSrobert     {
1769404b540aSrobert       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
1770404b540aSrobert 	{
1771404b540aSrobert 	  if (DECL_NAME (field) == NULL_TREE
1772404b540aSrobert 	      && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
1773404b540aSrobert 		  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
1774404b540aSrobert 	    {
1775404b540aSrobert 	      tree anon = lookup_field (field, component);
1776404b540aSrobert 
1777404b540aSrobert 	      if (anon)
1778404b540aSrobert 		return tree_cons (NULL_TREE, field, anon);
1779404b540aSrobert 	    }
1780404b540aSrobert 
1781404b540aSrobert 	  if (DECL_NAME (field) == component)
1782404b540aSrobert 	    break;
1783404b540aSrobert 	}
1784404b540aSrobert 
1785404b540aSrobert       if (field == NULL_TREE)
1786404b540aSrobert 	return NULL_TREE;
1787404b540aSrobert     }
1788404b540aSrobert 
1789404b540aSrobert   return tree_cons (NULL_TREE, field, NULL_TREE);
1790404b540aSrobert }
1791404b540aSrobert 
1792404b540aSrobert /* Make an expression to refer to the COMPONENT field of
1793404b540aSrobert    structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
1794404b540aSrobert 
1795404b540aSrobert tree
build_component_ref(tree datum,tree component)1796404b540aSrobert build_component_ref (tree datum, tree component)
1797404b540aSrobert {
1798404b540aSrobert   tree type = TREE_TYPE (datum);
1799404b540aSrobert   enum tree_code code = TREE_CODE (type);
1800404b540aSrobert   tree field = NULL;
1801404b540aSrobert   tree ref;
1802404b540aSrobert 
1803404b540aSrobert   if (!objc_is_public (datum, component))
1804404b540aSrobert     return error_mark_node;
1805404b540aSrobert 
1806404b540aSrobert   /* See if there is a field or component with name COMPONENT.  */
1807404b540aSrobert 
1808404b540aSrobert   if (code == RECORD_TYPE || code == UNION_TYPE)
1809404b540aSrobert     {
1810404b540aSrobert       if (!COMPLETE_TYPE_P (type))
1811404b540aSrobert 	{
1812404b540aSrobert 	  c_incomplete_type_error (NULL_TREE, type);
1813404b540aSrobert 	  return error_mark_node;
1814404b540aSrobert 	}
1815404b540aSrobert 
1816404b540aSrobert       field = lookup_field (datum, component);
1817404b540aSrobert 
1818404b540aSrobert       if (!field)
1819404b540aSrobert 	{
1820404b540aSrobert 	  error ("%qT has no member named %qE", type, component);
1821404b540aSrobert 	  return error_mark_node;
1822404b540aSrobert 	}
1823404b540aSrobert 
1824404b540aSrobert       /* Chain the COMPONENT_REFs if necessary down to the FIELD.
1825404b540aSrobert 	 This might be better solved in future the way the C++ front
1826404b540aSrobert 	 end does it - by giving the anonymous entities each a
1827404b540aSrobert 	 separate name and type, and then have build_component_ref
1828404b540aSrobert 	 recursively call itself.  We can't do that here.  */
1829404b540aSrobert       do
1830404b540aSrobert 	{
1831404b540aSrobert 	  tree subdatum = TREE_VALUE (field);
1832404b540aSrobert 	  int quals;
1833404b540aSrobert 	  tree subtype;
1834404b540aSrobert 
1835404b540aSrobert 	  if (TREE_TYPE (subdatum) == error_mark_node)
1836404b540aSrobert 	    return error_mark_node;
1837404b540aSrobert 
1838404b540aSrobert 	  quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum)));
1839404b540aSrobert 	  quals |= TYPE_QUALS (TREE_TYPE (datum));
1840404b540aSrobert 	  subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals);
1841404b540aSrobert 
1842404b540aSrobert 	  ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
1843404b540aSrobert 			NULL_TREE);
1844404b540aSrobert 	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
1845404b540aSrobert 	    TREE_READONLY (ref) = 1;
1846404b540aSrobert 	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
1847404b540aSrobert 	    TREE_THIS_VOLATILE (ref) = 1;
1848404b540aSrobert 
1849404b540aSrobert 	  if (TREE_DEPRECATED (subdatum))
1850404b540aSrobert 	    warn_deprecated_use (subdatum);
1851404b540aSrobert 
1852404b540aSrobert 	  datum = ref;
1853404b540aSrobert 
1854404b540aSrobert 	  field = TREE_CHAIN (field);
1855404b540aSrobert 	}
1856404b540aSrobert       while (field);
1857404b540aSrobert 
1858404b540aSrobert       return ref;
1859404b540aSrobert     }
1860404b540aSrobert   else if (code != ERROR_MARK)
1861404b540aSrobert     error ("request for member %qE in something not a structure or union",
1862404b540aSrobert 	   component);
1863404b540aSrobert 
1864404b540aSrobert   return error_mark_node;
1865404b540aSrobert }
1866404b540aSrobert 
1867404b540aSrobert /* Given an expression PTR for a pointer, return an expression
1868404b540aSrobert    for the value pointed to.
1869404b540aSrobert    ERRORSTRING is the name of the operator to appear in error messages.  */
1870404b540aSrobert 
1871404b540aSrobert tree
build_indirect_ref(tree ptr,const char * errorstring)1872404b540aSrobert build_indirect_ref (tree ptr, const char *errorstring)
1873404b540aSrobert {
1874404b540aSrobert   tree pointer = default_conversion (ptr);
1875404b540aSrobert   tree type = TREE_TYPE (pointer);
1876404b540aSrobert 
1877404b540aSrobert   if (TREE_CODE (type) == POINTER_TYPE)
1878404b540aSrobert     {
1879404b540aSrobert       if (TREE_CODE (pointer) == ADDR_EXPR
1880404b540aSrobert 	  && (TREE_TYPE (TREE_OPERAND (pointer, 0))
1881404b540aSrobert 	      == TREE_TYPE (type)))
1882404b540aSrobert 	return TREE_OPERAND (pointer, 0);
1883404b540aSrobert       else
1884404b540aSrobert 	{
1885404b540aSrobert 	  tree t = TREE_TYPE (type);
1886404b540aSrobert 	  tree ref;
1887404b540aSrobert 
1888404b540aSrobert 	  ref = build1 (INDIRECT_REF, t, pointer);
1889404b540aSrobert 
1890404b540aSrobert 	  if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
1891404b540aSrobert 	    {
1892404b540aSrobert 	      error ("dereferencing pointer to incomplete type");
1893404b540aSrobert 	      return error_mark_node;
1894404b540aSrobert 	    }
1895404b540aSrobert 	  if (VOID_TYPE_P (t) && skip_evaluation == 0)
1896404b540aSrobert 	    warning (0, "dereferencing %<void *%> pointer");
1897404b540aSrobert 
1898404b540aSrobert 	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
1899404b540aSrobert 	     so that we get the proper error message if the result is used
1900404b540aSrobert 	     to assign to.  Also, &* is supposed to be a no-op.
1901404b540aSrobert 	     And ANSI C seems to specify that the type of the result
1902404b540aSrobert 	     should be the const type.  */
1903404b540aSrobert 	  /* A de-reference of a pointer to const is not a const.  It is valid
1904404b540aSrobert 	     to change it via some other pointer.  */
1905404b540aSrobert 	  TREE_READONLY (ref) = TYPE_READONLY (t);
1906404b540aSrobert 	  TREE_SIDE_EFFECTS (ref)
1907404b540aSrobert 	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
1908404b540aSrobert 	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
1909404b540aSrobert 	  return ref;
1910404b540aSrobert 	}
1911404b540aSrobert     }
1912404b540aSrobert   else if (TREE_CODE (pointer) != ERROR_MARK)
1913404b540aSrobert     error ("invalid type argument of %qs", errorstring);
1914404b540aSrobert   return error_mark_node;
1915404b540aSrobert }
1916404b540aSrobert 
1917404b540aSrobert /* This handles expressions of the form "a[i]", which denotes
1918404b540aSrobert    an array reference.
1919404b540aSrobert 
1920404b540aSrobert    This is logically equivalent in C to *(a+i), but we may do it differently.
1921404b540aSrobert    If A is a variable or a member, we generate a primitive ARRAY_REF.
1922404b540aSrobert    This avoids forcing the array out of registers, and can work on
1923404b540aSrobert    arrays that are not lvalues (for example, members of structures returned
1924404b540aSrobert    by functions).  */
1925404b540aSrobert 
1926404b540aSrobert tree
build_array_ref(tree array,tree index)1927404b540aSrobert build_array_ref (tree array, tree index)
1928404b540aSrobert {
1929404b540aSrobert   bool swapped = false;
1930404b540aSrobert   if (TREE_TYPE (array) == error_mark_node
1931404b540aSrobert       || TREE_TYPE (index) == error_mark_node)
1932404b540aSrobert     return error_mark_node;
1933404b540aSrobert 
1934404b540aSrobert   if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
1935404b540aSrobert       && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
1936404b540aSrobert     {
1937404b540aSrobert       tree temp;
1938404b540aSrobert       if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
1939404b540aSrobert 	  && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
1940404b540aSrobert 	{
1941404b540aSrobert 	  error ("subscripted value is neither array nor pointer");
1942404b540aSrobert 	  return error_mark_node;
1943404b540aSrobert 	}
1944404b540aSrobert       temp = array;
1945404b540aSrobert       array = index;
1946404b540aSrobert       index = temp;
1947404b540aSrobert       swapped = true;
1948404b540aSrobert     }
1949404b540aSrobert 
1950404b540aSrobert   if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
1951404b540aSrobert     {
1952404b540aSrobert       error ("array subscript is not an integer");
1953404b540aSrobert       return error_mark_node;
1954404b540aSrobert     }
1955404b540aSrobert 
1956404b540aSrobert   if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE)
1957404b540aSrobert     {
1958404b540aSrobert       error ("subscripted value is pointer to function");
1959404b540aSrobert       return error_mark_node;
1960404b540aSrobert     }
1961404b540aSrobert 
1962404b540aSrobert   /* ??? Existing practice has been to warn only when the char
1963404b540aSrobert      index is syntactically the index, not for char[array].  */
1964404b540aSrobert   if (!swapped)
1965404b540aSrobert      warn_array_subscript_with_type_char (index);
1966404b540aSrobert 
1967404b540aSrobert   /* Apply default promotions *after* noticing character types.  */
1968404b540aSrobert   index = default_conversion (index);
1969404b540aSrobert 
1970404b540aSrobert   gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
1971404b540aSrobert 
1972404b540aSrobert   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1973404b540aSrobert     {
1974404b540aSrobert       tree rval, type;
1975404b540aSrobert 
1976404b540aSrobert       /* An array that is indexed by a non-constant
1977404b540aSrobert 	 cannot be stored in a register; we must be able to do
1978404b540aSrobert 	 address arithmetic on its address.
1979404b540aSrobert 	 Likewise an array of elements of variable size.  */
1980404b540aSrobert       if (TREE_CODE (index) != INTEGER_CST
1981404b540aSrobert 	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
1982404b540aSrobert 	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
1983404b540aSrobert 	{
1984404b540aSrobert 	  if (!c_mark_addressable (array))
1985404b540aSrobert 	    return error_mark_node;
1986404b540aSrobert 	}
1987404b540aSrobert       /* An array that is indexed by a constant value which is not within
1988404b540aSrobert 	 the array bounds cannot be stored in a register either; because we
1989404b540aSrobert 	 would get a crash in store_bit_field/extract_bit_field when trying
1990404b540aSrobert 	 to access a non-existent part of the register.  */
1991404b540aSrobert       if (TREE_CODE (index) == INTEGER_CST
1992404b540aSrobert 	  && TYPE_DOMAIN (TREE_TYPE (array))
1993404b540aSrobert 	  && !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array))))
1994404b540aSrobert 	{
1995404b540aSrobert 	  if (!c_mark_addressable (array))
1996404b540aSrobert 	    return error_mark_node;
1997404b540aSrobert 	}
1998404b540aSrobert 
1999404b540aSrobert       if (pedantic)
2000404b540aSrobert 	{
2001404b540aSrobert 	  tree foo = array;
2002404b540aSrobert 	  while (TREE_CODE (foo) == COMPONENT_REF)
2003404b540aSrobert 	    foo = TREE_OPERAND (foo, 0);
2004404b540aSrobert 	  if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
2005404b540aSrobert 	    pedwarn ("ISO C forbids subscripting %<register%> array");
2006404b540aSrobert 	  else if (!flag_isoc99 && !lvalue_p (foo))
2007404b540aSrobert 	    pedwarn ("ISO C90 forbids subscripting non-lvalue array");
2008404b540aSrobert 	}
2009404b540aSrobert 
2010404b540aSrobert       type = TREE_TYPE (TREE_TYPE (array));
2011404b540aSrobert       if (TREE_CODE (type) != ARRAY_TYPE)
2012404b540aSrobert 	type = TYPE_MAIN_VARIANT (type);
2013404b540aSrobert       rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
2014404b540aSrobert       /* Array ref is const/volatile if the array elements are
2015404b540aSrobert 	 or if the array is.  */
2016404b540aSrobert       TREE_READONLY (rval)
2017404b540aSrobert 	|= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
2018404b540aSrobert 	    | TREE_READONLY (array));
2019404b540aSrobert       TREE_SIDE_EFFECTS (rval)
2020404b540aSrobert 	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
2021404b540aSrobert 	    | TREE_SIDE_EFFECTS (array));
2022404b540aSrobert       TREE_THIS_VOLATILE (rval)
2023404b540aSrobert 	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
2024404b540aSrobert 	    /* This was added by rms on 16 Nov 91.
2025404b540aSrobert 	       It fixes  vol struct foo *a;  a->elts[1]
2026404b540aSrobert 	       in an inline function.
2027404b540aSrobert 	       Hope it doesn't break something else.  */
2028404b540aSrobert 	    | TREE_THIS_VOLATILE (array));
2029404b540aSrobert       return require_complete_type (fold (rval));
2030404b540aSrobert     }
2031404b540aSrobert   else
2032404b540aSrobert     {
2033404b540aSrobert       tree ar = default_conversion (array);
2034404b540aSrobert 
2035404b540aSrobert       if (ar == error_mark_node)
2036404b540aSrobert 	return ar;
2037404b540aSrobert 
2038404b540aSrobert       gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
2039404b540aSrobert       gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
2040404b540aSrobert 
2041404b540aSrobert       return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
2042404b540aSrobert 				 "array indexing");
2043404b540aSrobert     }
2044404b540aSrobert }
2045404b540aSrobert 
2046404b540aSrobert /* Build an external reference to identifier ID.  FUN indicates
2047404b540aSrobert    whether this will be used for a function call.  LOC is the source
2048404b540aSrobert    location of the identifier.  */
2049404b540aSrobert tree
build_external_ref(tree id,int fun,location_t loc)2050404b540aSrobert build_external_ref (tree id, int fun, location_t loc)
2051404b540aSrobert {
2052404b540aSrobert   tree ref;
2053404b540aSrobert   tree decl = lookup_name (id);
2054404b540aSrobert 
2055404b540aSrobert   /* In Objective-C, an instance variable (ivar) may be preferred to
2056404b540aSrobert      whatever lookup_name() found.  */
2057404b540aSrobert   decl = objc_lookup_ivar (decl, id);
2058404b540aSrobert 
2059404b540aSrobert   if (decl && decl != error_mark_node)
2060404b540aSrobert     ref = decl;
2061404b540aSrobert   else if (fun)
2062404b540aSrobert     /* Implicit function declaration.  */
2063404b540aSrobert     ref = implicitly_declare (id);
2064404b540aSrobert   else if (decl == error_mark_node)
2065404b540aSrobert     /* Don't complain about something that's already been
2066404b540aSrobert        complained about.  */
2067404b540aSrobert     return error_mark_node;
2068404b540aSrobert   else
2069404b540aSrobert     {
2070404b540aSrobert       undeclared_variable (id, loc);
2071404b540aSrobert       return error_mark_node;
2072404b540aSrobert     }
2073404b540aSrobert 
2074404b540aSrobert   if (TREE_TYPE (ref) == error_mark_node)
2075404b540aSrobert     return error_mark_node;
2076404b540aSrobert 
2077404b540aSrobert   if (TREE_DEPRECATED (ref))
2078404b540aSrobert     warn_deprecated_use (ref);
2079404b540aSrobert 
2080404b540aSrobert   if (!skip_evaluation)
2081404b540aSrobert     assemble_external (ref);
2082404b540aSrobert   TREE_USED (ref) = 1;
2083404b540aSrobert 
2084404b540aSrobert   if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof)
2085404b540aSrobert     {
2086404b540aSrobert       if (!in_sizeof && !in_typeof)
2087404b540aSrobert 	C_DECL_USED (ref) = 1;
2088404b540aSrobert       else if (DECL_INITIAL (ref) == 0
2089404b540aSrobert 	       && DECL_EXTERNAL (ref)
2090404b540aSrobert 	       && !TREE_PUBLIC (ref))
2091404b540aSrobert 	record_maybe_used_decl (ref);
2092404b540aSrobert     }
2093404b540aSrobert 
2094404b540aSrobert   if (TREE_CODE (ref) == CONST_DECL)
2095404b540aSrobert     {
2096404b540aSrobert       used_types_insert (TREE_TYPE (ref));
2097404b540aSrobert       ref = DECL_INITIAL (ref);
2098404b540aSrobert       TREE_CONSTANT (ref) = 1;
2099404b540aSrobert       TREE_INVARIANT (ref) = 1;
2100404b540aSrobert     }
2101404b540aSrobert   else if (current_function_decl != 0
2102404b540aSrobert 	   && !DECL_FILE_SCOPE_P (current_function_decl)
2103404b540aSrobert 	   && (TREE_CODE (ref) == VAR_DECL
2104404b540aSrobert 	       || TREE_CODE (ref) == PARM_DECL
2105404b540aSrobert 	       || TREE_CODE (ref) == FUNCTION_DECL))
2106404b540aSrobert     {
2107404b540aSrobert       tree context = decl_function_context (ref);
2108404b540aSrobert 
2109404b540aSrobert       if (context != 0 && context != current_function_decl)
2110404b540aSrobert 	DECL_NONLOCAL (ref) = 1;
2111404b540aSrobert     }
2112404b540aSrobert 
2113404b540aSrobert   return ref;
2114404b540aSrobert }
2115404b540aSrobert 
2116404b540aSrobert /* Record details of decls possibly used inside sizeof or typeof.  */
2117404b540aSrobert struct maybe_used_decl
2118404b540aSrobert {
2119404b540aSrobert   /* The decl.  */
2120404b540aSrobert   tree decl;
2121404b540aSrobert   /* The level seen at (in_sizeof + in_typeof).  */
2122404b540aSrobert   int level;
2123404b540aSrobert   /* The next one at this level or above, or NULL.  */
2124404b540aSrobert   struct maybe_used_decl *next;
2125404b540aSrobert };
2126404b540aSrobert 
2127404b540aSrobert static struct maybe_used_decl *maybe_used_decls;
2128404b540aSrobert 
2129404b540aSrobert /* Record that DECL, an undefined static function reference seen
2130404b540aSrobert    inside sizeof or typeof, might be used if the operand of sizeof is
2131404b540aSrobert    a VLA type or the operand of typeof is a variably modified
2132404b540aSrobert    type.  */
2133404b540aSrobert 
2134404b540aSrobert static void
record_maybe_used_decl(tree decl)2135404b540aSrobert record_maybe_used_decl (tree decl)
2136404b540aSrobert {
2137404b540aSrobert   struct maybe_used_decl *t = XOBNEW (&parser_obstack, struct maybe_used_decl);
2138404b540aSrobert   t->decl = decl;
2139404b540aSrobert   t->level = in_sizeof + in_typeof;
2140404b540aSrobert   t->next = maybe_used_decls;
2141404b540aSrobert   maybe_used_decls = t;
2142404b540aSrobert }
2143404b540aSrobert 
2144404b540aSrobert /* Pop the stack of decls possibly used inside sizeof or typeof.  If
2145404b540aSrobert    USED is false, just discard them.  If it is true, mark them used
2146404b540aSrobert    (if no longer inside sizeof or typeof) or move them to the next
2147404b540aSrobert    level up (if still inside sizeof or typeof).  */
2148404b540aSrobert 
2149404b540aSrobert void
pop_maybe_used(bool used)2150404b540aSrobert pop_maybe_used (bool used)
2151404b540aSrobert {
2152404b540aSrobert   struct maybe_used_decl *p = maybe_used_decls;
2153404b540aSrobert   int cur_level = in_sizeof + in_typeof;
2154404b540aSrobert   while (p && p->level > cur_level)
2155404b540aSrobert     {
2156404b540aSrobert       if (used)
2157404b540aSrobert 	{
2158404b540aSrobert 	  if (cur_level == 0)
2159404b540aSrobert 	    C_DECL_USED (p->decl) = 1;
2160404b540aSrobert 	  else
2161404b540aSrobert 	    p->level = cur_level;
2162404b540aSrobert 	}
2163404b540aSrobert       p = p->next;
2164404b540aSrobert     }
2165404b540aSrobert   if (!used || cur_level == 0)
2166404b540aSrobert     maybe_used_decls = p;
2167404b540aSrobert }
2168404b540aSrobert 
2169404b540aSrobert /* Return the result of sizeof applied to EXPR.  */
2170404b540aSrobert 
2171404b540aSrobert struct c_expr
c_expr_sizeof_expr(struct c_expr expr)2172404b540aSrobert c_expr_sizeof_expr (struct c_expr expr)
2173404b540aSrobert {
2174404b540aSrobert   struct c_expr ret;
2175404b540aSrobert   if (expr.value == error_mark_node)
2176404b540aSrobert     {
2177404b540aSrobert       ret.value = error_mark_node;
2178404b540aSrobert       ret.original_code = ERROR_MARK;
2179404b540aSrobert       pop_maybe_used (false);
2180404b540aSrobert     }
2181404b540aSrobert   else
2182404b540aSrobert     {
2183404b540aSrobert       ret.value = c_sizeof (TREE_TYPE (expr.value));
2184404b540aSrobert       ret.original_code = ERROR_MARK;
2185404b540aSrobert       if (c_vla_type_p (TREE_TYPE (expr.value)))
2186404b540aSrobert 	{
2187404b540aSrobert 	  /* sizeof is evaluated when given a vla (C99 6.5.3.4p2).  */
2188404b540aSrobert 	  ret.value = build2 (COMPOUND_EXPR, TREE_TYPE (ret.value), expr.value, ret.value);
2189404b540aSrobert 	}
2190404b540aSrobert       pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (expr.value)));
2191404b540aSrobert     }
2192404b540aSrobert   return ret;
2193404b540aSrobert }
2194404b540aSrobert 
2195404b540aSrobert /* Return the result of sizeof applied to T, a structure for the type
2196404b540aSrobert    name passed to sizeof (rather than the type itself).  */
2197404b540aSrobert 
2198404b540aSrobert struct c_expr
c_expr_sizeof_type(struct c_type_name * t)2199404b540aSrobert c_expr_sizeof_type (struct c_type_name *t)
2200404b540aSrobert {
2201404b540aSrobert   tree type;
2202404b540aSrobert   struct c_expr ret;
2203404b540aSrobert   type = groktypename (t);
2204404b540aSrobert   ret.value = c_sizeof (type);
2205404b540aSrobert   ret.original_code = ERROR_MARK;
2206404b540aSrobert   pop_maybe_used (type != error_mark_node
2207404b540aSrobert 		  ? C_TYPE_VARIABLE_SIZE (type) : false);
2208404b540aSrobert   return ret;
2209404b540aSrobert }
2210404b540aSrobert 
2211404b540aSrobert /* Build a function call to function FUNCTION with parameters PARAMS.
2212404b540aSrobert    PARAMS is a list--a chain of TREE_LIST nodes--in which the
2213404b540aSrobert    TREE_VALUE of each node is a parameter-expression.
2214404b540aSrobert    FUNCTION's data type may be a function type or a pointer-to-function.  */
2215404b540aSrobert 
2216404b540aSrobert tree
build_function_call(tree function,tree params)2217404b540aSrobert build_function_call (tree function, tree params)
2218404b540aSrobert {
2219404b540aSrobert   tree fntype, fundecl = 0;
2220404b540aSrobert   tree coerced_params;
2221404b540aSrobert   tree name = NULL_TREE, result;
2222404b540aSrobert   tree tem;
2223404b540aSrobert 
2224404b540aSrobert   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
2225404b540aSrobert   STRIP_TYPE_NOPS (function);
2226404b540aSrobert 
2227404b540aSrobert   /* Convert anything with function type to a pointer-to-function.  */
2228404b540aSrobert   if (TREE_CODE (function) == FUNCTION_DECL)
2229404b540aSrobert     {
2230404b540aSrobert       /* Implement type-directed function overloading for builtins.
2231404b540aSrobert 	 resolve_overloaded_builtin and targetm.resolve_overloaded_builtin
2232404b540aSrobert 	 handle all the type checking.  The result is a complete expression
2233404b540aSrobert 	 that implements this function call.  */
2234404b540aSrobert       tem = resolve_overloaded_builtin (function, params);
2235404b540aSrobert       if (tem)
2236404b540aSrobert 	return tem;
2237404b540aSrobert 
2238404b540aSrobert       name = DECL_NAME (function);
2239404b540aSrobert       fundecl = function;
2240404b540aSrobert     }
2241404b540aSrobert   if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
2242404b540aSrobert     function = function_to_pointer_conversion (function);
2243404b540aSrobert 
2244404b540aSrobert   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
2245404b540aSrobert      expressions, like those used for ObjC messenger dispatches.  */
2246404b540aSrobert   function = objc_rewrite_function_call (function, params);
2247404b540aSrobert 
2248404b540aSrobert   fntype = TREE_TYPE (function);
2249404b540aSrobert 
2250404b540aSrobert   if (TREE_CODE (fntype) == ERROR_MARK)
2251404b540aSrobert     return error_mark_node;
2252404b540aSrobert 
2253404b540aSrobert   if (!(TREE_CODE (fntype) == POINTER_TYPE
2254404b540aSrobert 	&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
2255404b540aSrobert     {
2256404b540aSrobert       error ("called object %qE is not a function", function);
2257404b540aSrobert       return error_mark_node;
2258404b540aSrobert     }
2259404b540aSrobert 
2260404b540aSrobert   if (fundecl && TREE_THIS_VOLATILE (fundecl))
2261404b540aSrobert     current_function_returns_abnormally = 1;
2262404b540aSrobert 
2263404b540aSrobert   /* fntype now gets the type of function pointed to.  */
2264404b540aSrobert   fntype = TREE_TYPE (fntype);
2265404b540aSrobert 
2266404b540aSrobert   /* Check that the function is called through a compatible prototype.
2267404b540aSrobert      If it is not, replace the call by a trap, wrapped up in a compound
2268404b540aSrobert      expression if necessary.  This has the nice side-effect to prevent
2269404b540aSrobert      the tree-inliner from generating invalid assignment trees which may
2270404b540aSrobert      blow up in the RTL expander later.  */
2271404b540aSrobert   if ((TREE_CODE (function) == NOP_EXPR
2272404b540aSrobert        || TREE_CODE (function) == CONVERT_EXPR)
2273404b540aSrobert       && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
2274404b540aSrobert       && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
2275404b540aSrobert       && !comptypes (fntype, TREE_TYPE (tem)))
2276404b540aSrobert     {
2277404b540aSrobert       tree return_type = TREE_TYPE (fntype);
2278404b540aSrobert       tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
2279404b540aSrobert 				       NULL_TREE);
2280404b540aSrobert 
2281404b540aSrobert       /* This situation leads to run-time undefined behavior.  We can't,
2282404b540aSrobert 	 therefore, simply error unless we can prove that all possible
2283404b540aSrobert 	 executions of the program must execute the code.  */
2284404b540aSrobert       warning (0, "function called through a non-compatible type");
2285404b540aSrobert 
2286404b540aSrobert       /* We can, however, treat "undefined" any way we please.
2287404b540aSrobert 	 Call abort to encourage the user to fix the program.  */
2288404b540aSrobert       inform ("if this code is reached, the program will abort");
2289404b540aSrobert 
2290404b540aSrobert       if (VOID_TYPE_P (return_type))
2291404b540aSrobert 	return trap;
2292404b540aSrobert       else
2293404b540aSrobert 	{
2294404b540aSrobert 	  tree rhs;
2295404b540aSrobert 
2296404b540aSrobert 	  if (AGGREGATE_TYPE_P (return_type))
2297404b540aSrobert 	    rhs = build_compound_literal (return_type,
2298404b540aSrobert 					  build_constructor (return_type, 0));
2299404b540aSrobert 	  else
2300404b540aSrobert 	    rhs = fold_convert (return_type, integer_zero_node);
2301404b540aSrobert 
2302404b540aSrobert 	  return build2 (COMPOUND_EXPR, return_type, trap, rhs);
2303404b540aSrobert 	}
2304404b540aSrobert     }
2305404b540aSrobert 
2306404b540aSrobert   /* Convert the parameters to the types declared in the
2307404b540aSrobert      function prototype, or apply default promotions.  */
2308404b540aSrobert 
2309404b540aSrobert   coerced_params
2310404b540aSrobert     = convert_arguments (TYPE_ARG_TYPES (fntype), params, function, fundecl);
2311404b540aSrobert 
2312404b540aSrobert   if (coerced_params == error_mark_node)
2313404b540aSrobert     return error_mark_node;
2314404b540aSrobert 
2315404b540aSrobert   /* Check that the arguments to the function are valid.  */
2316404b540aSrobert 
2317404b540aSrobert   check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
2318404b540aSrobert 			    TYPE_ARG_TYPES (fntype));
2319404b540aSrobert 
2320404b540aSrobert   if (require_constant_value)
2321404b540aSrobert     {
2322404b540aSrobert       result = fold_build3_initializer (CALL_EXPR, TREE_TYPE (fntype),
2323404b540aSrobert 					function, coerced_params, NULL_TREE);
2324404b540aSrobert 
2325404b540aSrobert       if (TREE_CONSTANT (result)
2326404b540aSrobert 	  && (name == NULL_TREE
2327404b540aSrobert 	      || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
2328404b540aSrobert 	pedwarn_init ("initializer element is not constant");
2329404b540aSrobert     }
2330404b540aSrobert   else
2331404b540aSrobert     result = fold_build3 (CALL_EXPR, TREE_TYPE (fntype),
2332404b540aSrobert 			  function, coerced_params, NULL_TREE);
2333404b540aSrobert 
2334404b540aSrobert   if (VOID_TYPE_P (TREE_TYPE (result)))
2335404b540aSrobert     return result;
2336404b540aSrobert   return require_complete_type (result);
2337404b540aSrobert }
2338404b540aSrobert 
2339404b540aSrobert /* Convert the argument expressions in the list VALUES
2340404b540aSrobert    to the types in the list TYPELIST.  The result is a list of converted
2341404b540aSrobert    argument expressions, unless there are too few arguments in which
2342404b540aSrobert    case it is error_mark_node.
2343404b540aSrobert 
2344404b540aSrobert    If TYPELIST is exhausted, or when an element has NULL as its type,
2345404b540aSrobert    perform the default conversions.
2346404b540aSrobert 
2347404b540aSrobert    PARMLIST is the chain of parm decls for the function being called.
2348404b540aSrobert    It may be 0, if that info is not available.
2349404b540aSrobert    It is used only for generating error messages.
2350404b540aSrobert 
2351404b540aSrobert    FUNCTION is a tree for the called function.  It is used only for
2352404b540aSrobert    error messages, where it is formatted with %qE.
2353404b540aSrobert 
2354404b540aSrobert    This is also where warnings about wrong number of args are generated.
2355404b540aSrobert 
2356404b540aSrobert    Both VALUES and the returned value are chains of TREE_LIST nodes
2357404b540aSrobert    with the elements of the list in the TREE_VALUE slots of those nodes.  */
2358404b540aSrobert 
2359404b540aSrobert static tree
convert_arguments(tree typelist,tree values,tree function,tree fundecl)2360404b540aSrobert convert_arguments (tree typelist, tree values, tree function, tree fundecl)
2361404b540aSrobert {
2362404b540aSrobert   tree typetail, valtail;
2363404b540aSrobert   tree result = NULL;
2364404b540aSrobert   int parmnum;
2365404b540aSrobert   tree selector;
2366404b540aSrobert 
2367404b540aSrobert   /* Change pointer to function to the function itself for
2368404b540aSrobert      diagnostics.  */
2369404b540aSrobert   if (TREE_CODE (function) == ADDR_EXPR
2370404b540aSrobert       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
2371404b540aSrobert     function = TREE_OPERAND (function, 0);
2372404b540aSrobert 
2373404b540aSrobert   /* Handle an ObjC selector specially for diagnostics.  */
2374404b540aSrobert   selector = objc_message_selector ();
2375404b540aSrobert 
2376404b540aSrobert   /* Scan the given expressions and types, producing individual
2377404b540aSrobert      converted arguments and pushing them on RESULT in reverse order.  */
2378404b540aSrobert 
2379404b540aSrobert   for (valtail = values, typetail = typelist, parmnum = 0;
2380404b540aSrobert        valtail;
2381404b540aSrobert        valtail = TREE_CHAIN (valtail), parmnum++)
2382404b540aSrobert     {
2383404b540aSrobert       tree type = typetail ? TREE_VALUE (typetail) : 0;
2384404b540aSrobert       tree val = TREE_VALUE (valtail);
2385404b540aSrobert       tree rname = function;
2386404b540aSrobert       int argnum = parmnum + 1;
2387404b540aSrobert       const char *invalid_func_diag;
2388404b540aSrobert 
2389404b540aSrobert       if (type == void_type_node)
2390404b540aSrobert 	{
2391404b540aSrobert 	  error ("too many arguments to function %qE", function);
2392404b540aSrobert 	  break;
2393404b540aSrobert 	}
2394404b540aSrobert 
2395404b540aSrobert       if (selector && argnum > 2)
2396404b540aSrobert 	{
2397404b540aSrobert 	  rname = selector;
2398404b540aSrobert 	  argnum -= 2;
2399404b540aSrobert 	}
2400404b540aSrobert 
2401404b540aSrobert       STRIP_TYPE_NOPS (val);
2402404b540aSrobert 
2403404b540aSrobert       val = require_complete_type (val);
2404404b540aSrobert 
2405404b540aSrobert       if (type != 0)
2406404b540aSrobert 	{
2407404b540aSrobert 	  /* Formal parm type is specified by a function prototype.  */
2408404b540aSrobert 	  tree parmval;
2409404b540aSrobert 
2410404b540aSrobert 	  if (type == error_mark_node || !COMPLETE_TYPE_P (type))
2411404b540aSrobert 	    {
2412404b540aSrobert 	      error ("type of formal parameter %d is incomplete", parmnum + 1);
2413404b540aSrobert 	      parmval = val;
2414404b540aSrobert 	    }
2415404b540aSrobert 	  else
2416404b540aSrobert 	    {
2417404b540aSrobert 	      /* Optionally warn about conversions that
2418404b540aSrobert 		 differ from the default conversions.  */
2419404b540aSrobert 	      if (warn_conversion || warn_traditional)
2420404b540aSrobert 		{
2421404b540aSrobert 		  unsigned int formal_prec = TYPE_PRECISION (type);
2422404b540aSrobert 
2423404b540aSrobert 		  if (INTEGRAL_TYPE_P (type)
2424404b540aSrobert 		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
2425404b540aSrobert 		    warning (0, "passing argument %d of %qE as integer "
2426404b540aSrobert 			     "rather than floating due to prototype",
2427404b540aSrobert 			     argnum, rname);
2428404b540aSrobert 		  if (INTEGRAL_TYPE_P (type)
2429404b540aSrobert 		      && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
2430404b540aSrobert 		    warning (0, "passing argument %d of %qE as integer "
2431404b540aSrobert 			     "rather than complex due to prototype",
2432404b540aSrobert 			     argnum, rname);
2433404b540aSrobert 		  else if (TREE_CODE (type) == COMPLEX_TYPE
2434404b540aSrobert 			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
2435404b540aSrobert 		    warning (0, "passing argument %d of %qE as complex "
2436404b540aSrobert 			     "rather than floating due to prototype",
2437404b540aSrobert 			     argnum, rname);
2438404b540aSrobert 		  else if (TREE_CODE (type) == REAL_TYPE
2439404b540aSrobert 			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
2440404b540aSrobert 		    warning (0, "passing argument %d of %qE as floating "
2441404b540aSrobert 			     "rather than integer due to prototype",
2442404b540aSrobert 			     argnum, rname);
2443404b540aSrobert 		  else if (TREE_CODE (type) == COMPLEX_TYPE
2444404b540aSrobert 			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
2445404b540aSrobert 		    warning (0, "passing argument %d of %qE as complex "
2446404b540aSrobert 			     "rather than integer due to prototype",
2447404b540aSrobert 			     argnum, rname);
2448404b540aSrobert 		  else if (TREE_CODE (type) == REAL_TYPE
2449404b540aSrobert 			   && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
2450404b540aSrobert 		    warning (0, "passing argument %d of %qE as floating "
2451404b540aSrobert 			     "rather than complex due to prototype",
2452404b540aSrobert 			     argnum, rname);
2453404b540aSrobert 		  /* ??? At some point, messages should be written about
2454404b540aSrobert 		     conversions between complex types, but that's too messy
2455404b540aSrobert 		     to do now.  */
2456404b540aSrobert 		  else if (TREE_CODE (type) == REAL_TYPE
2457404b540aSrobert 			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
2458404b540aSrobert 		    {
2459404b540aSrobert 		      /* Warn if any argument is passed as `float',
2460404b540aSrobert 			 since without a prototype it would be `double'.  */
2461404b540aSrobert 		      if (formal_prec == TYPE_PRECISION (float_type_node)
2462404b540aSrobert 			  && type != dfloat32_type_node)
2463404b540aSrobert 			warning (0, "passing argument %d of %qE as %<float%> "
2464404b540aSrobert 				 "rather than %<double%> due to prototype",
2465404b540aSrobert 				 argnum, rname);
2466404b540aSrobert 
2467404b540aSrobert 		      /* Warn if mismatch between argument and prototype
2468404b540aSrobert 			 for decimal float types.  Warn of conversions with
2469404b540aSrobert 			 binary float types and of precision narrowing due to
2470404b540aSrobert 			 prototype. */
2471404b540aSrobert  		      else if (type != TREE_TYPE (val)
2472404b540aSrobert 			       && (type == dfloat32_type_node
2473404b540aSrobert 				   || type == dfloat64_type_node
2474404b540aSrobert 				   || type == dfloat128_type_node
2475404b540aSrobert 				   || TREE_TYPE (val) == dfloat32_type_node
2476404b540aSrobert 				   || TREE_TYPE (val) == dfloat64_type_node
2477404b540aSrobert 				   || TREE_TYPE (val) == dfloat128_type_node)
2478404b540aSrobert 			       && (formal_prec
2479404b540aSrobert 				   <= TYPE_PRECISION (TREE_TYPE (val))
2480404b540aSrobert 				   || (type == dfloat128_type_node
2481404b540aSrobert 				       && (TREE_TYPE (val)
2482404b540aSrobert 					   != dfloat64_type_node
2483404b540aSrobert 					   && (TREE_TYPE (val)
2484404b540aSrobert 					       != dfloat32_type_node)))
2485404b540aSrobert 				   || (type == dfloat64_type_node
2486404b540aSrobert 				       && (TREE_TYPE (val)
2487404b540aSrobert 					   != dfloat32_type_node))))
2488404b540aSrobert 			warning (0, "passing argument %d of %qE as %qT "
2489404b540aSrobert 				 "rather than %qT due to prototype",
2490404b540aSrobert 				 argnum, rname, type, TREE_TYPE (val));
2491404b540aSrobert 
2492404b540aSrobert 		    }
2493404b540aSrobert 		  /* Detect integer changing in width or signedness.
2494404b540aSrobert 		     These warnings are only activated with
2495404b540aSrobert 		     -Wconversion, not with -Wtraditional.  */
2496404b540aSrobert 		  else if (warn_conversion && INTEGRAL_TYPE_P (type)
2497404b540aSrobert 			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
2498404b540aSrobert 		    {
2499404b540aSrobert 		      tree would_have_been = default_conversion (val);
2500404b540aSrobert 		      tree type1 = TREE_TYPE (would_have_been);
2501404b540aSrobert 
2502404b540aSrobert 		      if (TREE_CODE (type) == ENUMERAL_TYPE
2503404b540aSrobert 			  && (TYPE_MAIN_VARIANT (type)
2504404b540aSrobert 			      == TYPE_MAIN_VARIANT (TREE_TYPE (val))))
2505404b540aSrobert 			/* No warning if function asks for enum
2506404b540aSrobert 			   and the actual arg is that enum type.  */
2507404b540aSrobert 			;
2508404b540aSrobert 		      else if (formal_prec != TYPE_PRECISION (type1))
2509404b540aSrobert 			warning (OPT_Wconversion, "passing argument %d of %qE "
2510404b540aSrobert 				 "with different width due to prototype",
2511404b540aSrobert 				 argnum, rname);
2512404b540aSrobert 		      else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
2513404b540aSrobert 			;
2514404b540aSrobert 		      /* Don't complain if the formal parameter type
2515404b540aSrobert 			 is an enum, because we can't tell now whether
2516404b540aSrobert 			 the value was an enum--even the same enum.  */
2517404b540aSrobert 		      else if (TREE_CODE (type) == ENUMERAL_TYPE)
2518404b540aSrobert 			;
2519404b540aSrobert 		      else if (TREE_CODE (val) == INTEGER_CST
2520404b540aSrobert 			       && int_fits_type_p (val, type))
2521404b540aSrobert 			/* Change in signedness doesn't matter
2522404b540aSrobert 			   if a constant value is unaffected.  */
2523404b540aSrobert 			;
2524404b540aSrobert 		      /* If the value is extended from a narrower
2525404b540aSrobert 			 unsigned type, it doesn't matter whether we
2526404b540aSrobert 			 pass it as signed or unsigned; the value
2527404b540aSrobert 			 certainly is the same either way.  */
2528404b540aSrobert 		      else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)
2529404b540aSrobert 			       && TYPE_UNSIGNED (TREE_TYPE (val)))
2530404b540aSrobert 			;
2531404b540aSrobert 		      else if (TYPE_UNSIGNED (type))
2532404b540aSrobert 			warning (OPT_Wconversion, "passing argument %d of %qE "
2533404b540aSrobert 				 "as unsigned due to prototype",
2534404b540aSrobert 				 argnum, rname);
2535404b540aSrobert 		      else
2536404b540aSrobert 			warning (OPT_Wconversion, "passing argument %d of %qE "
2537404b540aSrobert 				 "as signed due to prototype", argnum, rname);
2538404b540aSrobert 		    }
2539404b540aSrobert 		}
2540404b540aSrobert 
2541404b540aSrobert 	      parmval = convert_for_assignment (type, val, ic_argpass,
2542404b540aSrobert 						fundecl, function,
2543404b540aSrobert 						parmnum + 1);
2544404b540aSrobert 
2545404b540aSrobert 	      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
2546404b540aSrobert 		  && INTEGRAL_TYPE_P (type)
2547404b540aSrobert 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
2548404b540aSrobert 		parmval = default_conversion (parmval);
2549404b540aSrobert 	    }
2550404b540aSrobert 	  result = tree_cons (NULL_TREE, parmval, result);
2551404b540aSrobert 	}
2552404b540aSrobert       else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
2553404b540aSrobert 	       && (TYPE_PRECISION (TREE_TYPE (val))
2554404b540aSrobert 		   < TYPE_PRECISION (double_type_node))
2555404b540aSrobert 	       && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
2556404b540aSrobert 	/* Convert `float' to `double'.  */
2557404b540aSrobert 	result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
2558404b540aSrobert       else if ((invalid_func_diag =
2559404b540aSrobert 		targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
2560404b540aSrobert 	{
2561404b540aSrobert 	  error (invalid_func_diag);
2562404b540aSrobert 	  return error_mark_node;
2563404b540aSrobert 	}
2564404b540aSrobert       else
2565404b540aSrobert 	/* Convert `short' and `char' to full-size `int'.  */
2566404b540aSrobert 	result = tree_cons (NULL_TREE, default_conversion (val), result);
2567404b540aSrobert 
2568404b540aSrobert       if (typetail)
2569404b540aSrobert 	typetail = TREE_CHAIN (typetail);
2570404b540aSrobert     }
2571404b540aSrobert 
2572404b540aSrobert   if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
2573404b540aSrobert     {
2574404b540aSrobert       error ("too few arguments to function %qE", function);
2575404b540aSrobert       return error_mark_node;
2576404b540aSrobert     }
2577404b540aSrobert 
2578404b540aSrobert   return nreverse (result);
2579404b540aSrobert }
2580404b540aSrobert 
2581404b540aSrobert /* This is the entry point used by the parser to build unary operators
2582404b540aSrobert    in the input.  CODE, a tree_code, specifies the unary operator, and
2583404b540aSrobert    ARG is the operand.  For unary plus, the C parser currently uses
2584404b540aSrobert    CONVERT_EXPR for code.  */
2585404b540aSrobert 
2586404b540aSrobert struct c_expr
parser_build_unary_op(enum tree_code code,struct c_expr arg)2587404b540aSrobert parser_build_unary_op (enum tree_code code, struct c_expr arg)
2588404b540aSrobert {
2589404b540aSrobert   struct c_expr result;
2590404b540aSrobert 
2591404b540aSrobert   result.original_code = ERROR_MARK;
2592404b540aSrobert   result.value = build_unary_op (code, arg.value, 0);
2593404b540aSrobert   overflow_warning (result.value);
2594404b540aSrobert   return result;
2595404b540aSrobert }
2596404b540aSrobert 
2597404b540aSrobert /* This is the entry point used by the parser to build binary operators
2598404b540aSrobert    in the input.  CODE, a tree_code, specifies the binary operator, and
2599404b540aSrobert    ARG1 and ARG2 are the operands.  In addition to constructing the
2600404b540aSrobert    expression, we check for operands that were written with other binary
2601404b540aSrobert    operators in a way that is likely to confuse the user.  */
2602404b540aSrobert 
2603404b540aSrobert struct c_expr
parser_build_binary_op(enum tree_code code,struct c_expr arg1,struct c_expr arg2)2604404b540aSrobert parser_build_binary_op (enum tree_code code, struct c_expr arg1,
2605404b540aSrobert 			struct c_expr arg2)
2606404b540aSrobert {
2607404b540aSrobert   struct c_expr result;
2608404b540aSrobert 
2609404b540aSrobert   enum tree_code code1 = arg1.original_code;
2610404b540aSrobert   enum tree_code code2 = arg2.original_code;
2611404b540aSrobert 
2612404b540aSrobert   result.value = build_binary_op (code, arg1.value, arg2.value, 1);
2613404b540aSrobert   result.original_code = code;
2614404b540aSrobert 
2615404b540aSrobert   if (TREE_CODE (result.value) == ERROR_MARK)
2616404b540aSrobert     return result;
2617404b540aSrobert 
2618404b540aSrobert   /* Check for cases such as x+y<<z which users are likely
2619404b540aSrobert      to misinterpret.  */
2620404b540aSrobert   if (warn_parentheses)
2621404b540aSrobert     {
2622404b540aSrobert       if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
2623404b540aSrobert 	{
2624404b540aSrobert 	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
2625404b540aSrobert 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
2626404b540aSrobert 	    warning (OPT_Wparentheses,
2627404b540aSrobert 		     "suggest parentheses around + or - inside shift");
2628404b540aSrobert 	}
2629404b540aSrobert 
2630404b540aSrobert       if (code == TRUTH_ORIF_EXPR)
2631404b540aSrobert 	{
2632404b540aSrobert 	  if (code1 == TRUTH_ANDIF_EXPR
2633404b540aSrobert 	      || code2 == TRUTH_ANDIF_EXPR)
2634404b540aSrobert 	    warning (OPT_Wparentheses,
2635404b540aSrobert 		     "suggest parentheses around && within ||");
2636404b540aSrobert 	}
2637404b540aSrobert 
2638404b540aSrobert       if (code == BIT_IOR_EXPR)
2639404b540aSrobert 	{
2640404b540aSrobert 	  if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
2641404b540aSrobert 	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
2642404b540aSrobert 	      || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
2643404b540aSrobert 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
2644404b540aSrobert 	    warning (OPT_Wparentheses,
2645404b540aSrobert 		     "suggest parentheses around arithmetic in operand of |");
2646404b540aSrobert 	  /* Check cases like x|y==z */
2647404b540aSrobert 	  if (TREE_CODE_CLASS (code1) == tcc_comparison
2648404b540aSrobert 	      || TREE_CODE_CLASS (code2) == tcc_comparison)
2649404b540aSrobert 	    warning (OPT_Wparentheses,
2650404b540aSrobert 		     "suggest parentheses around comparison in operand of |");
2651404b540aSrobert 	}
2652404b540aSrobert 
2653404b540aSrobert       if (code == BIT_XOR_EXPR)
2654404b540aSrobert 	{
2655404b540aSrobert 	  if (code1 == BIT_AND_EXPR
2656404b540aSrobert 	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
2657404b540aSrobert 	      || code2 == BIT_AND_EXPR
2658404b540aSrobert 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
2659404b540aSrobert 	    warning (OPT_Wparentheses,
2660404b540aSrobert 		     "suggest parentheses around arithmetic in operand of ^");
2661404b540aSrobert 	  /* Check cases like x^y==z */
2662404b540aSrobert 	  if (TREE_CODE_CLASS (code1) == tcc_comparison
2663404b540aSrobert 	      || TREE_CODE_CLASS (code2) == tcc_comparison)
2664404b540aSrobert 	    warning (OPT_Wparentheses,
2665404b540aSrobert 		     "suggest parentheses around comparison in operand of ^");
2666404b540aSrobert 	}
2667404b540aSrobert 
2668404b540aSrobert       if (code == BIT_AND_EXPR)
2669404b540aSrobert 	{
2670404b540aSrobert 	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
2671404b540aSrobert 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
2672404b540aSrobert 	    warning (OPT_Wparentheses,
2673404b540aSrobert 		     "suggest parentheses around + or - in operand of &");
2674404b540aSrobert 	  /* Check cases like x&y==z */
2675404b540aSrobert 	  if (TREE_CODE_CLASS (code1) == tcc_comparison
2676404b540aSrobert 	      || TREE_CODE_CLASS (code2) == tcc_comparison)
2677404b540aSrobert 	    warning (OPT_Wparentheses,
2678404b540aSrobert 		     "suggest parentheses around comparison in operand of &");
2679404b540aSrobert 	}
2680404b540aSrobert       /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
2681404b540aSrobert       if (TREE_CODE_CLASS (code) == tcc_comparison
2682404b540aSrobert 	  && (TREE_CODE_CLASS (code1) == tcc_comparison
2683404b540aSrobert 	      || TREE_CODE_CLASS (code2) == tcc_comparison))
2684404b540aSrobert 	warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
2685404b540aSrobert 		 "have their mathematical meaning");
2686404b540aSrobert 
2687404b540aSrobert     }
2688404b540aSrobert 
2689404b540aSrobert   /* Warn about comparisons against string literals, with the exception
2690404b540aSrobert      of testing for equality or inequality of a string literal with NULL.  */
2691404b540aSrobert   if (code == EQ_EXPR || code == NE_EXPR)
2692404b540aSrobert     {
2693404b540aSrobert       if ((code1 == STRING_CST && !integer_zerop (arg2.value))
2694404b540aSrobert 	  || (code2 == STRING_CST && !integer_zerop (arg1.value)))
2695404b540aSrobert 	warning (OPT_Waddress,
2696404b540aSrobert                  "comparison with string literal results in unspecified behaviour");
2697404b540aSrobert     }
2698404b540aSrobert   else if (TREE_CODE_CLASS (code) == tcc_comparison
2699404b540aSrobert 	   && (code1 == STRING_CST || code2 == STRING_CST))
2700404b540aSrobert     warning (OPT_Waddress,
2701404b540aSrobert              "comparison with string literal results in unspecified behaviour");
2702404b540aSrobert 
2703404b540aSrobert   overflow_warning (result.value);
2704404b540aSrobert 
2705404b540aSrobert   return result;
2706404b540aSrobert }
2707404b540aSrobert 
2708404b540aSrobert /* Return a tree for the difference of pointers OP0 and OP1.
2709404b540aSrobert    The resulting tree has type int.  */
2710404b540aSrobert 
2711404b540aSrobert static tree
pointer_diff(tree op0,tree op1)2712404b540aSrobert pointer_diff (tree op0, tree op1)
2713404b540aSrobert {
2714404b540aSrobert   tree restype = ptrdiff_type_node;
2715404b540aSrobert 
2716404b540aSrobert   tree target_type = TREE_TYPE (TREE_TYPE (op0));
2717404b540aSrobert   tree con0, con1, lit0, lit1;
2718404b540aSrobert   tree orig_op1 = op1;
2719404b540aSrobert 
2720404b540aSrobert   if (pedantic || warn_pointer_arith)
2721404b540aSrobert     {
2722404b540aSrobert       if (TREE_CODE (target_type) == VOID_TYPE)
2723404b540aSrobert 	pedwarn ("pointer of type %<void *%> used in subtraction");
2724404b540aSrobert       if (TREE_CODE (target_type) == FUNCTION_TYPE)
2725404b540aSrobert 	pedwarn ("pointer to a function used in subtraction");
2726404b540aSrobert     }
2727404b540aSrobert 
2728404b540aSrobert   /* If the conversion to ptrdiff_type does anything like widening or
2729404b540aSrobert      converting a partial to an integral mode, we get a convert_expression
2730404b540aSrobert      that is in the way to do any simplifications.
2731404b540aSrobert      (fold-const.c doesn't know that the extra bits won't be needed.
2732404b540aSrobert      split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
2733404b540aSrobert      different mode in place.)
2734404b540aSrobert      So first try to find a common term here 'by hand'; we want to cover
2735404b540aSrobert      at least the cases that occur in legal static initializers.  */
2736404b540aSrobert   if ((TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == CONVERT_EXPR)
2737404b540aSrobert       && (TYPE_PRECISION (TREE_TYPE (op0))
2738404b540aSrobert 	  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
2739404b540aSrobert     con0 = TREE_OPERAND (op0, 0);
2740404b540aSrobert   else
2741404b540aSrobert     con0 = op0;
2742404b540aSrobert   if ((TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == CONVERT_EXPR)
2743404b540aSrobert       && (TYPE_PRECISION (TREE_TYPE (op1))
2744404b540aSrobert 	  == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
2745404b540aSrobert     con1 = TREE_OPERAND (op1, 0);
2746404b540aSrobert   else
2747404b540aSrobert     con1 = op1;
2748404b540aSrobert 
2749404b540aSrobert   if (TREE_CODE (con0) == PLUS_EXPR)
2750404b540aSrobert     {
2751404b540aSrobert       lit0 = TREE_OPERAND (con0, 1);
2752404b540aSrobert       con0 = TREE_OPERAND (con0, 0);
2753404b540aSrobert     }
2754404b540aSrobert   else
2755404b540aSrobert     lit0 = integer_zero_node;
2756404b540aSrobert 
2757404b540aSrobert   if (TREE_CODE (con1) == PLUS_EXPR)
2758404b540aSrobert     {
2759404b540aSrobert       lit1 = TREE_OPERAND (con1, 1);
2760404b540aSrobert       con1 = TREE_OPERAND (con1, 0);
2761404b540aSrobert     }
2762404b540aSrobert   else
2763404b540aSrobert     lit1 = integer_zero_node;
2764404b540aSrobert 
2765404b540aSrobert   if (operand_equal_p (con0, con1, 0))
2766404b540aSrobert     {
2767404b540aSrobert       op0 = lit0;
2768404b540aSrobert       op1 = lit1;
2769404b540aSrobert     }
2770404b540aSrobert 
2771404b540aSrobert 
2772404b540aSrobert   /* First do the subtraction as integers;
2773404b540aSrobert      then drop through to build the divide operator.
2774404b540aSrobert      Do not do default conversions on the minus operator
2775404b540aSrobert      in case restype is a short type.  */
2776404b540aSrobert 
2777404b540aSrobert   op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
2778404b540aSrobert 			 convert (restype, op1), 0);
2779404b540aSrobert   /* This generates an error if op1 is pointer to incomplete type.  */
2780404b540aSrobert   if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
2781404b540aSrobert     error ("arithmetic on pointer to an incomplete type");
2782404b540aSrobert 
2783404b540aSrobert   /* This generates an error if op0 is pointer to incomplete type.  */
2784404b540aSrobert   op1 = c_size_in_bytes (target_type);
2785404b540aSrobert 
2786404b540aSrobert   /* Divide by the size, in easiest possible way.  */
2787404b540aSrobert   return fold_build2 (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
2788404b540aSrobert }
2789404b540aSrobert 
2790404b540aSrobert /* Construct and perhaps optimize a tree representation
2791404b540aSrobert    for a unary operation.  CODE, a tree_code, specifies the operation
2792404b540aSrobert    and XARG is the operand.
2793404b540aSrobert    For any CODE other than ADDR_EXPR, FLAG nonzero suppresses
2794404b540aSrobert    the default promotions (such as from short to int).
2795404b540aSrobert    For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
2796404b540aSrobert    allows non-lvalues; this is only used to handle conversion of non-lvalue
2797404b540aSrobert    arrays to pointers in C99.  */
2798404b540aSrobert 
2799404b540aSrobert tree
build_unary_op(enum tree_code code,tree xarg,int flag)2800404b540aSrobert build_unary_op (enum tree_code code, tree xarg, int flag)
2801404b540aSrobert {
2802404b540aSrobert   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
2803404b540aSrobert   tree arg = xarg;
2804404b540aSrobert   tree argtype = 0;
2805404b540aSrobert   enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
2806404b540aSrobert   tree val;
2807404b540aSrobert   int noconvert = flag;
2808404b540aSrobert   const char *invalid_op_diag;
2809404b540aSrobert 
2810404b540aSrobert   if (typecode == ERROR_MARK)
2811404b540aSrobert     return error_mark_node;
2812404b540aSrobert   if (typecode == ENUMERAL_TYPE || typecode == BOOLEAN_TYPE)
2813404b540aSrobert     typecode = INTEGER_TYPE;
2814404b540aSrobert 
2815404b540aSrobert   if ((invalid_op_diag
2816404b540aSrobert        = targetm.invalid_unary_op (code, TREE_TYPE (xarg))))
2817404b540aSrobert     {
2818404b540aSrobert       error (invalid_op_diag);
2819404b540aSrobert       return error_mark_node;
2820404b540aSrobert     }
2821404b540aSrobert 
2822404b540aSrobert   switch (code)
2823404b540aSrobert     {
2824404b540aSrobert     case CONVERT_EXPR:
2825404b540aSrobert       /* This is used for unary plus, because a CONVERT_EXPR
2826404b540aSrobert 	 is enough to prevent anybody from looking inside for
2827404b540aSrobert 	 associativity, but won't generate any code.  */
2828404b540aSrobert       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
2829404b540aSrobert 	    || typecode == COMPLEX_TYPE
2830404b540aSrobert 	    || typecode == VECTOR_TYPE))
2831404b540aSrobert 	{
2832404b540aSrobert 	  error ("wrong type argument to unary plus");
2833404b540aSrobert 	  return error_mark_node;
2834404b540aSrobert 	}
2835404b540aSrobert       else if (!noconvert)
2836404b540aSrobert 	arg = default_conversion (arg);
2837404b540aSrobert       arg = non_lvalue (arg);
2838404b540aSrobert       break;
2839404b540aSrobert 
2840404b540aSrobert     case NEGATE_EXPR:
2841404b540aSrobert       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
2842404b540aSrobert 	    || typecode == COMPLEX_TYPE
2843404b540aSrobert 	    || typecode == VECTOR_TYPE))
2844404b540aSrobert 	{
2845404b540aSrobert 	  error ("wrong type argument to unary minus");
2846404b540aSrobert 	  return error_mark_node;
2847404b540aSrobert 	}
2848404b540aSrobert       else if (!noconvert)
2849404b540aSrobert 	arg = default_conversion (arg);
2850404b540aSrobert       break;
2851404b540aSrobert 
2852404b540aSrobert     case BIT_NOT_EXPR:
2853404b540aSrobert       if (typecode == INTEGER_TYPE || typecode == VECTOR_TYPE)
2854404b540aSrobert 	{
2855404b540aSrobert 	  if (!noconvert)
2856404b540aSrobert 	    arg = default_conversion (arg);
2857404b540aSrobert 	}
2858404b540aSrobert       else if (typecode == COMPLEX_TYPE)
2859404b540aSrobert 	{
2860404b540aSrobert 	  code = CONJ_EXPR;
2861404b540aSrobert 	  if (pedantic)
2862404b540aSrobert 	    pedwarn ("ISO C does not support %<~%> for complex conjugation");
2863404b540aSrobert 	  if (!noconvert)
2864404b540aSrobert 	    arg = default_conversion (arg);
2865404b540aSrobert 	}
2866404b540aSrobert       else
2867404b540aSrobert 	{
2868404b540aSrobert 	  error ("wrong type argument to bit-complement");
2869404b540aSrobert 	  return error_mark_node;
2870404b540aSrobert 	}
2871404b540aSrobert       break;
2872404b540aSrobert 
2873404b540aSrobert     case ABS_EXPR:
2874404b540aSrobert       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
2875404b540aSrobert 	{
2876404b540aSrobert 	  error ("wrong type argument to abs");
2877404b540aSrobert 	  return error_mark_node;
2878404b540aSrobert 	}
2879404b540aSrobert       else if (!noconvert)
2880404b540aSrobert 	arg = default_conversion (arg);
2881404b540aSrobert       break;
2882404b540aSrobert 
2883404b540aSrobert     case CONJ_EXPR:
2884404b540aSrobert       /* Conjugating a real value is a no-op, but allow it anyway.  */
2885404b540aSrobert       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
2886404b540aSrobert 	    || typecode == COMPLEX_TYPE))
2887404b540aSrobert 	{
2888404b540aSrobert 	  error ("wrong type argument to conjugation");
2889404b540aSrobert 	  return error_mark_node;
2890404b540aSrobert 	}
2891404b540aSrobert       else if (!noconvert)
2892404b540aSrobert 	arg = default_conversion (arg);
2893404b540aSrobert       break;
2894404b540aSrobert 
2895404b540aSrobert     case TRUTH_NOT_EXPR:
2896404b540aSrobert       if (typecode != INTEGER_TYPE
2897404b540aSrobert 	  && typecode != REAL_TYPE && typecode != POINTER_TYPE
2898404b540aSrobert 	  && typecode != COMPLEX_TYPE)
2899404b540aSrobert 	{
2900404b540aSrobert 	  error ("wrong type argument to unary exclamation mark");
2901404b540aSrobert 	  return error_mark_node;
2902404b540aSrobert 	}
2903404b540aSrobert       arg = c_objc_common_truthvalue_conversion (arg);
2904404b540aSrobert       return invert_truthvalue (arg);
2905404b540aSrobert 
2906404b540aSrobert     case REALPART_EXPR:
2907404b540aSrobert       if (TREE_CODE (arg) == COMPLEX_CST)
2908404b540aSrobert 	return TREE_REALPART (arg);
2909404b540aSrobert       else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
2910404b540aSrobert 	return fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
2911404b540aSrobert       else
2912404b540aSrobert 	return arg;
2913404b540aSrobert 
2914404b540aSrobert     case IMAGPART_EXPR:
2915404b540aSrobert       if (TREE_CODE (arg) == COMPLEX_CST)
2916404b540aSrobert 	return TREE_IMAGPART (arg);
2917404b540aSrobert       else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
2918404b540aSrobert 	return fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
2919404b540aSrobert       else
2920404b540aSrobert 	return convert (TREE_TYPE (arg), integer_zero_node);
2921404b540aSrobert 
2922404b540aSrobert     case PREINCREMENT_EXPR:
2923404b540aSrobert     case POSTINCREMENT_EXPR:
2924404b540aSrobert     case PREDECREMENT_EXPR:
2925404b540aSrobert     case POSTDECREMENT_EXPR:
2926404b540aSrobert 
2927404b540aSrobert       /* Increment or decrement the real part of the value,
2928404b540aSrobert 	 and don't change the imaginary part.  */
2929404b540aSrobert       if (typecode == COMPLEX_TYPE)
2930404b540aSrobert 	{
2931404b540aSrobert 	  tree real, imag;
2932404b540aSrobert 
2933404b540aSrobert 	  if (pedantic)
2934404b540aSrobert 	    pedwarn ("ISO C does not support %<++%> and %<--%>"
2935404b540aSrobert 		     " on complex types");
2936404b540aSrobert 
2937404b540aSrobert 	  arg = stabilize_reference (arg);
2938404b540aSrobert 	  real = build_unary_op (REALPART_EXPR, arg, 1);
2939404b540aSrobert 	  imag = build_unary_op (IMAGPART_EXPR, arg, 1);
2940404b540aSrobert 	  return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
2941404b540aSrobert 			 build_unary_op (code, real, 1), imag);
2942404b540aSrobert 	}
2943404b540aSrobert 
2944404b540aSrobert       /* Report invalid types.  */
2945404b540aSrobert 
2946404b540aSrobert       if (typecode != POINTER_TYPE
2947404b540aSrobert 	  && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
2948404b540aSrobert 	{
2949404b540aSrobert 	  if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2950404b540aSrobert 	    error ("wrong type argument to increment");
2951404b540aSrobert 	  else
2952404b540aSrobert 	    error ("wrong type argument to decrement");
2953404b540aSrobert 
2954404b540aSrobert 	  return error_mark_node;
2955404b540aSrobert 	}
2956404b540aSrobert 
2957404b540aSrobert       {
2958404b540aSrobert 	tree inc;
2959404b540aSrobert 	tree result_type = TREE_TYPE (arg);
2960404b540aSrobert 
2961404b540aSrobert 	arg = get_unwidened (arg, 0);
2962404b540aSrobert 	argtype = TREE_TYPE (arg);
2963404b540aSrobert 
2964404b540aSrobert 	/* Compute the increment.  */
2965404b540aSrobert 
2966404b540aSrobert 	if (typecode == POINTER_TYPE)
2967404b540aSrobert 	  {
2968404b540aSrobert 	    /* If pointer target is an undefined struct,
2969404b540aSrobert 	       we just cannot know how to do the arithmetic.  */
2970404b540aSrobert 	    if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
2971404b540aSrobert 	      {
2972404b540aSrobert 		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2973404b540aSrobert 		  error ("increment of pointer to unknown structure");
2974404b540aSrobert 		else
2975404b540aSrobert 		  error ("decrement of pointer to unknown structure");
2976404b540aSrobert 	      }
2977404b540aSrobert 	    else if ((pedantic || warn_pointer_arith)
2978404b540aSrobert 		     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
2979404b540aSrobert 			 || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
2980404b540aSrobert 	      {
2981404b540aSrobert 		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
2982404b540aSrobert 		  pedwarn ("wrong type argument to increment");
2983404b540aSrobert 		else
2984404b540aSrobert 		  pedwarn ("wrong type argument to decrement");
2985404b540aSrobert 	      }
2986404b540aSrobert 
2987404b540aSrobert 	    inc = c_size_in_bytes (TREE_TYPE (result_type));
2988404b540aSrobert 	  }
2989404b540aSrobert 	else
2990404b540aSrobert 	  inc = integer_one_node;
2991404b540aSrobert 
2992404b540aSrobert 	inc = convert (argtype, inc);
2993404b540aSrobert 
2994404b540aSrobert 	/* Complain about anything else that is not a true lvalue.  */
2995404b540aSrobert 	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
2996404b540aSrobert 				    || code == POSTINCREMENT_EXPR)
2997404b540aSrobert 				   ? lv_increment
2998404b540aSrobert 				   : lv_decrement)))
2999404b540aSrobert 	  return error_mark_node;
3000404b540aSrobert 
3001404b540aSrobert 	/* Report a read-only lvalue.  */
3002404b540aSrobert 	if (TREE_READONLY (arg))
3003404b540aSrobert 	  {
3004404b540aSrobert 	    readonly_error (arg,
3005404b540aSrobert 			    ((code == PREINCREMENT_EXPR
3006404b540aSrobert 			      || code == POSTINCREMENT_EXPR)
3007404b540aSrobert 			     ? lv_increment : lv_decrement));
3008404b540aSrobert 	    return error_mark_node;
3009404b540aSrobert 	  }
3010404b540aSrobert 
3011404b540aSrobert 	if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
3012404b540aSrobert 	  val = boolean_increment (code, arg);
3013404b540aSrobert 	else
3014404b540aSrobert 	  val = build2 (code, TREE_TYPE (arg), arg, inc);
3015404b540aSrobert 	TREE_SIDE_EFFECTS (val) = 1;
3016404b540aSrobert 	val = convert (result_type, val);
3017404b540aSrobert 	if (TREE_CODE (val) != code)
3018404b540aSrobert 	  TREE_NO_WARNING (val) = 1;
3019404b540aSrobert 	return val;
3020404b540aSrobert       }
3021404b540aSrobert 
3022404b540aSrobert     case ADDR_EXPR:
3023404b540aSrobert       /* Note that this operation never does default_conversion.  */
3024404b540aSrobert 
3025404b540aSrobert       /* Let &* cancel out to simplify resulting code.  */
3026404b540aSrobert       if (TREE_CODE (arg) == INDIRECT_REF)
3027404b540aSrobert 	{
3028404b540aSrobert 	  /* Don't let this be an lvalue.  */
3029404b540aSrobert 	  if (lvalue_p (TREE_OPERAND (arg, 0)))
3030404b540aSrobert 	    return non_lvalue (TREE_OPERAND (arg, 0));
3031404b540aSrobert 	  return TREE_OPERAND (arg, 0);
3032404b540aSrobert 	}
3033404b540aSrobert 
3034404b540aSrobert       /* For &x[y], return x+y */
3035404b540aSrobert       if (TREE_CODE (arg) == ARRAY_REF)
3036404b540aSrobert 	{
3037404b540aSrobert 	  tree op0 = TREE_OPERAND (arg, 0);
3038404b540aSrobert 	  if (!c_mark_addressable (op0))
3039404b540aSrobert 	    return error_mark_node;
3040404b540aSrobert 	  return build_binary_op (PLUS_EXPR,
3041404b540aSrobert 				  (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
3042404b540aSrobert 				   ? array_to_pointer_conversion (op0)
3043404b540aSrobert 				   : op0),
3044404b540aSrobert 				  TREE_OPERAND (arg, 1), 1);
3045404b540aSrobert 	}
3046404b540aSrobert 
3047404b540aSrobert       /* Anything not already handled and not a true memory reference
3048404b540aSrobert 	 or a non-lvalue array is an error.  */
3049404b540aSrobert       else if (typecode != FUNCTION_TYPE && !flag
3050404b540aSrobert 	       && !lvalue_or_else (arg, lv_addressof))
3051404b540aSrobert 	return error_mark_node;
3052404b540aSrobert 
3053404b540aSrobert       /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
3054404b540aSrobert       argtype = TREE_TYPE (arg);
3055404b540aSrobert 
3056404b540aSrobert       /* If the lvalue is const or volatile, merge that into the type
3057404b540aSrobert 	 to which the address will point.  Note that you can't get a
3058404b540aSrobert 	 restricted pointer by taking the address of something, so we
3059404b540aSrobert 	 only have to deal with `const' and `volatile' here.  */
3060404b540aSrobert       if ((DECL_P (arg) || REFERENCE_CLASS_P (arg))
3061404b540aSrobert 	  && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)))
3062404b540aSrobert 	  argtype = c_build_type_variant (argtype,
3063404b540aSrobert 					  TREE_READONLY (arg),
3064404b540aSrobert 					  TREE_THIS_VOLATILE (arg));
3065404b540aSrobert 
3066404b540aSrobert       if (!c_mark_addressable (arg))
3067404b540aSrobert 	return error_mark_node;
3068404b540aSrobert 
3069404b540aSrobert       gcc_assert (TREE_CODE (arg) != COMPONENT_REF
3070404b540aSrobert 		  || !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)));
3071404b540aSrobert 
3072404b540aSrobert       argtype = build_pointer_type (argtype);
3073404b540aSrobert 
3074404b540aSrobert       /* ??? Cope with user tricks that amount to offsetof.  Delete this
3075404b540aSrobert 	 when we have proper support for integer constant expressions.  */
3076404b540aSrobert       val = get_base_address (arg);
3077404b540aSrobert       if (val && TREE_CODE (val) == INDIRECT_REF
3078404b540aSrobert           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
3079404b540aSrobert 	{
3080404b540aSrobert 	  tree op0 = fold_convert (argtype, fold_offsetof (arg, val)), op1;
3081404b540aSrobert 
3082404b540aSrobert 	  op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
3083404b540aSrobert 	  return fold_build2 (PLUS_EXPR, argtype, op0, op1);
3084404b540aSrobert 	}
3085404b540aSrobert 
3086404b540aSrobert       val = build1 (ADDR_EXPR, argtype, arg);
3087404b540aSrobert 
3088404b540aSrobert       return val;
3089404b540aSrobert 
3090404b540aSrobert     default:
3091404b540aSrobert       gcc_unreachable ();
3092404b540aSrobert     }
3093404b540aSrobert 
3094404b540aSrobert   if (argtype == 0)
3095404b540aSrobert     argtype = TREE_TYPE (arg);
3096404b540aSrobert   return require_constant_value ? fold_build1_initializer (code, argtype, arg)
3097404b540aSrobert 				: fold_build1 (code, argtype, arg);
3098404b540aSrobert }
3099404b540aSrobert 
3100404b540aSrobert /* Return nonzero if REF is an lvalue valid for this language.
3101404b540aSrobert    Lvalues can be assigned, unless their type has TYPE_READONLY.
3102404b540aSrobert    Lvalues can have their address taken, unless they have C_DECL_REGISTER.  */
3103404b540aSrobert 
3104404b540aSrobert static int
lvalue_p(tree ref)3105404b540aSrobert lvalue_p (tree ref)
3106404b540aSrobert {
3107404b540aSrobert   enum tree_code code = TREE_CODE (ref);
3108404b540aSrobert 
3109404b540aSrobert   switch (code)
3110404b540aSrobert     {
3111404b540aSrobert     case REALPART_EXPR:
3112404b540aSrobert     case IMAGPART_EXPR:
3113404b540aSrobert     case COMPONENT_REF:
3114404b540aSrobert       return lvalue_p (TREE_OPERAND (ref, 0));
3115404b540aSrobert 
3116404b540aSrobert     case COMPOUND_LITERAL_EXPR:
3117404b540aSrobert     case STRING_CST:
3118404b540aSrobert       return 1;
3119404b540aSrobert 
3120404b540aSrobert     case INDIRECT_REF:
3121404b540aSrobert     case ARRAY_REF:
3122404b540aSrobert     case VAR_DECL:
3123404b540aSrobert     case PARM_DECL:
3124404b540aSrobert     case RESULT_DECL:
3125404b540aSrobert     case ERROR_MARK:
3126404b540aSrobert       return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
3127404b540aSrobert 	      && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
3128404b540aSrobert 
3129404b540aSrobert     case BIND_EXPR:
3130404b540aSrobert       return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
3131404b540aSrobert 
3132404b540aSrobert     default:
3133404b540aSrobert       return 0;
3134404b540aSrobert     }
3135404b540aSrobert }
3136404b540aSrobert 
3137404b540aSrobert /* Give an error for storing in something that is 'const'.  */
3138404b540aSrobert 
3139404b540aSrobert static void
readonly_error(tree arg,enum lvalue_use use)3140404b540aSrobert readonly_error (tree arg, enum lvalue_use use)
3141404b540aSrobert {
3142404b540aSrobert   gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement
3143404b540aSrobert 	      || use == lv_asm);
3144404b540aSrobert   /* Using this macro rather than (for example) arrays of messages
3145404b540aSrobert      ensures that all the format strings are checked at compile
3146404b540aSrobert      time.  */
3147404b540aSrobert #define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A)		\
3148404b540aSrobert 				   : (use == lv_increment ? (I)		\
3149404b540aSrobert 				   : (use == lv_decrement ? (D) : (AS))))
3150404b540aSrobert   if (TREE_CODE (arg) == COMPONENT_REF)
3151404b540aSrobert     {
3152404b540aSrobert       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
3153404b540aSrobert 	readonly_error (TREE_OPERAND (arg, 0), use);
3154404b540aSrobert       else
3155404b540aSrobert 	error (READONLY_MSG (G_("assignment of read-only member %qD"),
3156404b540aSrobert 			     G_("increment of read-only member %qD"),
3157404b540aSrobert 			     G_("decrement of read-only member %qD"),
3158404b540aSrobert 			     G_("read-only member %qD used as %<asm%> output")),
3159404b540aSrobert 	       TREE_OPERAND (arg, 1));
3160404b540aSrobert     }
3161404b540aSrobert   else if (TREE_CODE (arg) == VAR_DECL)
3162404b540aSrobert     error (READONLY_MSG (G_("assignment of read-only variable %qD"),
3163404b540aSrobert 			 G_("increment of read-only variable %qD"),
3164404b540aSrobert 			 G_("decrement of read-only variable %qD"),
3165404b540aSrobert 			 G_("read-only variable %qD used as %<asm%> output")),
3166404b540aSrobert 	   arg);
3167404b540aSrobert   else
3168404b540aSrobert     error (READONLY_MSG (G_("assignment of read-only location"),
3169404b540aSrobert 			 G_("increment of read-only location"),
3170404b540aSrobert 			 G_("decrement of read-only location"),
3171404b540aSrobert 			 G_("read-only location used as %<asm%> output")));
3172404b540aSrobert }
3173404b540aSrobert 
3174404b540aSrobert 
3175404b540aSrobert /* Return nonzero if REF is an lvalue valid for this language;
3176404b540aSrobert    otherwise, print an error message and return zero.  USE says
3177404b540aSrobert    how the lvalue is being used and so selects the error message.  */
3178404b540aSrobert 
3179404b540aSrobert static int
lvalue_or_else(tree ref,enum lvalue_use use)3180404b540aSrobert lvalue_or_else (tree ref, enum lvalue_use use)
3181404b540aSrobert {
3182404b540aSrobert   int win = lvalue_p (ref);
3183404b540aSrobert 
3184404b540aSrobert   if (!win)
3185404b540aSrobert     lvalue_error (use);
3186404b540aSrobert 
3187404b540aSrobert   return win;
3188404b540aSrobert }
3189404b540aSrobert 
3190404b540aSrobert /* Mark EXP saying that we need to be able to take the
3191404b540aSrobert    address of it; it should not be allocated in a register.
3192404b540aSrobert    Returns true if successful.  */
3193404b540aSrobert 
3194404b540aSrobert bool
c_mark_addressable(tree exp)3195404b540aSrobert c_mark_addressable (tree exp)
3196404b540aSrobert {
3197404b540aSrobert   tree x = exp;
3198404b540aSrobert 
3199404b540aSrobert   while (1)
3200404b540aSrobert     switch (TREE_CODE (x))
3201404b540aSrobert       {
3202404b540aSrobert       case COMPONENT_REF:
3203404b540aSrobert 	if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
3204404b540aSrobert 	  {
3205404b540aSrobert 	    error
3206404b540aSrobert 	      ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1));
3207404b540aSrobert 	    return false;
3208404b540aSrobert 	  }
3209404b540aSrobert 
3210404b540aSrobert 	/* ... fall through ...  */
3211404b540aSrobert 
3212404b540aSrobert       case ADDR_EXPR:
3213404b540aSrobert       case ARRAY_REF:
3214404b540aSrobert       case REALPART_EXPR:
3215404b540aSrobert       case IMAGPART_EXPR:
3216404b540aSrobert 	x = TREE_OPERAND (x, 0);
3217404b540aSrobert 	break;
3218404b540aSrobert 
3219404b540aSrobert       case COMPOUND_LITERAL_EXPR:
3220404b540aSrobert       case CONSTRUCTOR:
3221404b540aSrobert 	TREE_ADDRESSABLE (x) = 1;
3222404b540aSrobert 	return true;
3223404b540aSrobert 
3224404b540aSrobert       case VAR_DECL:
3225404b540aSrobert       case CONST_DECL:
3226404b540aSrobert       case PARM_DECL:
3227404b540aSrobert       case RESULT_DECL:
3228404b540aSrobert 	if (C_DECL_REGISTER (x)
3229404b540aSrobert 	    && DECL_NONLOCAL (x))
3230404b540aSrobert 	  {
3231404b540aSrobert 	    if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
3232404b540aSrobert 	      {
3233404b540aSrobert 		error
3234404b540aSrobert 		  ("global register variable %qD used in nested function", x);
3235404b540aSrobert 		return false;
3236404b540aSrobert 	      }
3237404b540aSrobert 	    pedwarn ("register variable %qD used in nested function", x);
3238404b540aSrobert 	  }
3239404b540aSrobert 	else if (C_DECL_REGISTER (x))
3240404b540aSrobert 	  {
3241404b540aSrobert 	    if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
3242404b540aSrobert 	      error ("address of global register variable %qD requested", x);
3243404b540aSrobert 	    else
3244404b540aSrobert 	      error ("address of register variable %qD requested", x);
3245404b540aSrobert 	    return false;
3246404b540aSrobert 	  }
3247404b540aSrobert 
3248404b540aSrobert 	/* drops in */
3249404b540aSrobert       case FUNCTION_DECL:
3250404b540aSrobert 	TREE_ADDRESSABLE (x) = 1;
3251404b540aSrobert 	/* drops out */
3252404b540aSrobert       default:
3253404b540aSrobert 	return true;
3254404b540aSrobert     }
3255404b540aSrobert }
3256404b540aSrobert 
3257404b540aSrobert /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
3258404b540aSrobert 
3259404b540aSrobert tree
build_conditional_expr(tree ifexp,tree op1,tree op2)3260404b540aSrobert build_conditional_expr (tree ifexp, tree op1, tree op2)
3261404b540aSrobert {
3262404b540aSrobert   tree type1;
3263404b540aSrobert   tree type2;
3264404b540aSrobert   enum tree_code code1;
3265404b540aSrobert   enum tree_code code2;
3266404b540aSrobert   tree result_type = NULL;
3267404b540aSrobert   tree orig_op1 = op1, orig_op2 = op2;
3268404b540aSrobert 
3269404b540aSrobert   /* Promote both alternatives.  */
3270404b540aSrobert 
3271404b540aSrobert   if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
3272404b540aSrobert     op1 = default_conversion (op1);
3273404b540aSrobert   if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
3274404b540aSrobert     op2 = default_conversion (op2);
3275404b540aSrobert 
3276404b540aSrobert   if (TREE_CODE (ifexp) == ERROR_MARK
3277404b540aSrobert       || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
3278404b540aSrobert       || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
3279404b540aSrobert     return error_mark_node;
3280404b540aSrobert 
3281404b540aSrobert   type1 = TREE_TYPE (op1);
3282404b540aSrobert   code1 = TREE_CODE (type1);
3283404b540aSrobert   type2 = TREE_TYPE (op2);
3284404b540aSrobert   code2 = TREE_CODE (type2);
3285404b540aSrobert 
3286404b540aSrobert   /* C90 does not permit non-lvalue arrays in conditional expressions.
3287404b540aSrobert      In C99 they will be pointers by now.  */
3288404b540aSrobert   if (code1 == ARRAY_TYPE || code2 == ARRAY_TYPE)
3289404b540aSrobert     {
3290404b540aSrobert       error ("non-lvalue array in conditional expression");
3291404b540aSrobert       return error_mark_node;
3292404b540aSrobert     }
3293404b540aSrobert 
3294404b540aSrobert   /* Quickly detect the usual case where op1 and op2 have the same type
3295404b540aSrobert      after promotion.  */
3296404b540aSrobert   if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
3297404b540aSrobert     {
3298404b540aSrobert       if (type1 == type2)
3299404b540aSrobert 	result_type = type1;
3300404b540aSrobert       else
3301404b540aSrobert 	result_type = TYPE_MAIN_VARIANT (type1);
3302404b540aSrobert     }
3303404b540aSrobert   else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE
3304404b540aSrobert 	    || code1 == COMPLEX_TYPE)
3305404b540aSrobert 	   && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
3306404b540aSrobert 	       || code2 == COMPLEX_TYPE))
3307404b540aSrobert     {
3308404b540aSrobert       result_type = c_common_type (type1, type2);
3309404b540aSrobert 
3310404b540aSrobert       /* If -Wsign-compare, warn here if type1 and type2 have
3311404b540aSrobert 	 different signedness.  We'll promote the signed to unsigned
3312404b540aSrobert 	 and later code won't know it used to be different.
3313404b540aSrobert 	 Do this check on the original types, so that explicit casts
3314404b540aSrobert 	 will be considered, but default promotions won't.  */
3315404b540aSrobert       if (warn_sign_compare && !skip_evaluation)
3316404b540aSrobert 	{
3317404b540aSrobert 	  int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1));
3318404b540aSrobert 	  int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2));
3319404b540aSrobert 
3320404b540aSrobert 	  if (unsigned_op1 ^ unsigned_op2)
3321404b540aSrobert 	    {
3322404b540aSrobert 	      bool ovf;
3323404b540aSrobert 
3324404b540aSrobert 	      /* Do not warn if the result type is signed, since the
3325404b540aSrobert 		 signed type will only be chosen if it can represent
3326404b540aSrobert 		 all the values of the unsigned type.  */
3327404b540aSrobert 	      if (!TYPE_UNSIGNED (result_type))
3328404b540aSrobert 		/* OK */;
3329404b540aSrobert 	      /* Do not warn if the signed quantity is an unsuffixed
3330404b540aSrobert 		 integer literal (or some static constant expression
3331404b540aSrobert 		 involving such literals) and it is non-negative.  */
3332404b540aSrobert 	      else if ((unsigned_op2
3333404b540aSrobert 			&& tree_expr_nonnegative_warnv_p (op1, &ovf))
3334404b540aSrobert 		       || (unsigned_op1
3335404b540aSrobert 			   && tree_expr_nonnegative_warnv_p (op2, &ovf)))
3336404b540aSrobert 		/* OK */;
3337404b540aSrobert 	      else
3338404b540aSrobert 		warning (0, "signed and unsigned type in conditional expression");
3339404b540aSrobert 	    }
3340404b540aSrobert 	}
3341404b540aSrobert     }
3342404b540aSrobert   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
3343404b540aSrobert     {
3344404b540aSrobert       if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
3345404b540aSrobert 	pedwarn ("ISO C forbids conditional expr with only one void side");
3346404b540aSrobert       result_type = void_type_node;
3347404b540aSrobert     }
3348404b540aSrobert   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
3349404b540aSrobert     {
3350404b540aSrobert       if (comp_target_types (type1, type2))
3351404b540aSrobert 	result_type = common_pointer_type (type1, type2);
3352404b540aSrobert       else if (null_pointer_constant_p (orig_op1))
3353404b540aSrobert 	result_type = qualify_type (type2, type1);
3354404b540aSrobert       else if (null_pointer_constant_p (orig_op2))
3355404b540aSrobert 	result_type = qualify_type (type1, type2);
3356404b540aSrobert       else if (VOID_TYPE_P (TREE_TYPE (type1)))
3357404b540aSrobert 	{
3358404b540aSrobert 	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
3359404b540aSrobert 	    pedwarn ("ISO C forbids conditional expr between "
3360404b540aSrobert 		     "%<void *%> and function pointer");
3361404b540aSrobert 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
3362404b540aSrobert 							  TREE_TYPE (type2)));
3363404b540aSrobert 	}
3364404b540aSrobert       else if (VOID_TYPE_P (TREE_TYPE (type2)))
3365404b540aSrobert 	{
3366404b540aSrobert 	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
3367404b540aSrobert 	    pedwarn ("ISO C forbids conditional expr between "
3368404b540aSrobert 		     "%<void *%> and function pointer");
3369404b540aSrobert 	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
3370404b540aSrobert 							  TREE_TYPE (type1)));
3371404b540aSrobert 	}
3372404b540aSrobert       else
3373404b540aSrobert 	{
3374404b540aSrobert 	  pedwarn ("pointer type mismatch in conditional expression");
3375404b540aSrobert 	  result_type = build_pointer_type (void_type_node);
3376404b540aSrobert 	}
3377404b540aSrobert     }
3378404b540aSrobert   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
3379404b540aSrobert     {
3380404b540aSrobert       if (!null_pointer_constant_p (orig_op2))
3381404b540aSrobert 	pedwarn ("pointer/integer type mismatch in conditional expression");
3382404b540aSrobert       else
3383404b540aSrobert 	{
3384404b540aSrobert 	  op2 = null_pointer_node;
3385404b540aSrobert 	}
3386404b540aSrobert       result_type = type1;
3387404b540aSrobert     }
3388404b540aSrobert   else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
3389404b540aSrobert     {
3390404b540aSrobert       if (!null_pointer_constant_p (orig_op1))
3391404b540aSrobert 	pedwarn ("pointer/integer type mismatch in conditional expression");
3392404b540aSrobert       else
3393404b540aSrobert 	{
3394404b540aSrobert 	  op1 = null_pointer_node;
3395404b540aSrobert 	}
3396404b540aSrobert       result_type = type2;
3397404b540aSrobert     }
3398404b540aSrobert 
3399404b540aSrobert   if (!result_type)
3400404b540aSrobert     {
3401404b540aSrobert       if (flag_cond_mismatch)
3402404b540aSrobert 	result_type = void_type_node;
3403404b540aSrobert       else
3404404b540aSrobert 	{
3405404b540aSrobert 	  error ("type mismatch in conditional expression");
3406404b540aSrobert 	  return error_mark_node;
3407404b540aSrobert 	}
3408404b540aSrobert     }
3409404b540aSrobert 
3410404b540aSrobert   /* Merge const and volatile flags of the incoming types.  */
3411404b540aSrobert   result_type
3412404b540aSrobert     = build_type_variant (result_type,
3413404b540aSrobert 			  TREE_READONLY (op1) || TREE_READONLY (op2),
3414404b540aSrobert 			  TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
3415404b540aSrobert 
3416404b540aSrobert   if (result_type != TREE_TYPE (op1))
3417404b540aSrobert     op1 = convert_and_check (result_type, op1);
3418404b540aSrobert   if (result_type != TREE_TYPE (op2))
3419404b540aSrobert     op2 = convert_and_check (result_type, op2);
3420404b540aSrobert 
3421404b540aSrobert   return fold_build3 (COND_EXPR, result_type, ifexp, op1, op2);
3422404b540aSrobert }
3423404b540aSrobert 
3424404b540aSrobert /* Return a compound expression that performs two expressions and
3425404b540aSrobert    returns the value of the second of them.  */
3426404b540aSrobert 
3427404b540aSrobert tree
build_compound_expr(tree expr1,tree expr2)3428404b540aSrobert build_compound_expr (tree expr1, tree expr2)
3429404b540aSrobert {
3430404b540aSrobert   if (!TREE_SIDE_EFFECTS (expr1))
3431404b540aSrobert     {
3432404b540aSrobert       /* The left-hand operand of a comma expression is like an expression
3433404b540aSrobert 	 statement: with -Wextra or -Wunused, we should warn if it doesn't have
3434404b540aSrobert 	 any side-effects, unless it was explicitly cast to (void).  */
3435404b540aSrobert       if (warn_unused_value)
3436404b540aSrobert 	{
3437404b540aSrobert 	  if (VOID_TYPE_P (TREE_TYPE (expr1))
3438404b540aSrobert 	      && (TREE_CODE (expr1) == NOP_EXPR
3439404b540aSrobert 		  || TREE_CODE (expr1) == CONVERT_EXPR))
3440404b540aSrobert 	    ; /* (void) a, b */
3441404b540aSrobert 	  else if (VOID_TYPE_P (TREE_TYPE (expr1))
3442404b540aSrobert 		   && TREE_CODE (expr1) == COMPOUND_EXPR
3443404b540aSrobert 		   && (TREE_CODE (TREE_OPERAND (expr1, 1)) == CONVERT_EXPR
3444404b540aSrobert 		       || TREE_CODE (TREE_OPERAND (expr1, 1)) == NOP_EXPR))
3445404b540aSrobert 	    ; /* (void) a, (void) b, c */
3446404b540aSrobert 	  else
3447404b540aSrobert 	    warning (0, "left-hand operand of comma expression has no effect");
3448404b540aSrobert 	}
3449404b540aSrobert     }
3450404b540aSrobert 
3451404b540aSrobert   /* With -Wunused, we should also warn if the left-hand operand does have
3452404b540aSrobert      side-effects, but computes a value which is not used.  For example, in
3453404b540aSrobert      `foo() + bar(), baz()' the result of the `+' operator is not used,
3454404b540aSrobert      so we should issue a warning.  */
3455404b540aSrobert   else if (warn_unused_value)
3456404b540aSrobert     warn_if_unused_value (expr1, input_location);
3457404b540aSrobert 
3458404b540aSrobert   if (expr2 == error_mark_node)
3459404b540aSrobert     return error_mark_node;
3460404b540aSrobert 
3461404b540aSrobert   return build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
3462404b540aSrobert }
3463404b540aSrobert 
3464404b540aSrobert /* Build an expression representing a cast to type TYPE of expression EXPR.  */
3465404b540aSrobert 
3466404b540aSrobert tree
build_c_cast(tree type,tree expr)3467404b540aSrobert build_c_cast (tree type, tree expr)
3468404b540aSrobert {
3469404b540aSrobert   tree value = expr;
3470404b540aSrobert 
3471404b540aSrobert   if (type == error_mark_node || expr == error_mark_node)
3472404b540aSrobert     return error_mark_node;
3473404b540aSrobert 
3474404b540aSrobert   /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing
3475404b540aSrobert      only in <protocol> qualifications.  But when constructing cast expressions,
3476404b540aSrobert      the protocols do matter and must be kept around.  */
3477404b540aSrobert   if (objc_is_object_ptr (type) && objc_is_object_ptr (TREE_TYPE (expr)))
3478404b540aSrobert     return build1 (NOP_EXPR, type, expr);
3479404b540aSrobert 
3480404b540aSrobert   type = TYPE_MAIN_VARIANT (type);
3481404b540aSrobert 
3482404b540aSrobert   if (TREE_CODE (type) == ARRAY_TYPE)
3483404b540aSrobert     {
3484404b540aSrobert       error ("cast specifies array type");
3485404b540aSrobert       return error_mark_node;
3486404b540aSrobert     }
3487404b540aSrobert 
3488404b540aSrobert   if (TREE_CODE (type) == FUNCTION_TYPE)
3489404b540aSrobert     {
3490404b540aSrobert       error ("cast specifies function type");
3491404b540aSrobert       return error_mark_node;
3492404b540aSrobert     }
3493404b540aSrobert 
3494404b540aSrobert   if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
3495404b540aSrobert     {
3496404b540aSrobert       if (pedantic)
3497404b540aSrobert 	{
3498404b540aSrobert 	  if (TREE_CODE (type) == RECORD_TYPE
3499404b540aSrobert 	      || TREE_CODE (type) == UNION_TYPE)
3500404b540aSrobert 	    pedwarn ("ISO C forbids casting nonscalar to the same type");
3501404b540aSrobert 	}
3502404b540aSrobert     }
3503404b540aSrobert   else if (TREE_CODE (type) == UNION_TYPE)
3504404b540aSrobert     {
3505404b540aSrobert       tree field;
3506404b540aSrobert 
3507404b540aSrobert       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
3508404b540aSrobert 	if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
3509404b540aSrobert 		       TYPE_MAIN_VARIANT (TREE_TYPE (value))))
3510404b540aSrobert 	  break;
3511404b540aSrobert 
3512404b540aSrobert       if (field)
3513404b540aSrobert 	{
3514404b540aSrobert 	  tree t;
3515404b540aSrobert 
3516404b540aSrobert 	  if (pedantic)
3517404b540aSrobert 	    pedwarn ("ISO C forbids casts to union type");
3518404b540aSrobert 	  t = digest_init (type,
3519404b540aSrobert 			   build_constructor_single (type, field, value),
3520404b540aSrobert 			   true, 0);
3521404b540aSrobert 	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
3522404b540aSrobert 	  TREE_INVARIANT (t) = TREE_INVARIANT (value);
3523404b540aSrobert 	  return t;
3524404b540aSrobert 	}
3525404b540aSrobert       error ("cast to union type from type not present in union");
3526404b540aSrobert       return error_mark_node;
3527404b540aSrobert     }
3528404b540aSrobert   else
3529404b540aSrobert     {
3530404b540aSrobert       tree otype, ovalue;
3531404b540aSrobert 
3532404b540aSrobert       if (type == void_type_node)
3533404b540aSrobert 	return build1 (CONVERT_EXPR, type, value);
3534404b540aSrobert 
3535404b540aSrobert       otype = TREE_TYPE (value);
3536404b540aSrobert 
3537404b540aSrobert       /* Optionally warn about potentially worrisome casts.  */
3538404b540aSrobert 
3539404b540aSrobert       if (warn_cast_qual
3540404b540aSrobert 	  && TREE_CODE (type) == POINTER_TYPE
3541404b540aSrobert 	  && TREE_CODE (otype) == POINTER_TYPE)
3542404b540aSrobert 	{
3543404b540aSrobert 	  tree in_type = type;
3544404b540aSrobert 	  tree in_otype = otype;
3545404b540aSrobert 	  int added = 0;
3546404b540aSrobert 	  int discarded = 0;
3547404b540aSrobert 
3548404b540aSrobert 	  /* Check that the qualifiers on IN_TYPE are a superset of
3549404b540aSrobert 	     the qualifiers of IN_OTYPE.  The outermost level of
3550404b540aSrobert 	     POINTER_TYPE nodes is uninteresting and we stop as soon
3551404b540aSrobert 	     as we hit a non-POINTER_TYPE node on either type.  */
3552404b540aSrobert 	  do
3553404b540aSrobert 	    {
3554404b540aSrobert 	      in_otype = TREE_TYPE (in_otype);
3555404b540aSrobert 	      in_type = TREE_TYPE (in_type);
3556404b540aSrobert 
3557404b540aSrobert 	      /* GNU C allows cv-qualified function types.  'const'
3558404b540aSrobert 		 means the function is very pure, 'volatile' means it
3559404b540aSrobert 		 can't return.  We need to warn when such qualifiers
3560404b540aSrobert 		 are added, not when they're taken away.  */
3561404b540aSrobert 	      if (TREE_CODE (in_otype) == FUNCTION_TYPE
3562404b540aSrobert 		  && TREE_CODE (in_type) == FUNCTION_TYPE)
3563404b540aSrobert 		added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
3564404b540aSrobert 	      else
3565404b540aSrobert 		discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
3566404b540aSrobert 	    }
3567404b540aSrobert 	  while (TREE_CODE (in_type) == POINTER_TYPE
3568404b540aSrobert 		 && TREE_CODE (in_otype) == POINTER_TYPE);
3569404b540aSrobert 
3570404b540aSrobert 	  if (added)
3571404b540aSrobert 	    warning (0, "cast adds new qualifiers to function type");
3572404b540aSrobert 
3573404b540aSrobert 	  if (discarded)
3574404b540aSrobert 	    /* There are qualifiers present in IN_OTYPE that are not
3575404b540aSrobert 	       present in IN_TYPE.  */
3576404b540aSrobert 	    warning (0, "cast discards qualifiers from pointer target type");
3577404b540aSrobert 	}
3578404b540aSrobert 
3579404b540aSrobert       /* Warn about possible alignment problems.  */
3580404b540aSrobert       if (STRICT_ALIGNMENT
3581404b540aSrobert 	  && TREE_CODE (type) == POINTER_TYPE
3582404b540aSrobert 	  && TREE_CODE (otype) == POINTER_TYPE
3583404b540aSrobert 	  && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
3584404b540aSrobert 	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
3585404b540aSrobert 	  /* Don't warn about opaque types, where the actual alignment
3586404b540aSrobert 	     restriction is unknown.  */
3587404b540aSrobert 	  && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
3588404b540aSrobert 		|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
3589404b540aSrobert 	       && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
3590404b540aSrobert 	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
3591404b540aSrobert 	warning (OPT_Wcast_align,
3592404b540aSrobert 		 "cast increases required alignment of target type");
3593404b540aSrobert 
3594404b540aSrobert       if (TREE_CODE (type) == INTEGER_TYPE
3595404b540aSrobert 	  && TREE_CODE (otype) == POINTER_TYPE
3596404b540aSrobert 	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
3597404b540aSrobert       /* Unlike conversion of integers to pointers, where the
3598404b540aSrobert          warning is disabled for converting constants because
3599404b540aSrobert          of cases such as SIG_*, warn about converting constant
3600404b540aSrobert          pointers to integers. In some cases it may cause unwanted
3601404b540aSrobert          sign extension, and a warning is appropriate.  */
3602404b540aSrobert 	warning (OPT_Wpointer_to_int_cast,
3603404b540aSrobert 		 "cast from pointer to integer of different size");
3604404b540aSrobert 
3605404b540aSrobert       if (TREE_CODE (value) == CALL_EXPR
3606404b540aSrobert 	  && TREE_CODE (type) != TREE_CODE (otype))
3607404b540aSrobert 	warning (OPT_Wbad_function_cast, "cast from function call of type %qT "
3608404b540aSrobert 		 "to non-matching type %qT", otype, type);
3609404b540aSrobert 
3610404b540aSrobert       if (TREE_CODE (type) == POINTER_TYPE
3611404b540aSrobert 	  && TREE_CODE (otype) == INTEGER_TYPE
3612404b540aSrobert 	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
3613404b540aSrobert 	  /* Don't warn about converting any constant.  */
3614404b540aSrobert 	  && !TREE_CONSTANT (value))
3615404b540aSrobert 	warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
3616404b540aSrobert 		 "of different size");
3617404b540aSrobert 
3618404b540aSrobert       strict_aliasing_warning (otype, type, expr);
3619404b540aSrobert 
3620404b540aSrobert       /* If pedantic, warn for conversions between function and object
3621404b540aSrobert 	 pointer types, except for converting a null pointer constant
3622404b540aSrobert 	 to function pointer type.  */
3623404b540aSrobert       if (pedantic
3624404b540aSrobert 	  && TREE_CODE (type) == POINTER_TYPE
3625404b540aSrobert 	  && TREE_CODE (otype) == POINTER_TYPE
3626404b540aSrobert 	  && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
3627404b540aSrobert 	  && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
3628404b540aSrobert 	pedwarn ("ISO C forbids conversion of function pointer to object pointer type");
3629404b540aSrobert 
3630404b540aSrobert       if (pedantic
3631404b540aSrobert 	  && TREE_CODE (type) == POINTER_TYPE
3632404b540aSrobert 	  && TREE_CODE (otype) == POINTER_TYPE
3633404b540aSrobert 	  && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
3634404b540aSrobert 	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
3635404b540aSrobert 	  && !null_pointer_constant_p (value))
3636404b540aSrobert 	pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
3637404b540aSrobert 
3638404b540aSrobert       ovalue = value;
3639404b540aSrobert       value = convert (type, value);
3640404b540aSrobert 
3641404b540aSrobert       /* Ignore any integer overflow caused by the cast.  */
3642404b540aSrobert       if (TREE_CODE (value) == INTEGER_CST)
3643404b540aSrobert 	{
3644404b540aSrobert 	  if (CONSTANT_CLASS_P (ovalue)
3645404b540aSrobert 	      && (TREE_OVERFLOW (ovalue) || TREE_CONSTANT_OVERFLOW (ovalue)))
3646404b540aSrobert 	    {
3647404b540aSrobert 	      /* Avoid clobbering a shared constant.  */
3648404b540aSrobert 	      value = copy_node (value);
3649404b540aSrobert 	      TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
3650404b540aSrobert 	      TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
3651404b540aSrobert 	    }
3652404b540aSrobert 	  else if (TREE_OVERFLOW (value) || TREE_CONSTANT_OVERFLOW (value))
3653404b540aSrobert 	    /* Reset VALUE's overflow flags, ensuring constant sharing.  */
3654404b540aSrobert 	    value = build_int_cst_wide (TREE_TYPE (value),
3655404b540aSrobert 					TREE_INT_CST_LOW (value),
3656404b540aSrobert 					TREE_INT_CST_HIGH (value));
3657404b540aSrobert 	}
3658404b540aSrobert     }
3659404b540aSrobert 
3660404b540aSrobert   /* Don't let a cast be an lvalue.  */
3661404b540aSrobert   if (value == expr)
3662404b540aSrobert     value = non_lvalue (value);
3663404b540aSrobert 
3664404b540aSrobert   return value;
3665404b540aSrobert }
3666404b540aSrobert 
3667404b540aSrobert /* Interpret a cast of expression EXPR to type TYPE.  */
3668404b540aSrobert tree
c_cast_expr(struct c_type_name * type_name,tree expr)3669404b540aSrobert c_cast_expr (struct c_type_name *type_name, tree expr)
3670404b540aSrobert {
3671404b540aSrobert   tree type;
3672404b540aSrobert   int saved_wsp = warn_strict_prototypes;
3673404b540aSrobert 
3674404b540aSrobert   /* This avoids warnings about unprototyped casts on
3675404b540aSrobert      integers.  E.g. "#define SIG_DFL (void(*)())0".  */
3676404b540aSrobert   if (TREE_CODE (expr) == INTEGER_CST)
3677404b540aSrobert     warn_strict_prototypes = 0;
3678404b540aSrobert   type = groktypename (type_name);
3679404b540aSrobert   warn_strict_prototypes = saved_wsp;
3680404b540aSrobert 
3681404b540aSrobert   return build_c_cast (type, expr);
3682404b540aSrobert }
3683404b540aSrobert 
3684404b540aSrobert /* Build an assignment expression of lvalue LHS from value RHS.
3685404b540aSrobert    MODIFYCODE is the code for a binary operator that we use
3686404b540aSrobert    to combine the old value of LHS with RHS to get the new value.
3687404b540aSrobert    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.  */
3688404b540aSrobert 
3689404b540aSrobert tree
build_modify_expr(tree lhs,enum tree_code modifycode,tree rhs)3690404b540aSrobert build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
3691404b540aSrobert {
3692404b540aSrobert   tree result;
3693404b540aSrobert   tree newrhs;
3694404b540aSrobert   tree lhstype = TREE_TYPE (lhs);
3695404b540aSrobert   tree olhstype = lhstype;
3696404b540aSrobert 
3697404b540aSrobert   /* Types that aren't fully specified cannot be used in assignments.  */
3698404b540aSrobert   lhs = require_complete_type (lhs);
3699404b540aSrobert 
3700404b540aSrobert   /* Avoid duplicate error messages from operands that had errors.  */
3701404b540aSrobert   if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
3702404b540aSrobert     return error_mark_node;
3703404b540aSrobert 
3704404b540aSrobert   if (!lvalue_or_else (lhs, lv_assign))
3705404b540aSrobert     return error_mark_node;
3706404b540aSrobert 
3707404b540aSrobert   STRIP_TYPE_NOPS (rhs);
3708404b540aSrobert 
3709404b540aSrobert   newrhs = rhs;
3710404b540aSrobert 
3711404b540aSrobert   /* If a binary op has been requested, combine the old LHS value with the RHS
3712404b540aSrobert      producing the value we should actually store into the LHS.  */
3713404b540aSrobert 
3714404b540aSrobert   if (modifycode != NOP_EXPR)
3715404b540aSrobert     {
3716404b540aSrobert       lhs = stabilize_reference (lhs);
3717404b540aSrobert       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
3718404b540aSrobert     }
3719404b540aSrobert 
3720404b540aSrobert   /* Give an error for storing in something that is 'const'.  */
3721404b540aSrobert 
3722404b540aSrobert   if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
3723404b540aSrobert       || ((TREE_CODE (lhstype) == RECORD_TYPE
3724404b540aSrobert 	   || TREE_CODE (lhstype) == UNION_TYPE)
3725404b540aSrobert 	  && C_TYPE_FIELDS_READONLY (lhstype)))
3726404b540aSrobert     {
3727404b540aSrobert       readonly_error (lhs, lv_assign);
3728404b540aSrobert       return error_mark_node;
3729404b540aSrobert     }
3730404b540aSrobert 
3731404b540aSrobert   /* If storing into a structure or union member,
3732404b540aSrobert      it has probably been given type `int'.
3733404b540aSrobert      Compute the type that would go with
3734404b540aSrobert      the actual amount of storage the member occupies.  */
3735404b540aSrobert 
3736404b540aSrobert   if (TREE_CODE (lhs) == COMPONENT_REF
3737404b540aSrobert       && (TREE_CODE (lhstype) == INTEGER_TYPE
3738404b540aSrobert 	  || TREE_CODE (lhstype) == BOOLEAN_TYPE
3739404b540aSrobert 	  || TREE_CODE (lhstype) == REAL_TYPE
3740404b540aSrobert 	  || TREE_CODE (lhstype) == ENUMERAL_TYPE))
3741404b540aSrobert     lhstype = TREE_TYPE (get_unwidened (lhs, 0));
3742404b540aSrobert 
3743404b540aSrobert   /* If storing in a field that is in actuality a short or narrower than one,
3744404b540aSrobert      we must store in the field in its actual type.  */
3745404b540aSrobert 
3746404b540aSrobert   if (lhstype != TREE_TYPE (lhs))
3747404b540aSrobert     {
3748404b540aSrobert       lhs = copy_node (lhs);
3749404b540aSrobert       TREE_TYPE (lhs) = lhstype;
3750404b540aSrobert     }
3751404b540aSrobert 
3752404b540aSrobert   /* Convert new value to destination type.  */
3753404b540aSrobert 
3754404b540aSrobert   newrhs = convert_for_assignment (lhstype, newrhs, ic_assign,
3755404b540aSrobert 				   NULL_TREE, NULL_TREE, 0);
3756404b540aSrobert   if (TREE_CODE (newrhs) == ERROR_MARK)
3757404b540aSrobert     return error_mark_node;
3758404b540aSrobert 
3759404b540aSrobert   /* Emit ObjC write barrier, if necessary.  */
3760404b540aSrobert   if (c_dialect_objc () && flag_objc_gc)
3761404b540aSrobert     {
3762404b540aSrobert       result = objc_generate_write_barrier (lhs, modifycode, newrhs);
3763404b540aSrobert       if (result)
3764404b540aSrobert 	return result;
3765404b540aSrobert     }
3766404b540aSrobert 
3767404b540aSrobert   /* Scan operands.  */
3768404b540aSrobert 
3769404b540aSrobert   result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs);
3770404b540aSrobert   TREE_SIDE_EFFECTS (result) = 1;
3771404b540aSrobert 
3772404b540aSrobert   /* If we got the LHS in a different type for storing in,
3773404b540aSrobert      convert the result back to the nominal type of LHS
3774404b540aSrobert      so that the value we return always has the same type
3775404b540aSrobert      as the LHS argument.  */
3776404b540aSrobert 
3777404b540aSrobert   if (olhstype == TREE_TYPE (result))
3778404b540aSrobert     return result;
3779404b540aSrobert   return convert_for_assignment (olhstype, result, ic_assign,
3780404b540aSrobert 				 NULL_TREE, NULL_TREE, 0);
3781404b540aSrobert }
3782404b540aSrobert 
3783404b540aSrobert /* Convert value RHS to type TYPE as preparation for an assignment
3784404b540aSrobert    to an lvalue of type TYPE.
3785404b540aSrobert    The real work of conversion is done by `convert'.
3786404b540aSrobert    The purpose of this function is to generate error messages
3787404b540aSrobert    for assignments that are not allowed in C.
3788404b540aSrobert    ERRTYPE says whether it is argument passing, assignment,
3789404b540aSrobert    initialization or return.
3790404b540aSrobert 
3791404b540aSrobert    FUNCTION is a tree for the function being called.
3792404b540aSrobert    PARMNUM is the number of the argument, for printing in error messages.  */
3793404b540aSrobert 
3794404b540aSrobert static tree
convert_for_assignment(tree type,tree rhs,enum impl_conv errtype,tree fundecl,tree function,int parmnum)3795404b540aSrobert convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
3796404b540aSrobert 			tree fundecl, tree function, int parmnum)
3797404b540aSrobert {
3798404b540aSrobert   enum tree_code codel = TREE_CODE (type);
3799404b540aSrobert   tree rhstype;
3800404b540aSrobert   enum tree_code coder;
3801404b540aSrobert   tree rname = NULL_TREE;
3802404b540aSrobert   bool objc_ok = false;
3803404b540aSrobert 
3804404b540aSrobert   if (errtype == ic_argpass || errtype == ic_argpass_nonproto)
3805404b540aSrobert     {
3806404b540aSrobert       tree selector;
3807404b540aSrobert       /* Change pointer to function to the function itself for
3808404b540aSrobert 	 diagnostics.  */
3809404b540aSrobert       if (TREE_CODE (function) == ADDR_EXPR
3810404b540aSrobert 	  && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
3811404b540aSrobert 	function = TREE_OPERAND (function, 0);
3812404b540aSrobert 
3813404b540aSrobert       /* Handle an ObjC selector specially for diagnostics.  */
3814404b540aSrobert       selector = objc_message_selector ();
3815404b540aSrobert       rname = function;
3816404b540aSrobert       if (selector && parmnum > 2)
3817404b540aSrobert 	{
3818404b540aSrobert 	  rname = selector;
3819404b540aSrobert 	  parmnum -= 2;
3820404b540aSrobert 	}
3821404b540aSrobert     }
3822404b540aSrobert 
3823404b540aSrobert   /* This macro is used to emit diagnostics to ensure that all format
3824404b540aSrobert      strings are complete sentences, visible to gettext and checked at
3825404b540aSrobert      compile time.  */
3826404b540aSrobert #define WARN_FOR_ASSIGNMENT(AR, AS, IN, RE)	\
3827404b540aSrobert   do {						\
3828404b540aSrobert     switch (errtype)				\
3829404b540aSrobert       {						\
3830404b540aSrobert       case ic_argpass:				\
3831404b540aSrobert 	pedwarn (AR, parmnum, rname);		\
3832404b540aSrobert 	break;					\
3833404b540aSrobert       case ic_argpass_nonproto:			\
3834404b540aSrobert 	warning (0, AR, parmnum, rname);		\
3835404b540aSrobert 	break;					\
3836404b540aSrobert       case ic_assign:				\
3837404b540aSrobert 	pedwarn (AS);				\
3838404b540aSrobert 	break;					\
3839404b540aSrobert       case ic_init:				\
3840404b540aSrobert 	pedwarn (IN);				\
3841404b540aSrobert 	break;					\
3842404b540aSrobert       case ic_return:				\
3843404b540aSrobert 	pedwarn (RE);				\
3844404b540aSrobert 	break;					\
3845404b540aSrobert       default:					\
3846404b540aSrobert 	gcc_unreachable ();			\
3847404b540aSrobert       }						\
3848404b540aSrobert   } while (0)
3849404b540aSrobert 
3850404b540aSrobert   STRIP_TYPE_NOPS (rhs);
3851404b540aSrobert 
3852404b540aSrobert   if (optimize && TREE_CODE (rhs) == VAR_DECL
3853404b540aSrobert 	   && TREE_CODE (TREE_TYPE (rhs)) != ARRAY_TYPE)
3854404b540aSrobert     rhs = decl_constant_value_for_broken_optimization (rhs);
3855404b540aSrobert 
3856404b540aSrobert   rhstype = TREE_TYPE (rhs);
3857404b540aSrobert   coder = TREE_CODE (rhstype);
3858404b540aSrobert 
3859404b540aSrobert   if (coder == ERROR_MARK)
3860404b540aSrobert     return error_mark_node;
3861404b540aSrobert 
3862404b540aSrobert   if (c_dialect_objc ())
3863404b540aSrobert     {
3864404b540aSrobert       int parmno;
3865404b540aSrobert 
3866404b540aSrobert       switch (errtype)
3867404b540aSrobert 	{
3868404b540aSrobert 	case ic_return:
3869404b540aSrobert 	  parmno = 0;
3870404b540aSrobert 	  break;
3871404b540aSrobert 
3872404b540aSrobert 	case ic_assign:
3873404b540aSrobert 	  parmno = -1;
3874404b540aSrobert 	  break;
3875404b540aSrobert 
3876404b540aSrobert 	case ic_init:
3877404b540aSrobert 	  parmno = -2;
3878404b540aSrobert 	  break;
3879404b540aSrobert 
3880404b540aSrobert 	default:
3881404b540aSrobert 	  parmno = parmnum;
3882404b540aSrobert 	  break;
3883404b540aSrobert 	}
3884404b540aSrobert 
3885404b540aSrobert       objc_ok = objc_compare_types (type, rhstype, parmno, rname);
3886404b540aSrobert     }
3887404b540aSrobert 
3888404b540aSrobert   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
3889404b540aSrobert     {
3890404b540aSrobert       overflow_warning (rhs);
3891404b540aSrobert       return rhs;
3892404b540aSrobert     }
3893404b540aSrobert 
3894404b540aSrobert   if (coder == VOID_TYPE)
3895404b540aSrobert     {
3896404b540aSrobert       /* Except for passing an argument to an unprototyped function,
3897404b540aSrobert 	 this is a constraint violation.  When passing an argument to
3898404b540aSrobert 	 an unprototyped function, it is compile-time undefined;
3899404b540aSrobert 	 making it a constraint in that case was rejected in
3900404b540aSrobert 	 DR#252.  */
3901404b540aSrobert       error ("void value not ignored as it ought to be");
3902404b540aSrobert       return error_mark_node;
3903404b540aSrobert     }
3904404b540aSrobert   /* A type converts to a reference to it.
3905404b540aSrobert      This code doesn't fully support references, it's just for the
3906404b540aSrobert      special case of va_start and va_copy.  */
3907404b540aSrobert   if (codel == REFERENCE_TYPE
3908404b540aSrobert       && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
3909404b540aSrobert     {
3910404b540aSrobert       if (!lvalue_p (rhs))
3911404b540aSrobert 	{
3912404b540aSrobert 	  error ("cannot pass rvalue to reference parameter");
3913404b540aSrobert 	  return error_mark_node;
3914404b540aSrobert 	}
3915404b540aSrobert       if (!c_mark_addressable (rhs))
3916404b540aSrobert 	return error_mark_node;
3917404b540aSrobert       rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
3918404b540aSrobert 
3919404b540aSrobert       /* We already know that these two types are compatible, but they
3920404b540aSrobert 	 may not be exactly identical.  In fact, `TREE_TYPE (type)' is
3921404b540aSrobert 	 likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
3922404b540aSrobert 	 likely to be va_list, a typedef to __builtin_va_list, which
3923404b540aSrobert 	 is different enough that it will cause problems later.  */
3924404b540aSrobert       if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
3925404b540aSrobert 	rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
3926404b540aSrobert 
3927404b540aSrobert       rhs = build1 (NOP_EXPR, type, rhs);
3928404b540aSrobert       return rhs;
3929404b540aSrobert     }
3930404b540aSrobert   /* Some types can interconvert without explicit casts.  */
3931404b540aSrobert   else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
3932404b540aSrobert 	   && vector_types_convertible_p (type, TREE_TYPE (rhs)))
3933404b540aSrobert     return convert (type, rhs);
3934404b540aSrobert   /* Arithmetic types all interconvert, and enum is treated like int.  */
3935404b540aSrobert   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
3936404b540aSrobert 	    || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
3937404b540aSrobert 	    || codel == BOOLEAN_TYPE)
3938404b540aSrobert 	   && (coder == INTEGER_TYPE || coder == REAL_TYPE
3939404b540aSrobert 	       || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
3940404b540aSrobert 	       || coder == BOOLEAN_TYPE))
3941404b540aSrobert     return convert_and_check (type, rhs);
3942404b540aSrobert 
3943404b540aSrobert   /* Aggregates in different TUs might need conversion.  */
3944404b540aSrobert   if ((codel == RECORD_TYPE || codel == UNION_TYPE)
3945404b540aSrobert       && codel == coder
3946404b540aSrobert       && comptypes (type, rhstype))
3947404b540aSrobert     return convert_and_check (type, rhs);
3948404b540aSrobert 
3949404b540aSrobert   /* Conversion to a transparent union from its member types.
3950404b540aSrobert      This applies only to function arguments.  */
3951404b540aSrobert   if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
3952404b540aSrobert       && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
3953404b540aSrobert     {
3954404b540aSrobert       tree memb, marginal_memb = NULL_TREE;
3955404b540aSrobert 
3956404b540aSrobert       for (memb = TYPE_FIELDS (type); memb ; memb = TREE_CHAIN (memb))
3957404b540aSrobert 	{
3958404b540aSrobert 	  tree memb_type = TREE_TYPE (memb);
3959404b540aSrobert 
3960404b540aSrobert 	  if (comptypes (TYPE_MAIN_VARIANT (memb_type),
3961404b540aSrobert 			 TYPE_MAIN_VARIANT (rhstype)))
3962404b540aSrobert 	    break;
3963404b540aSrobert 
3964404b540aSrobert 	  if (TREE_CODE (memb_type) != POINTER_TYPE)
3965404b540aSrobert 	    continue;
3966404b540aSrobert 
3967404b540aSrobert 	  if (coder == POINTER_TYPE)
3968404b540aSrobert 	    {
3969404b540aSrobert 	      tree ttl = TREE_TYPE (memb_type);
3970404b540aSrobert 	      tree ttr = TREE_TYPE (rhstype);
3971404b540aSrobert 
3972404b540aSrobert 	      /* Any non-function converts to a [const][volatile] void *
3973404b540aSrobert 		 and vice versa; otherwise, targets must be the same.
3974404b540aSrobert 		 Meanwhile, the lhs target must have all the qualifiers of
3975404b540aSrobert 		 the rhs.  */
3976404b540aSrobert 	      if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
3977404b540aSrobert 		  || comp_target_types (memb_type, rhstype))
3978404b540aSrobert 		{
3979404b540aSrobert 		  /* If this type won't generate any warnings, use it.  */
3980404b540aSrobert 		  if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
3981404b540aSrobert 		      || ((TREE_CODE (ttr) == FUNCTION_TYPE
3982404b540aSrobert 			   && TREE_CODE (ttl) == FUNCTION_TYPE)
3983404b540aSrobert 			  ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
3984404b540aSrobert 			     == TYPE_QUALS (ttr))
3985404b540aSrobert 			  : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
3986404b540aSrobert 			     == TYPE_QUALS (ttl))))
3987404b540aSrobert 		    break;
3988404b540aSrobert 
3989404b540aSrobert 		  /* Keep looking for a better type, but remember this one.  */
3990404b540aSrobert 		  if (!marginal_memb)
3991404b540aSrobert 		    marginal_memb = memb;
3992404b540aSrobert 		}
3993404b540aSrobert 	    }
3994404b540aSrobert 
3995404b540aSrobert 	  /* Can convert integer zero to any pointer type.  */
3996404b540aSrobert 	  if (null_pointer_constant_p (rhs))
3997404b540aSrobert 	    {
3998404b540aSrobert 	      rhs = null_pointer_node;
3999404b540aSrobert 	      break;
4000404b540aSrobert 	    }
4001404b540aSrobert 	}
4002404b540aSrobert 
4003404b540aSrobert       if (memb || marginal_memb)
4004404b540aSrobert 	{
4005404b540aSrobert 	  if (!memb)
4006404b540aSrobert 	    {
4007404b540aSrobert 	      /* We have only a marginally acceptable member type;
4008404b540aSrobert 		 it needs a warning.  */
4009404b540aSrobert 	      tree ttl = TREE_TYPE (TREE_TYPE (marginal_memb));
4010404b540aSrobert 	      tree ttr = TREE_TYPE (rhstype);
4011404b540aSrobert 
4012404b540aSrobert 	      /* Const and volatile mean something different for function
4013404b540aSrobert 		 types, so the usual warnings are not appropriate.  */
4014404b540aSrobert 	      if (TREE_CODE (ttr) == FUNCTION_TYPE
4015404b540aSrobert 		  && TREE_CODE (ttl) == FUNCTION_TYPE)
4016404b540aSrobert 		{
4017404b540aSrobert 		  /* Because const and volatile on functions are
4018404b540aSrobert 		     restrictions that say the function will not do
4019404b540aSrobert 		     certain things, it is okay to use a const or volatile
4020404b540aSrobert 		     function where an ordinary one is wanted, but not
4021404b540aSrobert 		     vice-versa.  */
4022404b540aSrobert 		  if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
4023404b540aSrobert 		    WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE "
4024404b540aSrobert 					    "makes qualified function "
4025404b540aSrobert 					    "pointer from unqualified"),
4026404b540aSrobert 					 G_("assignment makes qualified "
4027404b540aSrobert 					    "function pointer from "
4028404b540aSrobert 					    "unqualified"),
4029404b540aSrobert 					 G_("initialization makes qualified "
4030404b540aSrobert 					    "function pointer from "
4031404b540aSrobert 					    "unqualified"),
4032404b540aSrobert 					 G_("return makes qualified function "
4033404b540aSrobert 					    "pointer from unqualified"));
4034404b540aSrobert 		}
4035404b540aSrobert 	      else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
4036404b540aSrobert 		WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE discards "
4037404b540aSrobert 					"qualifiers from pointer target type"),
4038404b540aSrobert 				     G_("assignment discards qualifiers "
4039404b540aSrobert 					"from pointer target type"),
4040404b540aSrobert 				     G_("initialization discards qualifiers "
4041404b540aSrobert 					"from pointer target type"),
4042404b540aSrobert 				     G_("return discards qualifiers from "
4043404b540aSrobert 					"pointer target type"));
4044404b540aSrobert 
4045404b540aSrobert 	      memb = marginal_memb;
4046404b540aSrobert 	    }
4047404b540aSrobert 
4048404b540aSrobert 	  if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)))
4049404b540aSrobert 	    pedwarn ("ISO C prohibits argument conversion to union type");
4050404b540aSrobert 
4051404b540aSrobert 	  return build_constructor_single (type, memb, rhs);
4052404b540aSrobert 	}
4053404b540aSrobert     }
4054404b540aSrobert 
4055404b540aSrobert   /* Conversions among pointers */
4056404b540aSrobert   else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
4057404b540aSrobert 	   && (coder == codel))
4058404b540aSrobert     {
4059404b540aSrobert       tree ttl = TREE_TYPE (type);
4060404b540aSrobert       tree ttr = TREE_TYPE (rhstype);
4061404b540aSrobert       tree mvl = ttl;
4062404b540aSrobert       tree mvr = ttr;
4063404b540aSrobert       bool is_opaque_pointer;
4064404b540aSrobert       int target_cmp = 0;   /* Cache comp_target_types () result.  */
4065404b540aSrobert 
4066404b540aSrobert       if (TREE_CODE (mvl) != ARRAY_TYPE)
4067404b540aSrobert 	mvl = TYPE_MAIN_VARIANT (mvl);
4068404b540aSrobert       if (TREE_CODE (mvr) != ARRAY_TYPE)
4069404b540aSrobert 	mvr = TYPE_MAIN_VARIANT (mvr);
4070404b540aSrobert       /* Opaque pointers are treated like void pointers.  */
4071404b540aSrobert       is_opaque_pointer = (targetm.vector_opaque_p (type)
4072404b540aSrobert 			   || targetm.vector_opaque_p (rhstype))
4073404b540aSrobert 	&& TREE_CODE (ttl) == VECTOR_TYPE
4074404b540aSrobert 	&& TREE_CODE (ttr) == VECTOR_TYPE;
4075404b540aSrobert 
4076404b540aSrobert       /* C++ does not allow the implicit conversion void* -> T*.  However,
4077404b540aSrobert 	 for the purpose of reducing the number of false positives, we
4078404b540aSrobert 	 tolerate the special case of
4079404b540aSrobert 
4080404b540aSrobert 		int *p = NULL;
4081404b540aSrobert 
4082404b540aSrobert 	 where NULL is typically defined in C to be '(void *) 0'.  */
4083404b540aSrobert       if (VOID_TYPE_P (ttr) && rhs != null_pointer_node && !VOID_TYPE_P (ttl))
4084404b540aSrobert 	warning (OPT_Wc___compat, "request for implicit conversion from "
4085404b540aSrobert 		 "%qT to %qT not permitted in C++", rhstype, type);
4086404b540aSrobert 
4087404b540aSrobert       /* Check if the right-hand side has a format attribute but the
4088404b540aSrobert 	 left-hand side doesn't.  */
4089404b540aSrobert       if (warn_missing_format_attribute
4090404b540aSrobert 	  && check_missing_format_attribute (type, rhstype))
4091404b540aSrobert 	{
4092404b540aSrobert 	  switch (errtype)
4093404b540aSrobert 	  {
4094404b540aSrobert 	  case ic_argpass:
4095404b540aSrobert 	  case ic_argpass_nonproto:
4096404b540aSrobert 	    warning (OPT_Wmissing_format_attribute,
4097404b540aSrobert 		     "argument %d of %qE might be "
4098404b540aSrobert 		     "a candidate for a format attribute",
4099404b540aSrobert 		     parmnum, rname);
4100404b540aSrobert 	    break;
4101404b540aSrobert 	  case ic_assign:
4102404b540aSrobert 	    warning (OPT_Wmissing_format_attribute,
4103404b540aSrobert 		     "assignment left-hand side might be "
4104404b540aSrobert 		     "a candidate for a format attribute");
4105404b540aSrobert 	    break;
4106404b540aSrobert 	  case ic_init:
4107404b540aSrobert 	    warning (OPT_Wmissing_format_attribute,
4108404b540aSrobert 		     "initialization left-hand side might be "
4109404b540aSrobert 		     "a candidate for a format attribute");
4110404b540aSrobert 	    break;
4111404b540aSrobert 	  case ic_return:
4112404b540aSrobert 	    warning (OPT_Wmissing_format_attribute,
4113404b540aSrobert 		     "return type might be "
4114404b540aSrobert 		     "a candidate for a format attribute");
4115404b540aSrobert 	    break;
4116404b540aSrobert 	  default:
4117404b540aSrobert 	    gcc_unreachable ();
4118404b540aSrobert 	  }
4119404b540aSrobert 	}
4120404b540aSrobert 
4121404b540aSrobert       /* Any non-function converts to a [const][volatile] void *
4122404b540aSrobert 	 and vice versa; otherwise, targets must be the same.
4123404b540aSrobert 	 Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
4124404b540aSrobert       if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
4125404b540aSrobert 	  || (target_cmp = comp_target_types (type, rhstype))
4126404b540aSrobert 	  || is_opaque_pointer
4127404b540aSrobert 	  || (c_common_unsigned_type (mvl)
4128404b540aSrobert 	      == c_common_unsigned_type (mvr)))
4129404b540aSrobert 	{
4130404b540aSrobert 	  if (pedantic
4131404b540aSrobert 	      && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
4132404b540aSrobert 		  ||
4133404b540aSrobert 		  (VOID_TYPE_P (ttr)
4134404b540aSrobert 		   && !null_pointer_constant_p (rhs)
4135404b540aSrobert 		   && TREE_CODE (ttl) == FUNCTION_TYPE)))
4136404b540aSrobert 	    WARN_FOR_ASSIGNMENT (G_("ISO C forbids passing argument %d of "
4137404b540aSrobert 				    "%qE between function pointer "
4138404b540aSrobert 				    "and %<void *%>"),
4139404b540aSrobert 				 G_("ISO C forbids assignment between "
4140404b540aSrobert 				    "function pointer and %<void *%>"),
4141404b540aSrobert 				 G_("ISO C forbids initialization between "
4142404b540aSrobert 				    "function pointer and %<void *%>"),
4143404b540aSrobert 				 G_("ISO C forbids return between function "
4144404b540aSrobert 				    "pointer and %<void *%>"));
4145404b540aSrobert 	  /* Const and volatile mean something different for function types,
4146404b540aSrobert 	     so the usual warnings are not appropriate.  */
4147404b540aSrobert 	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
4148404b540aSrobert 		   && TREE_CODE (ttl) != FUNCTION_TYPE)
4149404b540aSrobert 	    {
4150404b540aSrobert 	      if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
4151404b540aSrobert 		{
4152404b540aSrobert 		  /* Types differing only by the presence of the 'volatile'
4153404b540aSrobert 		     qualifier are acceptable if the 'volatile' has been added
4154404b540aSrobert 		     in by the Objective-C EH machinery.  */
4155404b540aSrobert 		  if (!objc_type_quals_match (ttl, ttr))
4156404b540aSrobert 		    WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE discards "
4157404b540aSrobert 					    "qualifiers from pointer target type"),
4158404b540aSrobert 					 G_("assignment discards qualifiers "
4159404b540aSrobert 					    "from pointer target type"),
4160404b540aSrobert 					 G_("initialization discards qualifiers "
4161404b540aSrobert 					    "from pointer target type"),
4162404b540aSrobert 					 G_("return discards qualifiers from "
4163404b540aSrobert 					    "pointer target type"));
4164404b540aSrobert 		}
4165404b540aSrobert 	      /* If this is not a case of ignoring a mismatch in signedness,
4166404b540aSrobert 		 no warning.  */
4167404b540aSrobert 	      else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
4168404b540aSrobert 		       || target_cmp)
4169404b540aSrobert 		;
4170404b540aSrobert 	      /* If there is a mismatch, do warn.  */
4171404b540aSrobert 	      else if (warn_pointer_sign)
4172404b540aSrobert 		WARN_FOR_ASSIGNMENT (G_("pointer targets in passing argument "
4173404b540aSrobert 					"%d of %qE differ in signedness"),
4174404b540aSrobert 				     G_("pointer targets in assignment "
4175404b540aSrobert 					"differ in signedness"),
4176404b540aSrobert 				     G_("pointer targets in initialization "
4177404b540aSrobert 					"differ in signedness"),
4178404b540aSrobert 				     G_("pointer targets in return differ "
4179404b540aSrobert 					"in signedness"));
4180404b540aSrobert 	    }
4181404b540aSrobert 	  else if (TREE_CODE (ttl) == FUNCTION_TYPE
4182404b540aSrobert 		   && TREE_CODE (ttr) == FUNCTION_TYPE)
4183404b540aSrobert 	    {
4184404b540aSrobert 	      /* Because const and volatile on functions are restrictions
4185404b540aSrobert 		 that say the function will not do certain things,
4186404b540aSrobert 		 it is okay to use a const or volatile function
4187404b540aSrobert 		 where an ordinary one is wanted, but not vice-versa.  */
4188404b540aSrobert 	      if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
4189404b540aSrobert 		WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes "
4190404b540aSrobert 					"qualified function pointer "
4191404b540aSrobert 					"from unqualified"),
4192404b540aSrobert 				     G_("assignment makes qualified function "
4193404b540aSrobert 					"pointer from unqualified"),
4194404b540aSrobert 				     G_("initialization makes qualified "
4195404b540aSrobert 					"function pointer from unqualified"),
4196404b540aSrobert 				     G_("return makes qualified function "
4197404b540aSrobert 					"pointer from unqualified"));
4198404b540aSrobert 	    }
4199404b540aSrobert 	}
4200404b540aSrobert       else
4201404b540aSrobert 	/* Avoid warning about the volatile ObjC EH puts on decls.  */
4202404b540aSrobert 	if (!objc_ok)
4203404b540aSrobert 	  WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE from "
4204404b540aSrobert 				  "incompatible pointer type"),
4205404b540aSrobert 			       G_("assignment from incompatible pointer type"),
4206404b540aSrobert 			       G_("initialization from incompatible "
4207404b540aSrobert 				  "pointer type"),
4208404b540aSrobert 			       G_("return from incompatible pointer type"));
4209404b540aSrobert 
4210404b540aSrobert       return convert (type, rhs);
4211404b540aSrobert     }
4212404b540aSrobert   else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
4213404b540aSrobert     {
4214404b540aSrobert       /* ??? This should not be an error when inlining calls to
4215404b540aSrobert 	 unprototyped functions.  */
4216404b540aSrobert       error ("invalid use of non-lvalue array");
4217404b540aSrobert       return error_mark_node;
4218404b540aSrobert     }
4219404b540aSrobert   else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
4220404b540aSrobert     {
4221404b540aSrobert       /* An explicit constant 0 can convert to a pointer,
4222404b540aSrobert 	 or one that results from arithmetic, even including
4223404b540aSrobert 	 a cast to integer type.  */
4224404b540aSrobert       if (!null_pointer_constant_p (rhs))
4225404b540aSrobert 	WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes "
4226404b540aSrobert 				"pointer from integer without a cast"),
4227404b540aSrobert 			     G_("assignment makes pointer from integer "
4228404b540aSrobert 				"without a cast"),
4229404b540aSrobert 			     G_("initialization makes pointer from "
4230404b540aSrobert 				"integer without a cast"),
4231404b540aSrobert 			     G_("return makes pointer from integer "
4232404b540aSrobert 				"without a cast"));
4233404b540aSrobert 
4234404b540aSrobert       return convert (type, rhs);
4235404b540aSrobert     }
4236404b540aSrobert   else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
4237404b540aSrobert     {
4238404b540aSrobert       WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes integer "
4239404b540aSrobert 			      "from pointer without a cast"),
4240404b540aSrobert 			   G_("assignment makes integer from pointer "
4241404b540aSrobert 			      "without a cast"),
4242404b540aSrobert 			   G_("initialization makes integer from pointer "
4243404b540aSrobert 			      "without a cast"),
4244404b540aSrobert 			   G_("return makes integer from pointer "
4245404b540aSrobert 			      "without a cast"));
4246404b540aSrobert       return convert (type, rhs);
4247404b540aSrobert     }
4248404b540aSrobert   else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE)
4249404b540aSrobert     return convert (type, rhs);
4250404b540aSrobert 
4251404b540aSrobert   switch (errtype)
4252404b540aSrobert     {
4253404b540aSrobert     case ic_argpass:
4254404b540aSrobert     case ic_argpass_nonproto:
4255404b540aSrobert       /* ??? This should not be an error when inlining calls to
4256404b540aSrobert 	 unprototyped functions.  */
4257404b540aSrobert       error ("incompatible type for argument %d of %qE", parmnum, rname);
4258404b540aSrobert       break;
4259404b540aSrobert     case ic_assign:
4260404b540aSrobert       error ("incompatible types in assignment");
4261404b540aSrobert       break;
4262404b540aSrobert     case ic_init:
4263404b540aSrobert       error ("incompatible types in initialization");
4264404b540aSrobert       break;
4265404b540aSrobert     case ic_return:
4266404b540aSrobert       error ("incompatible types in return");
4267404b540aSrobert       break;
4268404b540aSrobert     default:
4269404b540aSrobert       gcc_unreachable ();
4270404b540aSrobert     }
4271404b540aSrobert 
4272404b540aSrobert   return error_mark_node;
4273404b540aSrobert }
4274404b540aSrobert 
4275404b540aSrobert /* Convert VALUE for assignment into inlined parameter PARM.  ARGNUM
4276404b540aSrobert    is used for error and warning reporting and indicates which argument
4277404b540aSrobert    is being processed.  */
4278404b540aSrobert 
4279404b540aSrobert tree
c_convert_parm_for_inlining(tree parm,tree value,tree fn,int argnum)4280404b540aSrobert c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
4281404b540aSrobert {
4282404b540aSrobert   tree ret, type;
4283404b540aSrobert 
4284404b540aSrobert   /* If FN was prototyped at the call site, the value has been converted
4285404b540aSrobert      already in convert_arguments.
4286404b540aSrobert      However, we might see a prototype now that was not in place when
4287404b540aSrobert      the function call was seen, so check that the VALUE actually matches
4288404b540aSrobert      PARM before taking an early exit.  */
4289404b540aSrobert   if (!value
4290404b540aSrobert       || (TYPE_ARG_TYPES (TREE_TYPE (fn))
4291404b540aSrobert 	  && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
4292404b540aSrobert 	      == TYPE_MAIN_VARIANT (TREE_TYPE (value)))))
4293404b540aSrobert     return value;
4294404b540aSrobert 
4295404b540aSrobert   type = TREE_TYPE (parm);
4296404b540aSrobert   ret = convert_for_assignment (type, value,
4297404b540aSrobert 				ic_argpass_nonproto, fn,
4298404b540aSrobert 				fn, argnum);
4299404b540aSrobert   if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
4300404b540aSrobert       && INTEGRAL_TYPE_P (type)
4301404b540aSrobert       && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
4302404b540aSrobert     ret = default_conversion (ret);
4303404b540aSrobert   return ret;
4304404b540aSrobert }
4305404b540aSrobert 
4306404b540aSrobert /* If VALUE is a compound expr all of whose expressions are constant, then
4307404b540aSrobert    return its value.  Otherwise, return error_mark_node.
4308404b540aSrobert 
4309404b540aSrobert    This is for handling COMPOUND_EXPRs as initializer elements
4310404b540aSrobert    which is allowed with a warning when -pedantic is specified.  */
4311404b540aSrobert 
4312404b540aSrobert static tree
valid_compound_expr_initializer(tree value,tree endtype)4313404b540aSrobert valid_compound_expr_initializer (tree value, tree endtype)
4314404b540aSrobert {
4315404b540aSrobert   if (TREE_CODE (value) == COMPOUND_EXPR)
4316404b540aSrobert     {
4317404b540aSrobert       if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype)
4318404b540aSrobert 	  == error_mark_node)
4319404b540aSrobert 	return error_mark_node;
4320404b540aSrobert       return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
4321404b540aSrobert 					      endtype);
4322404b540aSrobert     }
4323404b540aSrobert   else if (!initializer_constant_valid_p (value, endtype))
4324404b540aSrobert     return error_mark_node;
4325404b540aSrobert   else
4326404b540aSrobert     return value;
4327404b540aSrobert }
4328404b540aSrobert 
4329404b540aSrobert /* Perform appropriate conversions on the initial value of a variable,
4330404b540aSrobert    store it in the declaration DECL,
4331404b540aSrobert    and print any error messages that are appropriate.
4332404b540aSrobert    If the init is invalid, store an ERROR_MARK.  */
4333404b540aSrobert 
4334404b540aSrobert void
store_init_value(tree decl,tree init)4335404b540aSrobert store_init_value (tree decl, tree init)
4336404b540aSrobert {
4337404b540aSrobert   tree value, type;
4338404b540aSrobert 
4339404b540aSrobert   /* If variable's type was invalidly declared, just ignore it.  */
4340404b540aSrobert 
4341404b540aSrobert   type = TREE_TYPE (decl);
4342404b540aSrobert   if (TREE_CODE (type) == ERROR_MARK)
4343404b540aSrobert     return;
4344404b540aSrobert 
4345404b540aSrobert   /* Digest the specified initializer into an expression.  */
4346404b540aSrobert 
4347404b540aSrobert   value = digest_init (type, init, true, TREE_STATIC (decl));
4348404b540aSrobert 
4349404b540aSrobert   /* Store the expression if valid; else report error.  */
4350404b540aSrobert 
4351404b540aSrobert   if (!in_system_header
4352404b540aSrobert       && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && !TREE_STATIC (decl))
4353404b540aSrobert     warning (OPT_Wtraditional, "traditional C rejects automatic "
4354404b540aSrobert 	     "aggregate initialization");
4355404b540aSrobert 
4356404b540aSrobert   DECL_INITIAL (decl) = value;
4357404b540aSrobert 
4358404b540aSrobert   /* ANSI wants warnings about out-of-range constant initializers.  */
4359404b540aSrobert   STRIP_TYPE_NOPS (value);
4360404b540aSrobert   constant_expression_warning (value);
4361404b540aSrobert 
4362404b540aSrobert   /* Check if we need to set array size from compound literal size.  */
4363404b540aSrobert   if (TREE_CODE (type) == ARRAY_TYPE
4364404b540aSrobert       && TYPE_DOMAIN (type) == 0
4365404b540aSrobert       && value != error_mark_node)
4366404b540aSrobert     {
4367404b540aSrobert       tree inside_init = init;
4368404b540aSrobert 
4369404b540aSrobert       STRIP_TYPE_NOPS (inside_init);
4370404b540aSrobert       inside_init = fold (inside_init);
4371404b540aSrobert 
4372404b540aSrobert       if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
4373404b540aSrobert 	{
4374404b540aSrobert 	  tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
4375404b540aSrobert 
4376404b540aSrobert 	  if (TYPE_DOMAIN (TREE_TYPE (cldecl)))
4377404b540aSrobert 	    {
4378404b540aSrobert 	      /* For int foo[] = (int [3]){1}; we need to set array size
4379404b540aSrobert 		 now since later on array initializer will be just the
4380404b540aSrobert 		 brace enclosed list of the compound literal.  */
4381404b540aSrobert 	      type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
4382404b540aSrobert 	      TREE_TYPE (decl) = type;
4383404b540aSrobert 	      TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl));
4384404b540aSrobert 	      layout_type (type);
4385404b540aSrobert 	      layout_decl (cldecl, 0);
4386404b540aSrobert 	    }
4387404b540aSrobert 	}
4388404b540aSrobert     }
4389404b540aSrobert }
4390404b540aSrobert 
4391404b540aSrobert /* Methods for storing and printing names for error messages.  */
4392404b540aSrobert 
4393404b540aSrobert /* Implement a spelling stack that allows components of a name to be pushed
4394404b540aSrobert    and popped.  Each element on the stack is this structure.  */
4395404b540aSrobert 
4396404b540aSrobert struct spelling
4397404b540aSrobert {
4398404b540aSrobert   int kind;
4399404b540aSrobert   union
4400404b540aSrobert     {
4401404b540aSrobert       unsigned HOST_WIDE_INT i;
4402404b540aSrobert       const char *s;
4403404b540aSrobert     } u;
4404404b540aSrobert };
4405404b540aSrobert 
4406404b540aSrobert #define SPELLING_STRING 1
4407404b540aSrobert #define SPELLING_MEMBER 2
4408404b540aSrobert #define SPELLING_BOUNDS 3
4409404b540aSrobert 
4410404b540aSrobert static struct spelling *spelling;	/* Next stack element (unused).  */
4411404b540aSrobert static struct spelling *spelling_base;	/* Spelling stack base.  */
4412404b540aSrobert static int spelling_size;		/* Size of the spelling stack.  */
4413404b540aSrobert 
4414404b540aSrobert /* Macros to save and restore the spelling stack around push_... functions.
4415404b540aSrobert    Alternative to SAVE_SPELLING_STACK.  */
4416404b540aSrobert 
4417404b540aSrobert #define SPELLING_DEPTH() (spelling - spelling_base)
4418404b540aSrobert #define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH))
4419404b540aSrobert 
4420404b540aSrobert /* Push an element on the spelling stack with type KIND and assign VALUE
4421404b540aSrobert    to MEMBER.  */
4422404b540aSrobert 
4423404b540aSrobert #define PUSH_SPELLING(KIND, VALUE, MEMBER)				\
4424404b540aSrobert {									\
4425404b540aSrobert   int depth = SPELLING_DEPTH ();					\
4426404b540aSrobert 									\
4427404b540aSrobert   if (depth >= spelling_size)						\
4428404b540aSrobert     {									\
4429404b540aSrobert       spelling_size += 10;						\
4430404b540aSrobert       spelling_base = XRESIZEVEC (struct spelling, spelling_base,	\
4431404b540aSrobert 				  spelling_size);			\
4432404b540aSrobert       RESTORE_SPELLING_DEPTH (depth);					\
4433404b540aSrobert     }									\
4434404b540aSrobert 									\
4435404b540aSrobert   spelling->kind = (KIND);						\
4436404b540aSrobert   spelling->MEMBER = (VALUE);						\
4437404b540aSrobert   spelling++;								\
4438404b540aSrobert }
4439404b540aSrobert 
4440404b540aSrobert /* Push STRING on the stack.  Printed literally.  */
4441404b540aSrobert 
4442404b540aSrobert static void
push_string(const char * string)4443404b540aSrobert push_string (const char *string)
4444404b540aSrobert {
4445404b540aSrobert   PUSH_SPELLING (SPELLING_STRING, string, u.s);
4446404b540aSrobert }
4447404b540aSrobert 
4448404b540aSrobert /* Push a member name on the stack.  Printed as '.' STRING.  */
4449404b540aSrobert 
4450404b540aSrobert static void
push_member_name(tree decl)4451404b540aSrobert push_member_name (tree decl)
4452404b540aSrobert {
4453404b540aSrobert   const char *const string
4454404b540aSrobert     = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
4455404b540aSrobert   PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
4456404b540aSrobert }
4457404b540aSrobert 
4458404b540aSrobert /* Push an array bounds on the stack.  Printed as [BOUNDS].  */
4459404b540aSrobert 
4460404b540aSrobert static void
push_array_bounds(unsigned HOST_WIDE_INT bounds)4461404b540aSrobert push_array_bounds (unsigned HOST_WIDE_INT bounds)
4462404b540aSrobert {
4463404b540aSrobert   PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
4464404b540aSrobert }
4465404b540aSrobert 
4466404b540aSrobert /* Compute the maximum size in bytes of the printed spelling.  */
4467404b540aSrobert 
4468404b540aSrobert static int
spelling_length(void)4469404b540aSrobert spelling_length (void)
4470404b540aSrobert {
4471404b540aSrobert   int size = 0;
4472404b540aSrobert   struct spelling *p;
4473404b540aSrobert 
4474404b540aSrobert   for (p = spelling_base; p < spelling; p++)
4475404b540aSrobert     {
4476404b540aSrobert       if (p->kind == SPELLING_BOUNDS)
4477404b540aSrobert 	size += 25;
4478404b540aSrobert       else
4479404b540aSrobert 	size += strlen (p->u.s) + 1;
4480404b540aSrobert     }
4481404b540aSrobert 
4482404b540aSrobert   return size;
4483404b540aSrobert }
4484404b540aSrobert 
4485404b540aSrobert /* Print the spelling to BUFFER and return it.  */
4486404b540aSrobert 
4487404b540aSrobert static char *
print_spelling(char * buffer)4488404b540aSrobert print_spelling (char *buffer)
4489404b540aSrobert {
4490404b540aSrobert   char *d = buffer;
4491404b540aSrobert   struct spelling *p;
4492404b540aSrobert 
4493404b540aSrobert   for (p = spelling_base; p < spelling; p++)
4494404b540aSrobert     if (p->kind == SPELLING_BOUNDS)
4495404b540aSrobert       {
4496404b540aSrobert 	sprintf (d, "[" HOST_WIDE_INT_PRINT_UNSIGNED "]", p->u.i);
4497404b540aSrobert 	d += strlen (d);
4498404b540aSrobert       }
4499404b540aSrobert     else
4500404b540aSrobert       {
4501404b540aSrobert 	const char *s;
4502404b540aSrobert 	if (p->kind == SPELLING_MEMBER)
4503404b540aSrobert 	  *d++ = '.';
4504404b540aSrobert 	for (s = p->u.s; (*d = *s++); d++)
4505404b540aSrobert 	  ;
4506404b540aSrobert       }
4507404b540aSrobert   *d++ = '\0';
4508404b540aSrobert   return buffer;
4509404b540aSrobert }
4510404b540aSrobert 
4511404b540aSrobert /* Issue an error message for a bad initializer component.
4512404b540aSrobert    MSGID identifies the message.
4513404b540aSrobert    The component name is taken from the spelling stack.  */
4514404b540aSrobert 
4515404b540aSrobert void
error_init(const char * msgid)4516404b540aSrobert error_init (const char *msgid)
4517404b540aSrobert {
4518404b540aSrobert   char *ofwhat;
4519404b540aSrobert 
4520404b540aSrobert   error ("%s", _(msgid));
4521404b540aSrobert   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
4522404b540aSrobert   if (*ofwhat)
4523404b540aSrobert     error ("(near initialization for %qs)", ofwhat);
4524404b540aSrobert }
4525404b540aSrobert 
4526404b540aSrobert /* Issue a pedantic warning for a bad initializer component.
4527404b540aSrobert    MSGID identifies the message.
4528404b540aSrobert    The component name is taken from the spelling stack.  */
4529404b540aSrobert 
4530404b540aSrobert void
pedwarn_init(const char * msgid)4531404b540aSrobert pedwarn_init (const char *msgid)
4532404b540aSrobert {
4533404b540aSrobert   char *ofwhat;
4534404b540aSrobert 
4535404b540aSrobert   pedwarn ("%s", _(msgid));
4536404b540aSrobert   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
4537404b540aSrobert   if (*ofwhat)
4538404b540aSrobert     pedwarn ("(near initialization for %qs)", ofwhat);
4539404b540aSrobert }
4540404b540aSrobert 
4541404b540aSrobert /* Issue a warning for a bad initializer component.
4542404b540aSrobert    MSGID identifies the message.
4543404b540aSrobert    The component name is taken from the spelling stack.  */
4544404b540aSrobert 
4545404b540aSrobert static void
warning_init(const char * msgid)4546404b540aSrobert warning_init (const char *msgid)
4547404b540aSrobert {
4548404b540aSrobert   char *ofwhat;
4549404b540aSrobert 
4550404b540aSrobert   warning (0, "%s", _(msgid));
4551404b540aSrobert   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
4552404b540aSrobert   if (*ofwhat)
4553404b540aSrobert     warning (0, "(near initialization for %qs)", ofwhat);
4554404b540aSrobert }
4555404b540aSrobert 
4556404b540aSrobert /* If TYPE is an array type and EXPR is a parenthesized string
4557404b540aSrobert    constant, warn if pedantic that EXPR is being used to initialize an
4558404b540aSrobert    object of type TYPE.  */
4559404b540aSrobert 
4560404b540aSrobert void
maybe_warn_string_init(tree type,struct c_expr expr)4561404b540aSrobert maybe_warn_string_init (tree type, struct c_expr expr)
4562404b540aSrobert {
4563404b540aSrobert   if (pedantic
4564404b540aSrobert       && TREE_CODE (type) == ARRAY_TYPE
4565404b540aSrobert       && TREE_CODE (expr.value) == STRING_CST
4566404b540aSrobert       && expr.original_code != STRING_CST)
4567404b540aSrobert     pedwarn_init ("array initialized from parenthesized string constant");
4568404b540aSrobert }
4569404b540aSrobert 
4570404b540aSrobert /* Digest the parser output INIT as an initializer for type TYPE.
4571404b540aSrobert    Return a C expression of type TYPE to represent the initial value.
4572404b540aSrobert 
4573404b540aSrobert    If INIT is a string constant, STRICT_STRING is true if it is
4574404b540aSrobert    unparenthesized or we should not warn here for it being parenthesized.
4575404b540aSrobert    For other types of INIT, STRICT_STRING is not used.
4576404b540aSrobert 
4577404b540aSrobert    REQUIRE_CONSTANT requests an error if non-constant initializers or
4578404b540aSrobert    elements are seen.  */
4579404b540aSrobert 
4580404b540aSrobert static tree
digest_init(tree type,tree init,bool strict_string,int require_constant)4581404b540aSrobert digest_init (tree type, tree init, bool strict_string, int require_constant)
4582404b540aSrobert {
4583404b540aSrobert   enum tree_code code = TREE_CODE (type);
4584404b540aSrobert   tree inside_init = init;
4585404b540aSrobert 
4586404b540aSrobert   if (type == error_mark_node
4587404b540aSrobert       || !init
4588404b540aSrobert       || init == error_mark_node
4589404b540aSrobert       || TREE_TYPE (init) == error_mark_node)
4590404b540aSrobert     return error_mark_node;
4591404b540aSrobert 
4592404b540aSrobert   STRIP_TYPE_NOPS (inside_init);
4593404b540aSrobert 
4594404b540aSrobert   inside_init = fold (inside_init);
4595404b540aSrobert 
4596404b540aSrobert   /* Initialization of an array of chars from a string constant
4597404b540aSrobert      optionally enclosed in braces.  */
4598404b540aSrobert 
4599404b540aSrobert   if (code == ARRAY_TYPE && inside_init
4600404b540aSrobert       && TREE_CODE (inside_init) == STRING_CST)
4601404b540aSrobert     {
4602404b540aSrobert       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
4603404b540aSrobert       /* Note that an array could be both an array of character type
4604404b540aSrobert 	 and an array of wchar_t if wchar_t is signed char or unsigned
4605404b540aSrobert 	 char.  */
4606404b540aSrobert       bool char_array = (typ1 == char_type_node
4607404b540aSrobert 			 || typ1 == signed_char_type_node
4608404b540aSrobert 			 || typ1 == unsigned_char_type_node);
4609404b540aSrobert       bool wchar_array = !!comptypes (typ1, wchar_type_node);
4610404b540aSrobert       if (char_array || wchar_array)
4611404b540aSrobert 	{
4612404b540aSrobert 	  struct c_expr expr;
4613404b540aSrobert 	  bool char_string;
4614404b540aSrobert 	  expr.value = inside_init;
4615404b540aSrobert 	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
4616404b540aSrobert 	  maybe_warn_string_init (type, expr);
4617404b540aSrobert 
4618404b540aSrobert 	  char_string
4619404b540aSrobert 	    = (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
4620404b540aSrobert 	       == char_type_node);
4621404b540aSrobert 
4622404b540aSrobert 	  if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
4623404b540aSrobert 			 TYPE_MAIN_VARIANT (type)))
4624404b540aSrobert 	    return inside_init;
4625404b540aSrobert 
4626404b540aSrobert 	  if (!wchar_array && !char_string)
4627404b540aSrobert 	    {
4628404b540aSrobert 	      error_init ("char-array initialized from wide string");
4629404b540aSrobert 	      return error_mark_node;
4630404b540aSrobert 	    }
4631404b540aSrobert 	  if (char_string && !char_array)
4632404b540aSrobert 	    {
4633404b540aSrobert 	      error_init ("wchar_t-array initialized from non-wide string");
4634404b540aSrobert 	      return error_mark_node;
4635404b540aSrobert 	    }
4636404b540aSrobert 
4637404b540aSrobert 	  TREE_TYPE (inside_init) = type;
4638404b540aSrobert 	  if (TYPE_DOMAIN (type) != 0
4639404b540aSrobert 	      && TYPE_SIZE (type) != 0
4640404b540aSrobert 	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
4641404b540aSrobert 	      /* Subtract 1 (or sizeof (wchar_t))
4642404b540aSrobert 		 because it's ok to ignore the terminating null char
4643404b540aSrobert 		 that is counted in the length of the constant.  */
4644404b540aSrobert 	      && 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
4645404b540aSrobert 				       TREE_STRING_LENGTH (inside_init)
4646404b540aSrobert 				       - ((TYPE_PRECISION (typ1)
4647404b540aSrobert 					   != TYPE_PRECISION (char_type_node))
4648404b540aSrobert 					  ? (TYPE_PRECISION (wchar_type_node)
4649404b540aSrobert 					     / BITS_PER_UNIT)
4650404b540aSrobert 					  : 1)))
4651404b540aSrobert 	    pedwarn_init ("initializer-string for array of chars is too long");
4652404b540aSrobert 
4653404b540aSrobert 	  return inside_init;
4654404b540aSrobert 	}
4655404b540aSrobert       else if (INTEGRAL_TYPE_P (typ1))
4656404b540aSrobert 	{
4657404b540aSrobert 	  error_init ("array of inappropriate type initialized "
4658404b540aSrobert 		      "from string constant");
4659404b540aSrobert 	  return error_mark_node;
4660404b540aSrobert 	}
4661404b540aSrobert     }
4662404b540aSrobert 
4663404b540aSrobert   /* Build a VECTOR_CST from a *constant* vector constructor.  If the
4664404b540aSrobert      vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
4665404b540aSrobert      below and handle as a constructor.  */
4666404b540aSrobert   if (code == VECTOR_TYPE
4667404b540aSrobert       && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE
4668404b540aSrobert       && vector_types_convertible_p (TREE_TYPE (inside_init), type)
4669404b540aSrobert       && TREE_CONSTANT (inside_init))
4670404b540aSrobert     {
4671404b540aSrobert       if (TREE_CODE (inside_init) == VECTOR_CST
4672404b540aSrobert 	  && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
4673404b540aSrobert 			TYPE_MAIN_VARIANT (type)))
4674404b540aSrobert 	return inside_init;
4675404b540aSrobert 
4676404b540aSrobert       if (TREE_CODE (inside_init) == CONSTRUCTOR)
4677404b540aSrobert 	{
4678404b540aSrobert 	  unsigned HOST_WIDE_INT ix;
4679404b540aSrobert 	  tree value;
4680404b540aSrobert 	  bool constant_p = true;
4681404b540aSrobert 
4682404b540aSrobert 	  /* Iterate through elements and check if all constructor
4683404b540aSrobert 	     elements are *_CSTs.  */
4684404b540aSrobert 	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value)
4685404b540aSrobert 	    if (!CONSTANT_CLASS_P (value))
4686404b540aSrobert 	      {
4687404b540aSrobert 		constant_p = false;
4688404b540aSrobert 		break;
4689404b540aSrobert 	      }
4690404b540aSrobert 
4691404b540aSrobert 	  if (constant_p)
4692404b540aSrobert 	    return build_vector_from_ctor (type,
4693404b540aSrobert 					   CONSTRUCTOR_ELTS (inside_init));
4694404b540aSrobert 	}
4695404b540aSrobert     }
4696404b540aSrobert 
4697404b540aSrobert   /* Any type can be initialized
4698404b540aSrobert      from an expression of the same type, optionally with braces.  */
4699404b540aSrobert 
4700404b540aSrobert   if (inside_init && TREE_TYPE (inside_init) != 0
4701404b540aSrobert       && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
4702404b540aSrobert 		     TYPE_MAIN_VARIANT (type))
4703404b540aSrobert 	  || (code == ARRAY_TYPE
4704404b540aSrobert 	      && comptypes (TREE_TYPE (inside_init), type))
4705404b540aSrobert 	  || (code == VECTOR_TYPE
4706404b540aSrobert 	      && comptypes (TREE_TYPE (inside_init), type))
4707404b540aSrobert 	  || (code == POINTER_TYPE
4708404b540aSrobert 	      && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
4709404b540aSrobert 	      && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
4710404b540aSrobert 			    TREE_TYPE (type)))))
4711404b540aSrobert     {
4712404b540aSrobert       if (code == POINTER_TYPE)
4713404b540aSrobert 	{
4714404b540aSrobert 	  if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE)
4715404b540aSrobert 	    {
4716404b540aSrobert 	      if (TREE_CODE (inside_init) == STRING_CST
4717404b540aSrobert 		  || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
4718404b540aSrobert 		inside_init = array_to_pointer_conversion (inside_init);
4719404b540aSrobert 	      else
4720404b540aSrobert 		{
4721404b540aSrobert 		  error_init ("invalid use of non-lvalue array");
4722404b540aSrobert 		  return error_mark_node;
4723404b540aSrobert 		}
4724404b540aSrobert 	    }
4725404b540aSrobert 	}
4726404b540aSrobert 
4727404b540aSrobert       if (code == VECTOR_TYPE)
4728404b540aSrobert 	/* Although the types are compatible, we may require a
4729404b540aSrobert 	   conversion.  */
4730404b540aSrobert 	inside_init = convert (type, inside_init);
4731404b540aSrobert 
4732404b540aSrobert       if (require_constant
4733404b540aSrobert 	  && (code == VECTOR_TYPE || !flag_isoc99)
4734404b540aSrobert 	  && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
4735404b540aSrobert 	{
4736404b540aSrobert 	  /* As an extension, allow initializing objects with static storage
4737404b540aSrobert 	     duration with compound literals (which are then treated just as
4738404b540aSrobert 	     the brace enclosed list they contain).  Also allow this for
4739404b540aSrobert 	     vectors, as we can only assign them with compound literals.  */
4740404b540aSrobert 	  tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
4741404b540aSrobert 	  inside_init = DECL_INITIAL (decl);
4742404b540aSrobert 	}
4743404b540aSrobert 
4744404b540aSrobert       if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
4745404b540aSrobert 	  && TREE_CODE (inside_init) != CONSTRUCTOR)
4746404b540aSrobert 	{
4747404b540aSrobert 	  error_init ("array initialized from non-constant array expression");
4748404b540aSrobert 	  return error_mark_node;
4749404b540aSrobert 	}
4750404b540aSrobert 
4751404b540aSrobert       if (optimize && TREE_CODE (inside_init) == VAR_DECL)
4752404b540aSrobert 	inside_init = decl_constant_value_for_broken_optimization (inside_init);
4753404b540aSrobert 
4754404b540aSrobert       /* Compound expressions can only occur here if -pedantic or
4755404b540aSrobert 	 -pedantic-errors is specified.  In the later case, we always want
4756404b540aSrobert 	 an error.  In the former case, we simply want a warning.  */
4757404b540aSrobert       if (require_constant && pedantic
4758404b540aSrobert 	  && TREE_CODE (inside_init) == COMPOUND_EXPR)
4759404b540aSrobert 	{
4760404b540aSrobert 	  inside_init
4761404b540aSrobert 	    = valid_compound_expr_initializer (inside_init,
4762404b540aSrobert 					       TREE_TYPE (inside_init));
4763404b540aSrobert 	  if (inside_init == error_mark_node)
4764404b540aSrobert 	    error_init ("initializer element is not constant");
4765404b540aSrobert 	  else
4766404b540aSrobert 	    pedwarn_init ("initializer element is not constant");
4767404b540aSrobert 	  if (flag_pedantic_errors)
4768404b540aSrobert 	    inside_init = error_mark_node;
4769404b540aSrobert 	}
4770404b540aSrobert       else if (require_constant
4771404b540aSrobert 	       && !initializer_constant_valid_p (inside_init,
4772404b540aSrobert 						 TREE_TYPE (inside_init)))
4773404b540aSrobert 	{
4774404b540aSrobert 	  error_init ("initializer element is not constant");
4775404b540aSrobert 	  inside_init = error_mark_node;
4776404b540aSrobert 	}
4777404b540aSrobert 
4778404b540aSrobert       /* Added to enable additional -Wmissing-format-attribute warnings.  */
4779404b540aSrobert       if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
4780404b540aSrobert 	inside_init = convert_for_assignment (type, inside_init, ic_init, NULL_TREE,
4781404b540aSrobert 					      NULL_TREE, 0);
4782404b540aSrobert       return inside_init;
4783404b540aSrobert     }
4784404b540aSrobert 
4785404b540aSrobert   /* Handle scalar types, including conversions.  */
4786404b540aSrobert 
4787404b540aSrobert   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
4788404b540aSrobert       || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
4789404b540aSrobert       || code == VECTOR_TYPE)
4790404b540aSrobert     {
4791404b540aSrobert       if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
4792404b540aSrobert 	  && (TREE_CODE (init) == STRING_CST
4793404b540aSrobert 	      || TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
4794404b540aSrobert 	init = array_to_pointer_conversion (init);
4795404b540aSrobert       inside_init
4796404b540aSrobert 	= convert_for_assignment (type, init, ic_init,
4797404b540aSrobert 				  NULL_TREE, NULL_TREE, 0);
4798404b540aSrobert 
4799404b540aSrobert       /* Check to see if we have already given an error message.  */
4800404b540aSrobert       if (inside_init == error_mark_node)
4801404b540aSrobert 	;
4802404b540aSrobert       else if (require_constant && !TREE_CONSTANT (inside_init))
4803404b540aSrobert 	{
4804404b540aSrobert 	  error_init ("initializer element is not constant");
4805404b540aSrobert 	  inside_init = error_mark_node;
4806404b540aSrobert 	}
4807404b540aSrobert       else if (require_constant
4808404b540aSrobert 	       && !initializer_constant_valid_p (inside_init,
4809404b540aSrobert 						 TREE_TYPE (inside_init)))
4810404b540aSrobert 	{
4811404b540aSrobert 	  error_init ("initializer element is not computable at load time");
4812404b540aSrobert 	  inside_init = error_mark_node;
4813404b540aSrobert 	}
4814404b540aSrobert 
4815404b540aSrobert       return inside_init;
4816404b540aSrobert     }
4817404b540aSrobert 
4818404b540aSrobert   /* Come here only for records and arrays.  */
4819404b540aSrobert 
4820404b540aSrobert   if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
4821404b540aSrobert     {
4822404b540aSrobert       error_init ("variable-sized object may not be initialized");
4823404b540aSrobert       return error_mark_node;
4824404b540aSrobert     }
4825404b540aSrobert 
4826404b540aSrobert   error_init ("invalid initializer");
4827404b540aSrobert   return error_mark_node;
4828404b540aSrobert }
4829404b540aSrobert 
4830404b540aSrobert /* Handle initializers that use braces.  */
4831404b540aSrobert 
4832404b540aSrobert /* Type of object we are accumulating a constructor for.
4833404b540aSrobert    This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE.  */
4834404b540aSrobert static tree constructor_type;
4835404b540aSrobert 
4836404b540aSrobert /* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields
4837404b540aSrobert    left to fill.  */
4838404b540aSrobert static tree constructor_fields;
4839404b540aSrobert 
4840404b540aSrobert /* For an ARRAY_TYPE, this is the specified index
4841404b540aSrobert    at which to store the next element we get.  */
4842404b540aSrobert static tree constructor_index;
4843404b540aSrobert 
4844404b540aSrobert /* For an ARRAY_TYPE, this is the maximum index.  */
4845404b540aSrobert static tree constructor_max_index;
4846404b540aSrobert 
4847404b540aSrobert /* For a RECORD_TYPE, this is the first field not yet written out.  */
4848404b540aSrobert static tree constructor_unfilled_fields;
4849404b540aSrobert 
4850404b540aSrobert /* For an ARRAY_TYPE, this is the index of the first element
4851404b540aSrobert    not yet written out.  */
4852404b540aSrobert static tree constructor_unfilled_index;
4853404b540aSrobert 
4854404b540aSrobert /* In a RECORD_TYPE, the byte index of the next consecutive field.
4855404b540aSrobert    This is so we can generate gaps between fields, when appropriate.  */
4856404b540aSrobert static tree constructor_bit_index;
4857404b540aSrobert 
4858404b540aSrobert /* If we are saving up the elements rather than allocating them,
4859404b540aSrobert    this is the list of elements so far (in reverse order,
4860404b540aSrobert    most recent first).  */
4861404b540aSrobert static VEC(constructor_elt,gc) *constructor_elements;
4862404b540aSrobert 
4863404b540aSrobert /* 1 if constructor should be incrementally stored into a constructor chain,
4864404b540aSrobert    0 if all the elements should be kept in AVL tree.  */
4865404b540aSrobert static int constructor_incremental;
4866404b540aSrobert 
4867404b540aSrobert /* 1 if so far this constructor's elements are all compile-time constants.  */
4868404b540aSrobert static int constructor_constant;
4869404b540aSrobert 
4870404b540aSrobert /* 1 if so far this constructor's elements are all valid address constants.  */
4871404b540aSrobert static int constructor_simple;
4872404b540aSrobert 
4873404b540aSrobert /* 1 if this constructor is erroneous so far.  */
4874404b540aSrobert static int constructor_erroneous;
4875404b540aSrobert 
4876*64bcbf86Sclaudio /* 1 if this constructor is a zero init. */
4877*64bcbf86Sclaudio static int constructor_zeroinit;
4878*64bcbf86Sclaudio 
4879404b540aSrobert /* Structure for managing pending initializer elements, organized as an
4880404b540aSrobert    AVL tree.  */
4881404b540aSrobert 
4882404b540aSrobert struct init_node
4883404b540aSrobert {
4884404b540aSrobert   struct init_node *left, *right;
4885404b540aSrobert   struct init_node *parent;
4886404b540aSrobert   int balance;
4887404b540aSrobert   tree purpose;
4888404b540aSrobert   tree value;
4889404b540aSrobert };
4890404b540aSrobert 
4891404b540aSrobert /* Tree of pending elements at this constructor level.
4892404b540aSrobert    These are elements encountered out of order
4893404b540aSrobert    which belong at places we haven't reached yet in actually
4894404b540aSrobert    writing the output.
4895404b540aSrobert    Will never hold tree nodes across GC runs.  */
4896404b540aSrobert static struct init_node *constructor_pending_elts;
4897404b540aSrobert 
4898404b540aSrobert /* The SPELLING_DEPTH of this constructor.  */
4899404b540aSrobert static int constructor_depth;
4900404b540aSrobert 
4901404b540aSrobert /* DECL node for which an initializer is being read.
4902404b540aSrobert    0 means we are reading a constructor expression
4903404b540aSrobert    such as (struct foo) {...}.  */
4904404b540aSrobert static tree constructor_decl;
4905404b540aSrobert 
4906404b540aSrobert /* Nonzero if this is an initializer for a top-level decl.  */
4907404b540aSrobert static int constructor_top_level;
4908404b540aSrobert 
4909404b540aSrobert /* Nonzero if there were any member designators in this initializer.  */
4910404b540aSrobert static int constructor_designated;
4911404b540aSrobert 
4912404b540aSrobert /* Nesting depth of designator list.  */
4913404b540aSrobert static int designator_depth;
4914404b540aSrobert 
4915404b540aSrobert /* Nonzero if there were diagnosed errors in this designator list.  */
4916404b540aSrobert static int designator_erroneous;
4917404b540aSrobert 
4918404b540aSrobert 
4919404b540aSrobert /* This stack has a level for each implicit or explicit level of
4920404b540aSrobert    structuring in the initializer, including the outermost one.  It
4921404b540aSrobert    saves the values of most of the variables above.  */
4922404b540aSrobert 
4923404b540aSrobert struct constructor_range_stack;
4924404b540aSrobert 
4925404b540aSrobert struct constructor_stack
4926404b540aSrobert {
4927404b540aSrobert   struct constructor_stack *next;
4928404b540aSrobert   tree type;
4929404b540aSrobert   tree fields;
4930404b540aSrobert   tree index;
4931404b540aSrobert   tree max_index;
4932404b540aSrobert   tree unfilled_index;
4933404b540aSrobert   tree unfilled_fields;
4934404b540aSrobert   tree bit_index;
4935404b540aSrobert   VEC(constructor_elt,gc) *elements;
4936404b540aSrobert   struct init_node *pending_elts;
4937404b540aSrobert   int offset;
4938404b540aSrobert   int depth;
4939404b540aSrobert   /* If value nonzero, this value should replace the entire
4940404b540aSrobert      constructor at this level.  */
4941404b540aSrobert   struct c_expr replacement_value;
4942404b540aSrobert   struct constructor_range_stack *range_stack;
4943404b540aSrobert   char constant;
4944404b540aSrobert   char simple;
4945404b540aSrobert   char implicit;
4946404b540aSrobert   char erroneous;
4947404b540aSrobert   char outer;
4948404b540aSrobert   char incremental;
4949404b540aSrobert   char designated;
4950404b540aSrobert };
4951404b540aSrobert 
4952404b540aSrobert static struct constructor_stack *constructor_stack;
4953404b540aSrobert 
4954404b540aSrobert /* This stack represents designators from some range designator up to
4955404b540aSrobert    the last designator in the list.  */
4956404b540aSrobert 
4957404b540aSrobert struct constructor_range_stack
4958404b540aSrobert {
4959404b540aSrobert   struct constructor_range_stack *next, *prev;
4960404b540aSrobert   struct constructor_stack *stack;
4961404b540aSrobert   tree range_start;
4962404b540aSrobert   tree index;
4963404b540aSrobert   tree range_end;
4964404b540aSrobert   tree fields;
4965404b540aSrobert };
4966404b540aSrobert 
4967404b540aSrobert static struct constructor_range_stack *constructor_range_stack;
4968404b540aSrobert 
4969404b540aSrobert /* This stack records separate initializers that are nested.
4970404b540aSrobert    Nested initializers can't happen in ANSI C, but GNU C allows them
4971404b540aSrobert    in cases like { ... (struct foo) { ... } ... }.  */
4972404b540aSrobert 
4973404b540aSrobert struct initializer_stack
4974404b540aSrobert {
4975404b540aSrobert   struct initializer_stack *next;
4976404b540aSrobert   tree decl;
4977404b540aSrobert   struct constructor_stack *constructor_stack;
4978404b540aSrobert   struct constructor_range_stack *constructor_range_stack;
4979404b540aSrobert   VEC(constructor_elt,gc) *elements;
4980404b540aSrobert   struct spelling *spelling;
4981404b540aSrobert   struct spelling *spelling_base;
4982404b540aSrobert   int spelling_size;
4983404b540aSrobert   char top_level;
4984404b540aSrobert   char require_constant_value;
4985404b540aSrobert   char require_constant_elements;
4986404b540aSrobert };
4987404b540aSrobert 
4988404b540aSrobert static struct initializer_stack *initializer_stack;
4989404b540aSrobert 
4990404b540aSrobert /* Prepare to parse and output the initializer for variable DECL.  */
4991404b540aSrobert 
4992404b540aSrobert void
start_init(tree decl,tree asmspec_tree ATTRIBUTE_UNUSED,int top_level)4993404b540aSrobert start_init (tree decl, tree asmspec_tree ATTRIBUTE_UNUSED, int top_level)
4994404b540aSrobert {
4995404b540aSrobert   const char *locus;
4996404b540aSrobert   struct initializer_stack *p = XNEW (struct initializer_stack);
4997404b540aSrobert 
4998404b540aSrobert   p->decl = constructor_decl;
4999404b540aSrobert   p->require_constant_value = require_constant_value;
5000404b540aSrobert   p->require_constant_elements = require_constant_elements;
5001404b540aSrobert   p->constructor_stack = constructor_stack;
5002404b540aSrobert   p->constructor_range_stack = constructor_range_stack;
5003404b540aSrobert   p->elements = constructor_elements;
5004404b540aSrobert   p->spelling = spelling;
5005404b540aSrobert   p->spelling_base = spelling_base;
5006404b540aSrobert   p->spelling_size = spelling_size;
5007404b540aSrobert   p->top_level = constructor_top_level;
5008404b540aSrobert   p->next = initializer_stack;
5009404b540aSrobert   initializer_stack = p;
5010404b540aSrobert 
5011404b540aSrobert   constructor_decl = decl;
5012404b540aSrobert   constructor_designated = 0;
5013404b540aSrobert   constructor_top_level = top_level;
5014404b540aSrobert 
5015404b540aSrobert   if (decl != 0 && decl != error_mark_node)
5016404b540aSrobert     {
5017404b540aSrobert       require_constant_value = TREE_STATIC (decl);
5018404b540aSrobert       require_constant_elements
5019404b540aSrobert 	= ((TREE_STATIC (decl) || (pedantic && !flag_isoc99))
5020404b540aSrobert 	   /* For a scalar, you can always use any value to initialize,
5021404b540aSrobert 	      even within braces.  */
5022404b540aSrobert 	   && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
5023404b540aSrobert 	       || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
5024404b540aSrobert 	       || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
5025404b540aSrobert 	       || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
5026404b540aSrobert       locus = IDENTIFIER_POINTER (DECL_NAME (decl));
5027404b540aSrobert     }
5028404b540aSrobert   else
5029404b540aSrobert     {
5030404b540aSrobert       require_constant_value = 0;
5031404b540aSrobert       require_constant_elements = 0;
5032404b540aSrobert       locus = "(anonymous)";
5033404b540aSrobert     }
5034404b540aSrobert 
5035404b540aSrobert   constructor_stack = 0;
5036404b540aSrobert   constructor_range_stack = 0;
5037404b540aSrobert 
5038*64bcbf86Sclaudio   constructor_zeroinit = 0;
5039404b540aSrobert   missing_braces_mentioned = 0;
5040404b540aSrobert 
5041404b540aSrobert   spelling_base = 0;
5042404b540aSrobert   spelling_size = 0;
5043404b540aSrobert   RESTORE_SPELLING_DEPTH (0);
5044404b540aSrobert 
5045404b540aSrobert   if (locus)
5046404b540aSrobert     push_string (locus);
5047404b540aSrobert }
5048404b540aSrobert 
5049404b540aSrobert void
finish_init(void)5050404b540aSrobert finish_init (void)
5051404b540aSrobert {
5052404b540aSrobert   struct initializer_stack *p = initializer_stack;
5053404b540aSrobert 
5054404b540aSrobert   /* Free the whole constructor stack of this initializer.  */
5055404b540aSrobert   while (constructor_stack)
5056404b540aSrobert     {
5057404b540aSrobert       struct constructor_stack *q = constructor_stack;
5058404b540aSrobert       constructor_stack = q->next;
5059404b540aSrobert       free (q);
5060404b540aSrobert     }
5061404b540aSrobert 
5062404b540aSrobert   gcc_assert (!constructor_range_stack);
5063404b540aSrobert 
5064404b540aSrobert   /* Pop back to the data of the outer initializer (if any).  */
5065404b540aSrobert   free (spelling_base);
5066404b540aSrobert 
5067404b540aSrobert   constructor_decl = p->decl;
5068404b540aSrobert   require_constant_value = p->require_constant_value;
5069404b540aSrobert   require_constant_elements = p->require_constant_elements;
5070404b540aSrobert   constructor_stack = p->constructor_stack;
5071404b540aSrobert   constructor_range_stack = p->constructor_range_stack;
5072404b540aSrobert   constructor_elements = p->elements;
5073404b540aSrobert   spelling = p->spelling;
5074404b540aSrobert   spelling_base = p->spelling_base;
5075404b540aSrobert   spelling_size = p->spelling_size;
5076404b540aSrobert   constructor_top_level = p->top_level;
5077404b540aSrobert   initializer_stack = p->next;
5078404b540aSrobert   free (p);
5079404b540aSrobert }
5080404b540aSrobert 
5081404b540aSrobert /* Call here when we see the initializer is surrounded by braces.
5082404b540aSrobert    This is instead of a call to push_init_level;
5083404b540aSrobert    it is matched by a call to pop_init_level.
5084404b540aSrobert 
5085404b540aSrobert    TYPE is the type to initialize, for a constructor expression.
5086404b540aSrobert    For an initializer for a decl, TYPE is zero.  */
5087404b540aSrobert 
5088404b540aSrobert void
really_start_incremental_init(tree type)5089404b540aSrobert really_start_incremental_init (tree type)
5090404b540aSrobert {
5091404b540aSrobert   struct constructor_stack *p = XNEW (struct constructor_stack);
5092404b540aSrobert 
5093404b540aSrobert   if (type == 0)
5094404b540aSrobert     type = TREE_TYPE (constructor_decl);
5095404b540aSrobert 
5096404b540aSrobert   if (targetm.vector_opaque_p (type))
5097404b540aSrobert     error ("opaque vector types cannot be initialized");
5098404b540aSrobert 
5099404b540aSrobert   p->type = constructor_type;
5100404b540aSrobert   p->fields = constructor_fields;
5101404b540aSrobert   p->index = constructor_index;
5102404b540aSrobert   p->max_index = constructor_max_index;
5103404b540aSrobert   p->unfilled_index = constructor_unfilled_index;
5104404b540aSrobert   p->unfilled_fields = constructor_unfilled_fields;
5105404b540aSrobert   p->bit_index = constructor_bit_index;
5106404b540aSrobert   p->elements = constructor_elements;
5107404b540aSrobert   p->constant = constructor_constant;
5108404b540aSrobert   p->simple = constructor_simple;
5109404b540aSrobert   p->erroneous = constructor_erroneous;
5110404b540aSrobert   p->pending_elts = constructor_pending_elts;
5111404b540aSrobert   p->depth = constructor_depth;
5112404b540aSrobert   p->replacement_value.value = 0;
5113404b540aSrobert   p->replacement_value.original_code = ERROR_MARK;
5114404b540aSrobert   p->implicit = 0;
5115404b540aSrobert   p->range_stack = 0;
5116404b540aSrobert   p->outer = 0;
5117404b540aSrobert   p->incremental = constructor_incremental;
5118404b540aSrobert   p->designated = constructor_designated;
5119404b540aSrobert   p->next = 0;
5120404b540aSrobert   constructor_stack = p;
5121404b540aSrobert 
5122404b540aSrobert   constructor_constant = 1;
5123404b540aSrobert   constructor_simple = 1;
5124404b540aSrobert   constructor_depth = SPELLING_DEPTH ();
5125404b540aSrobert   constructor_elements = 0;
5126404b540aSrobert   constructor_pending_elts = 0;
5127404b540aSrobert   constructor_type = type;
5128404b540aSrobert   constructor_incremental = 1;
5129404b540aSrobert   constructor_designated = 0;
5130404b540aSrobert   designator_depth = 0;
5131404b540aSrobert   designator_erroneous = 0;
5132404b540aSrobert 
5133404b540aSrobert   if (TREE_CODE (constructor_type) == RECORD_TYPE
5134404b540aSrobert       || TREE_CODE (constructor_type) == UNION_TYPE)
5135404b540aSrobert     {
5136404b540aSrobert       constructor_fields = TYPE_FIELDS (constructor_type);
5137404b540aSrobert       /* Skip any nameless bit fields at the beginning.  */
5138404b540aSrobert       while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
5139404b540aSrobert 	     && DECL_NAME (constructor_fields) == 0)
5140404b540aSrobert 	constructor_fields = TREE_CHAIN (constructor_fields);
5141404b540aSrobert 
5142404b540aSrobert       constructor_unfilled_fields = constructor_fields;
5143404b540aSrobert       constructor_bit_index = bitsize_zero_node;
5144404b540aSrobert     }
5145404b540aSrobert   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
5146404b540aSrobert     {
5147404b540aSrobert       if (TYPE_DOMAIN (constructor_type))
5148404b540aSrobert 	{
5149404b540aSrobert 	  constructor_max_index
5150404b540aSrobert 	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
5151404b540aSrobert 
5152404b540aSrobert 	  /* Detect non-empty initializations of zero-length arrays.  */
5153404b540aSrobert 	  if (constructor_max_index == NULL_TREE
5154404b540aSrobert 	      && TYPE_SIZE (constructor_type))
5155404b540aSrobert 	    constructor_max_index = build_int_cst (NULL_TREE, -1);
5156404b540aSrobert 
5157404b540aSrobert 	  /* constructor_max_index needs to be an INTEGER_CST.  Attempts
5158404b540aSrobert 	     to initialize VLAs will cause a proper error; avoid tree
5159404b540aSrobert 	     checking errors as well by setting a safe value.  */
5160404b540aSrobert 	  if (constructor_max_index
5161404b540aSrobert 	      && TREE_CODE (constructor_max_index) != INTEGER_CST)
5162404b540aSrobert 	    constructor_max_index = build_int_cst (NULL_TREE, -1);
5163404b540aSrobert 
5164404b540aSrobert 	  constructor_index
5165404b540aSrobert 	    = convert (bitsizetype,
5166404b540aSrobert 		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
5167404b540aSrobert 	}
5168404b540aSrobert       else
5169404b540aSrobert 	{
5170404b540aSrobert 	  constructor_index = bitsize_zero_node;
5171404b540aSrobert 	  constructor_max_index = NULL_TREE;
5172404b540aSrobert 	}
5173404b540aSrobert 
5174404b540aSrobert       constructor_unfilled_index = constructor_index;
5175404b540aSrobert     }
5176404b540aSrobert   else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
5177404b540aSrobert     {
5178404b540aSrobert       /* Vectors are like simple fixed-size arrays.  */
5179404b540aSrobert       constructor_max_index =
5180404b540aSrobert 	build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1);
5181404b540aSrobert       constructor_index = bitsize_zero_node;
5182404b540aSrobert       constructor_unfilled_index = constructor_index;
5183404b540aSrobert     }
5184404b540aSrobert   else
5185404b540aSrobert     {
5186404b540aSrobert       /* Handle the case of int x = {5}; */
5187404b540aSrobert       constructor_fields = constructor_type;
5188404b540aSrobert       constructor_unfilled_fields = constructor_type;
5189404b540aSrobert     }
5190404b540aSrobert }
5191404b540aSrobert 
5192404b540aSrobert /* Push down into a subobject, for initialization.
5193404b540aSrobert    If this is for an explicit set of braces, IMPLICIT is 0.
5194404b540aSrobert    If it is because the next element belongs at a lower level,
5195404b540aSrobert    IMPLICIT is 1 (or 2 if the push is because of designator list).  */
5196404b540aSrobert 
5197404b540aSrobert void
push_init_level(int implicit)5198404b540aSrobert push_init_level (int implicit)
5199404b540aSrobert {
5200404b540aSrobert   struct constructor_stack *p;
5201404b540aSrobert   tree value = NULL_TREE;
5202404b540aSrobert 
5203404b540aSrobert   /* If we've exhausted any levels that didn't have braces,
5204404b540aSrobert      pop them now.  If implicit == 1, this will have been done in
5205404b540aSrobert      process_init_element; do not repeat it here because in the case
5206404b540aSrobert      of excess initializers for an empty aggregate this leads to an
5207404b540aSrobert      infinite cycle of popping a level and immediately recreating
5208404b540aSrobert      it.  */
5209404b540aSrobert   if (implicit != 1)
5210404b540aSrobert     {
5211404b540aSrobert       while (constructor_stack->implicit)
5212404b540aSrobert 	{
5213404b540aSrobert 	  if ((TREE_CODE (constructor_type) == RECORD_TYPE
5214404b540aSrobert 	       || TREE_CODE (constructor_type) == UNION_TYPE)
5215404b540aSrobert 	      && constructor_fields == 0)
5216404b540aSrobert 	    process_init_element (pop_init_level (1));
5217404b540aSrobert 	  else if (TREE_CODE (constructor_type) == ARRAY_TYPE
5218404b540aSrobert 		   && constructor_max_index
5219404b540aSrobert 		   && tree_int_cst_lt (constructor_max_index,
5220404b540aSrobert 				       constructor_index))
5221404b540aSrobert 	    process_init_element (pop_init_level (1));
5222404b540aSrobert 	  else
5223404b540aSrobert 	    break;
5224404b540aSrobert 	}
5225404b540aSrobert     }
5226404b540aSrobert 
5227404b540aSrobert   /* Unless this is an explicit brace, we need to preserve previous
5228404b540aSrobert      content if any.  */
5229404b540aSrobert   if (implicit)
5230404b540aSrobert     {
5231404b540aSrobert       if ((TREE_CODE (constructor_type) == RECORD_TYPE
5232404b540aSrobert 	   || TREE_CODE (constructor_type) == UNION_TYPE)
5233404b540aSrobert 	  && constructor_fields)
5234404b540aSrobert 	value = find_init_member (constructor_fields);
5235404b540aSrobert       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
5236404b540aSrobert 	value = find_init_member (constructor_index);
5237404b540aSrobert     }
5238404b540aSrobert 
5239404b540aSrobert   p = XNEW (struct constructor_stack);
5240404b540aSrobert   p->type = constructor_type;
5241404b540aSrobert   p->fields = constructor_fields;
5242404b540aSrobert   p->index = constructor_index;
5243404b540aSrobert   p->max_index = constructor_max_index;
5244404b540aSrobert   p->unfilled_index = constructor_unfilled_index;
5245404b540aSrobert   p->unfilled_fields = constructor_unfilled_fields;
5246404b540aSrobert   p->bit_index = constructor_bit_index;
5247404b540aSrobert   p->elements = constructor_elements;
5248404b540aSrobert   p->constant = constructor_constant;
5249404b540aSrobert   p->simple = constructor_simple;
5250404b540aSrobert   p->erroneous = constructor_erroneous;
5251404b540aSrobert   p->pending_elts = constructor_pending_elts;
5252404b540aSrobert   p->depth = constructor_depth;
5253404b540aSrobert   p->replacement_value.value = 0;
5254404b540aSrobert   p->replacement_value.original_code = ERROR_MARK;
5255404b540aSrobert   p->implicit = implicit;
5256404b540aSrobert   p->outer = 0;
5257404b540aSrobert   p->incremental = constructor_incremental;
5258404b540aSrobert   p->designated = constructor_designated;
5259404b540aSrobert   p->next = constructor_stack;
5260404b540aSrobert   p->range_stack = 0;
5261404b540aSrobert   constructor_stack = p;
5262404b540aSrobert 
5263404b540aSrobert   constructor_constant = 1;
5264404b540aSrobert   constructor_simple = 1;
5265404b540aSrobert   constructor_depth = SPELLING_DEPTH ();
5266404b540aSrobert   constructor_elements = 0;
5267404b540aSrobert   constructor_incremental = 1;
5268404b540aSrobert   constructor_designated = 0;
5269404b540aSrobert   constructor_pending_elts = 0;
5270404b540aSrobert   if (!implicit)
5271404b540aSrobert     {
5272404b540aSrobert       p->range_stack = constructor_range_stack;
5273404b540aSrobert       constructor_range_stack = 0;
5274404b540aSrobert       designator_depth = 0;
5275404b540aSrobert       designator_erroneous = 0;
5276404b540aSrobert     }
5277404b540aSrobert 
5278404b540aSrobert   /* Don't die if an entire brace-pair level is superfluous
5279404b540aSrobert      in the containing level.  */
5280404b540aSrobert   if (constructor_type == 0)
5281404b540aSrobert     ;
5282404b540aSrobert   else if (TREE_CODE (constructor_type) == RECORD_TYPE
5283404b540aSrobert 	   || TREE_CODE (constructor_type) == UNION_TYPE)
5284404b540aSrobert     {
5285404b540aSrobert       /* Don't die if there are extra init elts at the end.  */
5286404b540aSrobert       if (constructor_fields == 0)
5287404b540aSrobert 	constructor_type = 0;
5288404b540aSrobert       else
5289404b540aSrobert 	{
5290404b540aSrobert 	  constructor_type = TREE_TYPE (constructor_fields);
5291404b540aSrobert 	  push_member_name (constructor_fields);
5292404b540aSrobert 	  constructor_depth++;
5293404b540aSrobert 	}
5294404b540aSrobert     }
5295404b540aSrobert   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
5296404b540aSrobert     {
5297404b540aSrobert       constructor_type = TREE_TYPE (constructor_type);
5298404b540aSrobert       push_array_bounds (tree_low_cst (constructor_index, 1));
5299404b540aSrobert       constructor_depth++;
5300404b540aSrobert     }
5301404b540aSrobert 
5302404b540aSrobert   if (constructor_type == 0)
5303404b540aSrobert     {
5304404b540aSrobert       error_init ("extra brace group at end of initializer");
5305404b540aSrobert       constructor_fields = 0;
5306404b540aSrobert       constructor_unfilled_fields = 0;
5307404b540aSrobert       return;
5308404b540aSrobert     }
5309404b540aSrobert 
5310404b540aSrobert   if (value && TREE_CODE (value) == CONSTRUCTOR)
5311404b540aSrobert     {
5312404b540aSrobert       constructor_constant = TREE_CONSTANT (value);
5313404b540aSrobert       constructor_simple = TREE_STATIC (value);
5314404b540aSrobert       constructor_elements = CONSTRUCTOR_ELTS (value);
5315404b540aSrobert       if (!VEC_empty (constructor_elt, constructor_elements)
5316404b540aSrobert 	  && (TREE_CODE (constructor_type) == RECORD_TYPE
5317404b540aSrobert 	      || TREE_CODE (constructor_type) == ARRAY_TYPE))
5318404b540aSrobert 	set_nonincremental_init ();
5319404b540aSrobert     }
5320404b540aSrobert 
5321404b540aSrobert   if (TREE_CODE (constructor_type) == RECORD_TYPE
5322404b540aSrobert 	   || TREE_CODE (constructor_type) == UNION_TYPE)
5323404b540aSrobert     {
5324404b540aSrobert       constructor_fields = TYPE_FIELDS (constructor_type);
5325404b540aSrobert       /* Skip any nameless bit fields at the beginning.  */
5326404b540aSrobert       while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
5327404b540aSrobert 	     && DECL_NAME (constructor_fields) == 0)
5328404b540aSrobert 	constructor_fields = TREE_CHAIN (constructor_fields);
5329404b540aSrobert 
5330404b540aSrobert       constructor_unfilled_fields = constructor_fields;
5331404b540aSrobert       constructor_bit_index = bitsize_zero_node;
5332404b540aSrobert     }
5333404b540aSrobert   else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
5334404b540aSrobert     {
5335404b540aSrobert       /* Vectors are like simple fixed-size arrays.  */
5336404b540aSrobert       constructor_max_index =
5337404b540aSrobert 	build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1);
5338404b540aSrobert       constructor_index = convert (bitsizetype, integer_zero_node);
5339404b540aSrobert       constructor_unfilled_index = constructor_index;
5340404b540aSrobert     }
5341404b540aSrobert   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
5342404b540aSrobert     {
5343404b540aSrobert       if (TYPE_DOMAIN (constructor_type))
5344404b540aSrobert 	{
5345404b540aSrobert 	  constructor_max_index
5346404b540aSrobert 	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
5347404b540aSrobert 
5348404b540aSrobert 	  /* Detect non-empty initializations of zero-length arrays.  */
5349404b540aSrobert 	  if (constructor_max_index == NULL_TREE
5350404b540aSrobert 	      && TYPE_SIZE (constructor_type))
5351404b540aSrobert 	    constructor_max_index = build_int_cst (NULL_TREE, -1);
5352404b540aSrobert 
5353404b540aSrobert 	  /* constructor_max_index needs to be an INTEGER_CST.  Attempts
5354404b540aSrobert 	     to initialize VLAs will cause a proper error; avoid tree
5355404b540aSrobert 	     checking errors as well by setting a safe value.  */
5356404b540aSrobert 	  if (constructor_max_index
5357404b540aSrobert 	      && TREE_CODE (constructor_max_index) != INTEGER_CST)
5358404b540aSrobert 	    constructor_max_index = build_int_cst (NULL_TREE, -1);
5359404b540aSrobert 
5360404b540aSrobert 	  constructor_index
5361404b540aSrobert 	    = convert (bitsizetype,
5362404b540aSrobert 		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
5363404b540aSrobert 	}
5364404b540aSrobert       else
5365404b540aSrobert 	constructor_index = bitsize_zero_node;
5366404b540aSrobert 
5367404b540aSrobert       constructor_unfilled_index = constructor_index;
5368404b540aSrobert       if (value && TREE_CODE (value) == STRING_CST)
5369404b540aSrobert 	{
5370404b540aSrobert 	  /* We need to split the char/wchar array into individual
5371404b540aSrobert 	     characters, so that we don't have to special case it
5372404b540aSrobert 	     everywhere.  */
5373404b540aSrobert 	  set_nonincremental_init_from_string (value);
5374404b540aSrobert 	}
5375404b540aSrobert     }
5376404b540aSrobert   else
5377404b540aSrobert     {
5378404b540aSrobert       if (constructor_type != error_mark_node)
5379404b540aSrobert 	warning_init ("braces around scalar initializer");
5380404b540aSrobert       constructor_fields = constructor_type;
5381404b540aSrobert       constructor_unfilled_fields = constructor_type;
5382404b540aSrobert     }
5383404b540aSrobert }
5384404b540aSrobert 
5385404b540aSrobert /* At the end of an implicit or explicit brace level,
5386404b540aSrobert    finish up that level of constructor.  If a single expression
5387404b540aSrobert    with redundant braces initialized that level, return the
5388404b540aSrobert    c_expr structure for that expression.  Otherwise, the original_code
5389404b540aSrobert    element is set to ERROR_MARK.
5390404b540aSrobert    If we were outputting the elements as they are read, return 0 as the value
5391404b540aSrobert    from inner levels (process_init_element ignores that),
5392404b540aSrobert    but return error_mark_node as the value from the outermost level
5393404b540aSrobert    (that's what we want to put in DECL_INITIAL).
5394404b540aSrobert    Otherwise, return a CONSTRUCTOR expression as the value.  */
5395404b540aSrobert 
5396404b540aSrobert struct c_expr
pop_init_level(int implicit)5397404b540aSrobert pop_init_level (int implicit)
5398404b540aSrobert {
5399404b540aSrobert   struct constructor_stack *p;
5400404b540aSrobert   struct c_expr ret;
5401404b540aSrobert   ret.value = 0;
5402404b540aSrobert   ret.original_code = ERROR_MARK;
5403404b540aSrobert 
5404404b540aSrobert   if (implicit == 0)
5405404b540aSrobert     {
5406404b540aSrobert       /* When we come to an explicit close brace,
5407404b540aSrobert 	 pop any inner levels that didn't have explicit braces.  */
5408404b540aSrobert       while (constructor_stack->implicit)
5409404b540aSrobert 	process_init_element (pop_init_level (1));
5410404b540aSrobert 
5411404b540aSrobert       gcc_assert (!constructor_range_stack);
5412404b540aSrobert     }
5413404b540aSrobert 
5414404b540aSrobert   /* Now output all pending elements.  */
5415404b540aSrobert   constructor_incremental = 1;
5416404b540aSrobert   output_pending_init_elements (1);
5417404b540aSrobert 
5418404b540aSrobert   p = constructor_stack;
5419404b540aSrobert 
5420404b540aSrobert   /* Error for initializing a flexible array member, or a zero-length
5421404b540aSrobert      array member in an inappropriate context.  */
5422404b540aSrobert   if (constructor_type && constructor_fields
5423404b540aSrobert       && TREE_CODE (constructor_type) == ARRAY_TYPE
5424404b540aSrobert       && TYPE_DOMAIN (constructor_type)
5425404b540aSrobert       && !TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
5426404b540aSrobert     {
5427404b540aSrobert       /* Silently discard empty initializations.  The parser will
5428404b540aSrobert 	 already have pedwarned for empty brackets.  */
5429404b540aSrobert       if (integer_zerop (constructor_unfilled_index))
5430404b540aSrobert 	constructor_type = NULL_TREE;
5431404b540aSrobert       else
5432404b540aSrobert 	{
5433404b540aSrobert 	  gcc_assert (!TYPE_SIZE (constructor_type));
5434404b540aSrobert 
5435404b540aSrobert 	  if (constructor_depth > 2)
5436404b540aSrobert 	    error_init ("initialization of flexible array member in a nested context");
5437404b540aSrobert 	  else if (pedantic)
5438404b540aSrobert 	    pedwarn_init ("initialization of a flexible array member");
5439404b540aSrobert 
5440404b540aSrobert 	  /* We have already issued an error message for the existence
5441404b540aSrobert 	     of a flexible array member not at the end of the structure.
5442404b540aSrobert 	     Discard the initializer so that we do not die later.  */
5443404b540aSrobert 	  if (TREE_CHAIN (constructor_fields) != NULL_TREE)
5444404b540aSrobert 	    constructor_type = NULL_TREE;
5445404b540aSrobert 	}
5446404b540aSrobert     }
5447404b540aSrobert 
5448*64bcbf86Sclaudio   if (VEC_length (constructor_elt,constructor_elements) == 0)
5449*64bcbf86Sclaudio      constructor_zeroinit = 1;
5450*64bcbf86Sclaudio   else if (VEC_length (constructor_elt,constructor_elements) == 1 &&
5451*64bcbf86Sclaudio       initializer_zerop (VEC_index (constructor_elt,constructor_elements,0)->value))
5452*64bcbf86Sclaudio      constructor_zeroinit = 1;
5453*64bcbf86Sclaudio   else
5454*64bcbf86Sclaudio      constructor_zeroinit = 0;
5455*64bcbf86Sclaudio 
5456*64bcbf86Sclaudio   /* only warn for missing braces unless it is { 0 } */
5457*64bcbf86Sclaudio   if (p->implicit == 1 && warn_missing_braces && !missing_braces_mentioned &&
5458*64bcbf86Sclaudio       !constructor_zeroinit)
5459*64bcbf86Sclaudio     {
5460*64bcbf86Sclaudio       missing_braces_mentioned = 1;
5461*64bcbf86Sclaudio       warning_init ("missing braces around initializer");
5462*64bcbf86Sclaudio     }
5463*64bcbf86Sclaudio 
5464404b540aSrobert   /* Warn when some struct elements are implicitly initialized to zero.  */
5465404b540aSrobert   if (warn_missing_field_initializers
5466404b540aSrobert       && constructor_type
5467404b540aSrobert       && TREE_CODE (constructor_type) == RECORD_TYPE
5468404b540aSrobert       && constructor_unfilled_fields)
5469404b540aSrobert     {
5470404b540aSrobert 	/* Do not warn for flexible array members or zero-length arrays.  */
5471404b540aSrobert 	while (constructor_unfilled_fields
5472404b540aSrobert 	       && (!DECL_SIZE (constructor_unfilled_fields)
5473404b540aSrobert 		   || integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
5474404b540aSrobert 	  constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
5475404b540aSrobert 
5476404b540aSrobert 	/* Do not warn if this level of the initializer uses member
5477404b540aSrobert 	   designators; it is likely to be deliberate.  */
5478404b540aSrobert 	if (constructor_unfilled_fields && !constructor_designated)
5479404b540aSrobert 	  {
5480404b540aSrobert 	    push_member_name (constructor_unfilled_fields);
5481404b540aSrobert 	    warning_init ("missing initializer");
5482404b540aSrobert 	    RESTORE_SPELLING_DEPTH (constructor_depth);
5483404b540aSrobert 	  }
5484404b540aSrobert     }
5485404b540aSrobert 
5486404b540aSrobert   /* Pad out the end of the structure.  */
5487404b540aSrobert   if (p->replacement_value.value)
5488404b540aSrobert     /* If this closes a superfluous brace pair,
5489404b540aSrobert        just pass out the element between them.  */
5490404b540aSrobert     ret = p->replacement_value;
5491404b540aSrobert   else if (constructor_type == 0)
5492404b540aSrobert     ;
5493404b540aSrobert   else if (TREE_CODE (constructor_type) != RECORD_TYPE
5494404b540aSrobert 	   && TREE_CODE (constructor_type) != UNION_TYPE
5495404b540aSrobert 	   && TREE_CODE (constructor_type) != ARRAY_TYPE
5496404b540aSrobert 	   && TREE_CODE (constructor_type) != VECTOR_TYPE)
5497404b540aSrobert     {
5498404b540aSrobert       /* A nonincremental scalar initializer--just return
5499404b540aSrobert 	 the element, after verifying there is just one.  */
5500404b540aSrobert       if (VEC_empty (constructor_elt,constructor_elements))
5501404b540aSrobert 	{
5502404b540aSrobert 	  if (!constructor_erroneous)
5503404b540aSrobert 	    error_init ("empty scalar initializer");
5504404b540aSrobert 	  ret.value = error_mark_node;
5505404b540aSrobert 	}
5506404b540aSrobert       else if (VEC_length (constructor_elt,constructor_elements) != 1)
5507404b540aSrobert 	{
5508404b540aSrobert 	  error_init ("extra elements in scalar initializer");
5509404b540aSrobert 	  ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
5510404b540aSrobert 	}
5511404b540aSrobert       else
5512404b540aSrobert 	ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
5513404b540aSrobert     }
5514404b540aSrobert   else
5515404b540aSrobert     {
5516404b540aSrobert       if (constructor_erroneous)
5517404b540aSrobert 	ret.value = error_mark_node;
5518404b540aSrobert       else
5519404b540aSrobert 	{
5520404b540aSrobert 	  ret.value = build_constructor (constructor_type,
5521404b540aSrobert 					 constructor_elements);
5522404b540aSrobert 	  if (constructor_constant)
5523404b540aSrobert 	    TREE_CONSTANT (ret.value) = TREE_INVARIANT (ret.value) = 1;
5524404b540aSrobert 	  if (constructor_constant && constructor_simple)
5525404b540aSrobert 	    TREE_STATIC (ret.value) = 1;
5526404b540aSrobert 	}
5527404b540aSrobert     }
5528404b540aSrobert 
5529404b540aSrobert   constructor_type = p->type;
5530404b540aSrobert   constructor_fields = p->fields;
5531404b540aSrobert   constructor_index = p->index;
5532404b540aSrobert   constructor_max_index = p->max_index;
5533404b540aSrobert   constructor_unfilled_index = p->unfilled_index;
5534404b540aSrobert   constructor_unfilled_fields = p->unfilled_fields;
5535404b540aSrobert   constructor_bit_index = p->bit_index;
5536404b540aSrobert   constructor_elements = p->elements;
5537404b540aSrobert   constructor_constant = p->constant;
5538404b540aSrobert   constructor_simple = p->simple;
5539404b540aSrobert   constructor_erroneous = p->erroneous;
5540404b540aSrobert   constructor_incremental = p->incremental;
5541404b540aSrobert   constructor_designated = p->designated;
5542404b540aSrobert   constructor_pending_elts = p->pending_elts;
5543404b540aSrobert   constructor_depth = p->depth;
5544404b540aSrobert   if (!p->implicit)
5545404b540aSrobert     constructor_range_stack = p->range_stack;
5546404b540aSrobert   RESTORE_SPELLING_DEPTH (constructor_depth);
5547404b540aSrobert 
5548404b540aSrobert   constructor_stack = p->next;
5549404b540aSrobert   free (p);
5550404b540aSrobert 
5551404b540aSrobert   if (ret.value == 0 && constructor_stack == 0)
5552404b540aSrobert     ret.value = error_mark_node;
5553404b540aSrobert   return ret;
5554404b540aSrobert }
5555404b540aSrobert 
5556404b540aSrobert /* Common handling for both array range and field name designators.
5557404b540aSrobert    ARRAY argument is nonzero for array ranges.  Returns zero for success.  */
5558404b540aSrobert 
5559404b540aSrobert static int
set_designator(int array)5560404b540aSrobert set_designator (int array)
5561404b540aSrobert {
5562404b540aSrobert   tree subtype;
5563404b540aSrobert   enum tree_code subcode;
5564404b540aSrobert 
5565404b540aSrobert   /* Don't die if an entire brace-pair level is superfluous
5566404b540aSrobert      in the containing level.  */
5567404b540aSrobert   if (constructor_type == 0)
5568404b540aSrobert     return 1;
5569404b540aSrobert 
5570404b540aSrobert   /* If there were errors in this designator list already, bail out
5571404b540aSrobert      silently.  */
5572404b540aSrobert   if (designator_erroneous)
5573404b540aSrobert     return 1;
5574404b540aSrobert 
5575404b540aSrobert   if (!designator_depth)
5576404b540aSrobert     {
5577404b540aSrobert       gcc_assert (!constructor_range_stack);
5578404b540aSrobert 
5579404b540aSrobert       /* Designator list starts at the level of closest explicit
5580404b540aSrobert 	 braces.  */
5581404b540aSrobert       while (constructor_stack->implicit)
5582404b540aSrobert 	process_init_element (pop_init_level (1));
5583404b540aSrobert       constructor_designated = 1;
5584404b540aSrobert       return 0;
5585404b540aSrobert     }
5586404b540aSrobert 
5587404b540aSrobert   switch (TREE_CODE (constructor_type))
5588404b540aSrobert     {
5589404b540aSrobert     case  RECORD_TYPE:
5590404b540aSrobert     case  UNION_TYPE:
5591404b540aSrobert       subtype = TREE_TYPE (constructor_fields);
5592404b540aSrobert       if (subtype != error_mark_node)
5593404b540aSrobert 	subtype = TYPE_MAIN_VARIANT (subtype);
5594404b540aSrobert       break;
5595404b540aSrobert     case ARRAY_TYPE:
5596404b540aSrobert       subtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
5597404b540aSrobert       break;
5598404b540aSrobert     default:
5599404b540aSrobert       gcc_unreachable ();
5600404b540aSrobert     }
5601404b540aSrobert 
5602404b540aSrobert   subcode = TREE_CODE (subtype);
5603404b540aSrobert   if (array && subcode != ARRAY_TYPE)
5604404b540aSrobert     {
5605404b540aSrobert       error_init ("array index in non-array initializer");
5606404b540aSrobert       return 1;
5607404b540aSrobert     }
5608404b540aSrobert   else if (!array && subcode != RECORD_TYPE && subcode != UNION_TYPE)
5609404b540aSrobert     {
5610404b540aSrobert       error_init ("field name not in record or union initializer");
5611404b540aSrobert       return 1;
5612404b540aSrobert     }
5613404b540aSrobert 
5614404b540aSrobert   constructor_designated = 1;
5615404b540aSrobert   push_init_level (2);
5616404b540aSrobert   return 0;
5617404b540aSrobert }
5618404b540aSrobert 
5619404b540aSrobert /* If there are range designators in designator list, push a new designator
5620404b540aSrobert    to constructor_range_stack.  RANGE_END is end of such stack range or
5621404b540aSrobert    NULL_TREE if there is no range designator at this level.  */
5622404b540aSrobert 
5623404b540aSrobert static void
push_range_stack(tree range_end)5624404b540aSrobert push_range_stack (tree range_end)
5625404b540aSrobert {
5626404b540aSrobert   struct constructor_range_stack *p;
5627404b540aSrobert 
5628404b540aSrobert   p = GGC_NEW (struct constructor_range_stack);
5629404b540aSrobert   p->prev = constructor_range_stack;
5630404b540aSrobert   p->next = 0;
5631404b540aSrobert   p->fields = constructor_fields;
5632404b540aSrobert   p->range_start = constructor_index;
5633404b540aSrobert   p->index = constructor_index;
5634404b540aSrobert   p->stack = constructor_stack;
5635404b540aSrobert   p->range_end = range_end;
5636404b540aSrobert   if (constructor_range_stack)
5637404b540aSrobert     constructor_range_stack->next = p;
5638404b540aSrobert   constructor_range_stack = p;
5639404b540aSrobert }
5640404b540aSrobert 
5641404b540aSrobert /* Within an array initializer, specify the next index to be initialized.
5642404b540aSrobert    FIRST is that index.  If LAST is nonzero, then initialize a range
5643404b540aSrobert    of indices, running from FIRST through LAST.  */
5644404b540aSrobert 
5645404b540aSrobert void
set_init_index(tree first,tree last)5646404b540aSrobert set_init_index (tree first, tree last)
5647404b540aSrobert {
5648404b540aSrobert   if (set_designator (1))
5649404b540aSrobert     return;
5650404b540aSrobert 
5651404b540aSrobert   designator_erroneous = 1;
5652404b540aSrobert 
5653404b540aSrobert   if (!INTEGRAL_TYPE_P (TREE_TYPE (first))
5654404b540aSrobert       || (last && !INTEGRAL_TYPE_P (TREE_TYPE (last))))
5655404b540aSrobert     {
5656404b540aSrobert       error_init ("array index in initializer not of integer type");
5657404b540aSrobert       return;
5658404b540aSrobert     }
5659404b540aSrobert 
5660404b540aSrobert   if (TREE_CODE (first) != INTEGER_CST)
5661404b540aSrobert     error_init ("nonconstant array index in initializer");
5662404b540aSrobert   else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
5663404b540aSrobert     error_init ("nonconstant array index in initializer");
5664404b540aSrobert   else if (TREE_CODE (constructor_type) != ARRAY_TYPE)
5665404b540aSrobert     error_init ("array index in non-array initializer");
5666404b540aSrobert   else if (tree_int_cst_sgn (first) == -1)
5667404b540aSrobert     error_init ("array index in initializer exceeds array bounds");
5668404b540aSrobert   else if (constructor_max_index
5669404b540aSrobert 	   && tree_int_cst_lt (constructor_max_index, first))
5670404b540aSrobert     error_init ("array index in initializer exceeds array bounds");
5671404b540aSrobert   else
5672404b540aSrobert     {
5673404b540aSrobert       constructor_index = convert (bitsizetype, first);
5674404b540aSrobert 
5675404b540aSrobert       if (last)
5676404b540aSrobert 	{
5677404b540aSrobert 	  if (tree_int_cst_equal (first, last))
5678404b540aSrobert 	    last = 0;
5679404b540aSrobert 	  else if (tree_int_cst_lt (last, first))
5680404b540aSrobert 	    {
5681404b540aSrobert 	      error_init ("empty index range in initializer");
5682404b540aSrobert 	      last = 0;
5683404b540aSrobert 	    }
5684404b540aSrobert 	  else
5685404b540aSrobert 	    {
5686404b540aSrobert 	      last = convert (bitsizetype, last);
5687404b540aSrobert 	      if (constructor_max_index != 0
5688404b540aSrobert 		  && tree_int_cst_lt (constructor_max_index, last))
5689404b540aSrobert 		{
5690404b540aSrobert 		  error_init ("array index range in initializer exceeds array bounds");
5691404b540aSrobert 		  last = 0;
5692404b540aSrobert 		}
5693404b540aSrobert 	    }
5694404b540aSrobert 	}
5695404b540aSrobert 
5696404b540aSrobert       designator_depth++;
5697404b540aSrobert       designator_erroneous = 0;
5698404b540aSrobert       if (constructor_range_stack || last)
5699404b540aSrobert 	push_range_stack (last);
5700404b540aSrobert     }
5701404b540aSrobert }
5702404b540aSrobert 
5703404b540aSrobert /* Within a struct initializer, specify the next field to be initialized.  */
5704404b540aSrobert 
5705404b540aSrobert void
set_init_label(tree fieldname)5706404b540aSrobert set_init_label (tree fieldname)
5707404b540aSrobert {
5708dbc3b72cSkettenis   tree anon = NULL_TREE;
5709404b540aSrobert   tree tail;
5710404b540aSrobert 
5711404b540aSrobert   if (set_designator (0))
5712404b540aSrobert     return;
5713404b540aSrobert 
5714404b540aSrobert   designator_erroneous = 1;
5715404b540aSrobert 
5716404b540aSrobert   if (TREE_CODE (constructor_type) != RECORD_TYPE
5717404b540aSrobert       && TREE_CODE (constructor_type) != UNION_TYPE)
5718404b540aSrobert     {
5719404b540aSrobert       error_init ("field name not in record or union initializer");
5720404b540aSrobert       return;
5721404b540aSrobert     }
5722404b540aSrobert 
5723404b540aSrobert   for (tail = TYPE_FIELDS (constructor_type); tail;
5724404b540aSrobert        tail = TREE_CHAIN (tail))
5725404b540aSrobert     {
5726dbc3b72cSkettenis       if (DECL_NAME (tail) == NULL_TREE
5727dbc3b72cSkettenis 	  && (TREE_CODE (TREE_TYPE (tail)) == RECORD_TYPE
5728dbc3b72cSkettenis 	      || TREE_CODE (TREE_TYPE (tail)) == UNION_TYPE))
5729dbc3b72cSkettenis 	{
5730dbc3b72cSkettenis 	  anon = lookup_field (tail, fieldname);
5731dbc3b72cSkettenis 	  if (anon)
5732dbc3b72cSkettenis 	    break;
5733dbc3b72cSkettenis 	}
5734dbc3b72cSkettenis 
5735404b540aSrobert       if (DECL_NAME (tail) == fieldname)
5736404b540aSrobert 	break;
5737404b540aSrobert     }
5738404b540aSrobert 
5739404b540aSrobert   if (tail == 0)
5740404b540aSrobert     error ("unknown field %qE specified in initializer", fieldname);
5741dbc3b72cSkettenis 
5742dbc3b72cSkettenis   while (tail)
5743404b540aSrobert     {
5744404b540aSrobert       constructor_fields = tail;
5745404b540aSrobert       designator_depth++;
5746404b540aSrobert       designator_erroneous = 0;
5747404b540aSrobert       if (constructor_range_stack)
5748404b540aSrobert 	push_range_stack (NULL_TREE);
5749dbc3b72cSkettenis 
5750dbc3b72cSkettenis       if (anon)
5751dbc3b72cSkettenis 	{
5752dbc3b72cSkettenis 	  if (set_designator (0))
5753dbc3b72cSkettenis 	    return;
5754dbc3b72cSkettenis 	  tail = TREE_VALUE(anon);
5755dbc3b72cSkettenis 	  anon = TREE_CHAIN(anon);
5756dbc3b72cSkettenis 	}
5757dbc3b72cSkettenis       else
5758dbc3b72cSkettenis 	tail = NULL_TREE;
5759404b540aSrobert     }
5760404b540aSrobert }
5761404b540aSrobert 
5762404b540aSrobert /* Add a new initializer to the tree of pending initializers.  PURPOSE
5763404b540aSrobert    identifies the initializer, either array index or field in a structure.
5764404b540aSrobert    VALUE is the value of that index or field.  */
5765404b540aSrobert 
5766404b540aSrobert static void
add_pending_init(tree purpose,tree value)5767404b540aSrobert add_pending_init (tree purpose, tree value)
5768404b540aSrobert {
5769404b540aSrobert   struct init_node *p, **q, *r;
5770404b540aSrobert 
5771404b540aSrobert   q = &constructor_pending_elts;
5772404b540aSrobert   p = 0;
5773404b540aSrobert 
5774404b540aSrobert   if (TREE_CODE (constructor_type) == ARRAY_TYPE)
5775404b540aSrobert     {
5776404b540aSrobert       while (*q != 0)
5777404b540aSrobert 	{
5778404b540aSrobert 	  p = *q;
5779404b540aSrobert 	  if (tree_int_cst_lt (purpose, p->purpose))
5780404b540aSrobert 	    q = &p->left;
5781404b540aSrobert 	  else if (tree_int_cst_lt (p->purpose, purpose))
5782404b540aSrobert 	    q = &p->right;
5783404b540aSrobert 	  else
5784404b540aSrobert 	    {
5785404b540aSrobert 	      if (TREE_SIDE_EFFECTS (p->value))
5786404b540aSrobert 		warning_init ("initialized field with side-effects overwritten");
5787404b540aSrobert 	      else if (warn_override_init)
5788404b540aSrobert 		warning_init ("initialized field overwritten");
5789404b540aSrobert 	      p->value = value;
5790404b540aSrobert 	      return;
5791404b540aSrobert 	    }
5792404b540aSrobert 	}
5793404b540aSrobert     }
5794404b540aSrobert   else
5795404b540aSrobert     {
5796404b540aSrobert       tree bitpos;
5797404b540aSrobert 
5798404b540aSrobert       bitpos = bit_position (purpose);
5799404b540aSrobert       while (*q != NULL)
5800404b540aSrobert 	{
5801404b540aSrobert 	  p = *q;
5802404b540aSrobert 	  if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
5803404b540aSrobert 	    q = &p->left;
5804404b540aSrobert 	  else if (p->purpose != purpose)
5805404b540aSrobert 	    q = &p->right;
5806404b540aSrobert 	  else
5807404b540aSrobert 	    {
5808404b540aSrobert 	      if (TREE_SIDE_EFFECTS (p->value))
5809404b540aSrobert 		warning_init ("initialized field with side-effects overwritten");
5810404b540aSrobert 	      else if (warn_override_init)
5811404b540aSrobert 		warning_init ("initialized field overwritten");
5812404b540aSrobert 	      p->value = value;
5813404b540aSrobert 	      return;
5814404b540aSrobert 	    }
5815404b540aSrobert 	}
5816404b540aSrobert     }
5817404b540aSrobert 
5818404b540aSrobert   r = GGC_NEW (struct init_node);
5819404b540aSrobert   r->purpose = purpose;
5820404b540aSrobert   r->value = value;
5821404b540aSrobert 
5822404b540aSrobert   *q = r;
5823404b540aSrobert   r->parent = p;
5824404b540aSrobert   r->left = 0;
5825404b540aSrobert   r->right = 0;
5826404b540aSrobert   r->balance = 0;
5827404b540aSrobert 
5828404b540aSrobert   while (p)
5829404b540aSrobert     {
5830404b540aSrobert       struct init_node *s;
5831404b540aSrobert 
5832404b540aSrobert       if (r == p->left)
5833404b540aSrobert 	{
5834404b540aSrobert 	  if (p->balance == 0)
5835404b540aSrobert 	    p->balance = -1;
5836404b540aSrobert 	  else if (p->balance < 0)
5837404b540aSrobert 	    {
5838404b540aSrobert 	      if (r->balance < 0)
5839404b540aSrobert 		{
5840404b540aSrobert 		  /* L rotation.  */
5841404b540aSrobert 		  p->left = r->right;
5842404b540aSrobert 		  if (p->left)
5843404b540aSrobert 		    p->left->parent = p;
5844404b540aSrobert 		  r->right = p;
5845404b540aSrobert 
5846404b540aSrobert 		  p->balance = 0;
5847404b540aSrobert 		  r->balance = 0;
5848404b540aSrobert 
5849404b540aSrobert 		  s = p->parent;
5850404b540aSrobert 		  p->parent = r;
5851404b540aSrobert 		  r->parent = s;
5852404b540aSrobert 		  if (s)
5853404b540aSrobert 		    {
5854404b540aSrobert 		      if (s->left == p)
5855404b540aSrobert 			s->left = r;
5856404b540aSrobert 		      else
5857404b540aSrobert 			s->right = r;
5858404b540aSrobert 		    }
5859404b540aSrobert 		  else
5860404b540aSrobert 		    constructor_pending_elts = r;
5861404b540aSrobert 		}
5862404b540aSrobert 	      else
5863404b540aSrobert 		{
5864404b540aSrobert 		  /* LR rotation.  */
5865404b540aSrobert 		  struct init_node *t = r->right;
5866404b540aSrobert 
5867404b540aSrobert 		  r->right = t->left;
5868404b540aSrobert 		  if (r->right)
5869404b540aSrobert 		    r->right->parent = r;
5870404b540aSrobert 		  t->left = r;
5871404b540aSrobert 
5872404b540aSrobert 		  p->left = t->right;
5873404b540aSrobert 		  if (p->left)
5874404b540aSrobert 		    p->left->parent = p;
5875404b540aSrobert 		  t->right = p;
5876404b540aSrobert 
5877404b540aSrobert 		  p->balance = t->balance < 0;
5878404b540aSrobert 		  r->balance = -(t->balance > 0);
5879404b540aSrobert 		  t->balance = 0;
5880404b540aSrobert 
5881404b540aSrobert 		  s = p->parent;
5882404b540aSrobert 		  p->parent = t;
5883404b540aSrobert 		  r->parent = t;
5884404b540aSrobert 		  t->parent = s;
5885404b540aSrobert 		  if (s)
5886404b540aSrobert 		    {
5887404b540aSrobert 		      if (s->left == p)
5888404b540aSrobert 			s->left = t;
5889404b540aSrobert 		      else
5890404b540aSrobert 			s->right = t;
5891404b540aSrobert 		    }
5892404b540aSrobert 		  else
5893404b540aSrobert 		    constructor_pending_elts = t;
5894404b540aSrobert 		}
5895404b540aSrobert 	      break;
5896404b540aSrobert 	    }
5897404b540aSrobert 	  else
5898404b540aSrobert 	    {
5899404b540aSrobert 	      /* p->balance == +1; growth of left side balances the node.  */
5900404b540aSrobert 	      p->balance = 0;
5901404b540aSrobert 	      break;
5902404b540aSrobert 	    }
5903404b540aSrobert 	}
5904404b540aSrobert       else /* r == p->right */
5905404b540aSrobert 	{
5906404b540aSrobert 	  if (p->balance == 0)
5907404b540aSrobert 	    /* Growth propagation from right side.  */
5908404b540aSrobert 	    p->balance++;
5909404b540aSrobert 	  else if (p->balance > 0)
5910404b540aSrobert 	    {
5911404b540aSrobert 	      if (r->balance > 0)
5912404b540aSrobert 		{
5913404b540aSrobert 		  /* R rotation.  */
5914404b540aSrobert 		  p->right = r->left;
5915404b540aSrobert 		  if (p->right)
5916404b540aSrobert 		    p->right->parent = p;
5917404b540aSrobert 		  r->left = p;
5918404b540aSrobert 
5919404b540aSrobert 		  p->balance = 0;
5920404b540aSrobert 		  r->balance = 0;
5921404b540aSrobert 
5922404b540aSrobert 		  s = p->parent;
5923404b540aSrobert 		  p->parent = r;
5924404b540aSrobert 		  r->parent = s;
5925404b540aSrobert 		  if (s)
5926404b540aSrobert 		    {
5927404b540aSrobert 		      if (s->left == p)
5928404b540aSrobert 			s->left = r;
5929404b540aSrobert 		      else
5930404b540aSrobert 			s->right = r;
5931404b540aSrobert 		    }
5932404b540aSrobert 		  else
5933404b540aSrobert 		    constructor_pending_elts = r;
5934404b540aSrobert 		}
5935404b540aSrobert 	      else /* r->balance == -1 */
5936404b540aSrobert 		{
5937404b540aSrobert 		  /* RL rotation */
5938404b540aSrobert 		  struct init_node *t = r->left;
5939404b540aSrobert 
5940404b540aSrobert 		  r->left = t->right;
5941404b540aSrobert 		  if (r->left)
5942404b540aSrobert 		    r->left->parent = r;
5943404b540aSrobert 		  t->right = r;
5944404b540aSrobert 
5945404b540aSrobert 		  p->right = t->left;
5946404b540aSrobert 		  if (p->right)
5947404b540aSrobert 		    p->right->parent = p;
5948404b540aSrobert 		  t->left = p;
5949404b540aSrobert 
5950404b540aSrobert 		  r->balance = (t->balance < 0);
5951404b540aSrobert 		  p->balance = -(t->balance > 0);
5952404b540aSrobert 		  t->balance = 0;
5953404b540aSrobert 
5954404b540aSrobert 		  s = p->parent;
5955404b540aSrobert 		  p->parent = t;
5956404b540aSrobert 		  r->parent = t;
5957404b540aSrobert 		  t->parent = s;
5958404b540aSrobert 		  if (s)
5959404b540aSrobert 		    {
5960404b540aSrobert 		      if (s->left == p)
5961404b540aSrobert 			s->left = t;
5962404b540aSrobert 		      else
5963404b540aSrobert 			s->right = t;
5964404b540aSrobert 		    }
5965404b540aSrobert 		  else
5966404b540aSrobert 		    constructor_pending_elts = t;
5967404b540aSrobert 		}
5968404b540aSrobert 	      break;
5969404b540aSrobert 	    }
5970404b540aSrobert 	  else
5971404b540aSrobert 	    {
5972404b540aSrobert 	      /* p->balance == -1; growth of right side balances the node.  */
5973404b540aSrobert 	      p->balance = 0;
5974404b540aSrobert 	      break;
5975404b540aSrobert 	    }
5976404b540aSrobert 	}
5977404b540aSrobert 
5978404b540aSrobert       r = p;
5979404b540aSrobert       p = p->parent;
5980404b540aSrobert     }
5981404b540aSrobert }
5982404b540aSrobert 
5983404b540aSrobert /* Build AVL tree from a sorted chain.  */
5984404b540aSrobert 
5985404b540aSrobert static void
set_nonincremental_init(void)5986404b540aSrobert set_nonincremental_init (void)
5987404b540aSrobert {
5988404b540aSrobert   unsigned HOST_WIDE_INT ix;
5989404b540aSrobert   tree index, value;
5990404b540aSrobert 
5991404b540aSrobert   if (TREE_CODE (constructor_type) != RECORD_TYPE
5992404b540aSrobert       && TREE_CODE (constructor_type) != ARRAY_TYPE)
5993404b540aSrobert     return;
5994404b540aSrobert 
5995404b540aSrobert   FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
5996404b540aSrobert     add_pending_init (index, value);
5997404b540aSrobert   constructor_elements = 0;
5998404b540aSrobert   if (TREE_CODE (constructor_type) == RECORD_TYPE)
5999404b540aSrobert     {
6000404b540aSrobert       constructor_unfilled_fields = TYPE_FIELDS (constructor_type);
6001404b540aSrobert       /* Skip any nameless bit fields at the beginning.  */
6002404b540aSrobert       while (constructor_unfilled_fields != 0
6003404b540aSrobert 	     && DECL_C_BIT_FIELD (constructor_unfilled_fields)
6004404b540aSrobert 	     && DECL_NAME (constructor_unfilled_fields) == 0)
6005404b540aSrobert 	constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
6006404b540aSrobert 
6007404b540aSrobert     }
6008404b540aSrobert   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6009404b540aSrobert     {
6010404b540aSrobert       if (TYPE_DOMAIN (constructor_type))
6011404b540aSrobert 	constructor_unfilled_index
6012404b540aSrobert 	    = convert (bitsizetype,
6013404b540aSrobert 		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
6014404b540aSrobert       else
6015404b540aSrobert 	constructor_unfilled_index = bitsize_zero_node;
6016404b540aSrobert     }
6017404b540aSrobert   constructor_incremental = 0;
6018404b540aSrobert }
6019404b540aSrobert 
6020404b540aSrobert /* Build AVL tree from a string constant.  */
6021404b540aSrobert 
6022404b540aSrobert static void
set_nonincremental_init_from_string(tree str)6023404b540aSrobert set_nonincremental_init_from_string (tree str)
6024404b540aSrobert {
6025404b540aSrobert   tree value, purpose, type;
6026404b540aSrobert   HOST_WIDE_INT val[2];
6027404b540aSrobert   const char *p, *end;
6028404b540aSrobert   int byte, wchar_bytes, charwidth, bitpos;
6029404b540aSrobert 
6030404b540aSrobert   gcc_assert (TREE_CODE (constructor_type) == ARRAY_TYPE);
6031404b540aSrobert 
6032404b540aSrobert   if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
6033404b540aSrobert       == TYPE_PRECISION (char_type_node))
6034404b540aSrobert     wchar_bytes = 1;
6035404b540aSrobert   else
6036404b540aSrobert     {
6037404b540aSrobert       gcc_assert (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
6038404b540aSrobert 		  == TYPE_PRECISION (wchar_type_node));
6039404b540aSrobert       wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
6040404b540aSrobert     }
6041404b540aSrobert   charwidth = TYPE_PRECISION (char_type_node);
6042404b540aSrobert   type = TREE_TYPE (constructor_type);
6043404b540aSrobert   p = TREE_STRING_POINTER (str);
6044404b540aSrobert   end = p + TREE_STRING_LENGTH (str);
6045404b540aSrobert 
6046404b540aSrobert   for (purpose = bitsize_zero_node;
6047404b540aSrobert        p < end && !tree_int_cst_lt (constructor_max_index, purpose);
6048404b540aSrobert        purpose = size_binop (PLUS_EXPR, purpose, bitsize_one_node))
6049404b540aSrobert     {
6050404b540aSrobert       if (wchar_bytes == 1)
6051404b540aSrobert 	{
6052404b540aSrobert 	  val[1] = (unsigned char) *p++;
6053404b540aSrobert 	  val[0] = 0;
6054404b540aSrobert 	}
6055404b540aSrobert       else
6056404b540aSrobert 	{
6057404b540aSrobert 	  val[0] = 0;
6058404b540aSrobert 	  val[1] = 0;
6059404b540aSrobert 	  for (byte = 0; byte < wchar_bytes; byte++)
6060404b540aSrobert 	    {
6061404b540aSrobert 	      if (BYTES_BIG_ENDIAN)
6062404b540aSrobert 		bitpos = (wchar_bytes - byte - 1) * charwidth;
6063404b540aSrobert 	      else
6064404b540aSrobert 		bitpos = byte * charwidth;
6065404b540aSrobert 	      val[bitpos < HOST_BITS_PER_WIDE_INT]
6066404b540aSrobert 		|= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++))
6067404b540aSrobert 		   << (bitpos % HOST_BITS_PER_WIDE_INT);
6068404b540aSrobert 	    }
6069404b540aSrobert 	}
6070404b540aSrobert 
6071404b540aSrobert       if (!TYPE_UNSIGNED (type))
6072404b540aSrobert 	{
6073404b540aSrobert 	  bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR;
6074404b540aSrobert 	  if (bitpos < HOST_BITS_PER_WIDE_INT)
6075404b540aSrobert 	    {
6076404b540aSrobert 	      if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
6077404b540aSrobert 		{
6078404b540aSrobert 		  val[1] |= ((HOST_WIDE_INT) -1) << bitpos;
6079404b540aSrobert 		  val[0] = -1;
6080404b540aSrobert 		}
6081404b540aSrobert 	    }
6082404b540aSrobert 	  else if (bitpos == HOST_BITS_PER_WIDE_INT)
6083404b540aSrobert 	    {
6084404b540aSrobert 	      if (val[1] < 0)
6085404b540aSrobert 		val[0] = -1;
6086404b540aSrobert 	    }
6087404b540aSrobert 	  else if (val[0] & (((HOST_WIDE_INT) 1)
6088404b540aSrobert 			     << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
6089404b540aSrobert 	    val[0] |= ((HOST_WIDE_INT) -1)
6090404b540aSrobert 		      << (bitpos - HOST_BITS_PER_WIDE_INT);
6091404b540aSrobert 	}
6092404b540aSrobert 
6093404b540aSrobert       value = build_int_cst_wide (type, val[1], val[0]);
6094404b540aSrobert       add_pending_init (purpose, value);
6095404b540aSrobert     }
6096404b540aSrobert 
6097404b540aSrobert   constructor_incremental = 0;
6098404b540aSrobert }
6099404b540aSrobert 
6100404b540aSrobert /* Return value of FIELD in pending initializer or zero if the field was
6101404b540aSrobert    not initialized yet.  */
6102404b540aSrobert 
6103404b540aSrobert static tree
find_init_member(tree field)6104404b540aSrobert find_init_member (tree field)
6105404b540aSrobert {
6106404b540aSrobert   struct init_node *p;
6107404b540aSrobert 
6108404b540aSrobert   if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6109404b540aSrobert     {
6110404b540aSrobert       if (constructor_incremental
6111404b540aSrobert 	  && tree_int_cst_lt (field, constructor_unfilled_index))
6112404b540aSrobert 	set_nonincremental_init ();
6113404b540aSrobert 
6114404b540aSrobert       p = constructor_pending_elts;
6115404b540aSrobert       while (p)
6116404b540aSrobert 	{
6117404b540aSrobert 	  if (tree_int_cst_lt (field, p->purpose))
6118404b540aSrobert 	    p = p->left;
6119404b540aSrobert 	  else if (tree_int_cst_lt (p->purpose, field))
6120404b540aSrobert 	    p = p->right;
6121404b540aSrobert 	  else
6122404b540aSrobert 	    return p->value;
6123404b540aSrobert 	}
6124404b540aSrobert     }
6125404b540aSrobert   else if (TREE_CODE (constructor_type) == RECORD_TYPE)
6126404b540aSrobert     {
6127404b540aSrobert       tree bitpos = bit_position (field);
6128404b540aSrobert 
6129404b540aSrobert       if (constructor_incremental
6130404b540aSrobert 	  && (!constructor_unfilled_fields
6131404b540aSrobert 	      || tree_int_cst_lt (bitpos,
6132404b540aSrobert 				  bit_position (constructor_unfilled_fields))))
6133404b540aSrobert 	set_nonincremental_init ();
6134404b540aSrobert 
6135404b540aSrobert       p = constructor_pending_elts;
6136404b540aSrobert       while (p)
6137404b540aSrobert 	{
6138404b540aSrobert 	  if (field == p->purpose)
6139404b540aSrobert 	    return p->value;
6140404b540aSrobert 	  else if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
6141404b540aSrobert 	    p = p->left;
6142404b540aSrobert 	  else
6143404b540aSrobert 	    p = p->right;
6144404b540aSrobert 	}
6145404b540aSrobert     }
6146404b540aSrobert   else if (TREE_CODE (constructor_type) == UNION_TYPE)
6147404b540aSrobert     {
6148404b540aSrobert       if (!VEC_empty (constructor_elt, constructor_elements)
6149404b540aSrobert 	  && (VEC_last (constructor_elt, constructor_elements)->index
6150404b540aSrobert 	      == field))
6151404b540aSrobert 	return VEC_last (constructor_elt, constructor_elements)->value;
6152404b540aSrobert     }
6153404b540aSrobert   return 0;
6154404b540aSrobert }
6155404b540aSrobert 
6156404b540aSrobert /* "Output" the next constructor element.
6157404b540aSrobert    At top level, really output it to assembler code now.
6158404b540aSrobert    Otherwise, collect it in a list from which we will make a CONSTRUCTOR.
6159404b540aSrobert    TYPE is the data type that the containing data type wants here.
6160404b540aSrobert    FIELD is the field (a FIELD_DECL) or the index that this element fills.
6161404b540aSrobert    If VALUE is a string constant, STRICT_STRING is true if it is
6162404b540aSrobert    unparenthesized or we should not warn here for it being parenthesized.
6163404b540aSrobert    For other types of VALUE, STRICT_STRING is not used.
6164404b540aSrobert 
6165404b540aSrobert    PENDING if non-nil means output pending elements that belong
6166404b540aSrobert    right after this element.  (PENDING is normally 1;
6167404b540aSrobert    it is 0 while outputting pending elements, to avoid recursion.)  */
6168404b540aSrobert 
6169404b540aSrobert static void
output_init_element(tree value,bool strict_string,tree type,tree field,int pending)6170404b540aSrobert output_init_element (tree value, bool strict_string, tree type, tree field,
6171404b540aSrobert 		     int pending)
6172404b540aSrobert {
6173404b540aSrobert   constructor_elt *celt;
6174404b540aSrobert 
6175404b540aSrobert   if (type == error_mark_node || value == error_mark_node)
6176404b540aSrobert     {
6177404b540aSrobert       constructor_erroneous = 1;
6178404b540aSrobert       return;
6179404b540aSrobert     }
6180404b540aSrobert   if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
6181404b540aSrobert       && (TREE_CODE (value) == STRING_CST
6182404b540aSrobert 	  || TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
6183404b540aSrobert       && !(TREE_CODE (value) == STRING_CST
6184404b540aSrobert 	   && TREE_CODE (type) == ARRAY_TYPE
6185404b540aSrobert 	   && INTEGRAL_TYPE_P (TREE_TYPE (type)))
6186404b540aSrobert       && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
6187404b540aSrobert 		     TYPE_MAIN_VARIANT (type)))
6188404b540aSrobert     value = array_to_pointer_conversion (value);
6189404b540aSrobert 
6190404b540aSrobert   if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
6191404b540aSrobert       && require_constant_value && !flag_isoc99 && pending)
6192404b540aSrobert     {
6193404b540aSrobert       /* As an extension, allow initializing objects with static storage
6194404b540aSrobert 	 duration with compound literals (which are then treated just as
6195404b540aSrobert 	 the brace enclosed list they contain).  */
6196404b540aSrobert       tree decl = COMPOUND_LITERAL_EXPR_DECL (value);
6197404b540aSrobert       value = DECL_INITIAL (decl);
6198404b540aSrobert     }
6199404b540aSrobert 
6200404b540aSrobert   if (value == error_mark_node)
6201404b540aSrobert     constructor_erroneous = 1;
6202404b540aSrobert   else if (!TREE_CONSTANT (value))
6203404b540aSrobert     constructor_constant = 0;
6204404b540aSrobert   else if (!initializer_constant_valid_p (value, TREE_TYPE (value))
6205404b540aSrobert 	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
6206404b540aSrobert 		|| TREE_CODE (constructor_type) == UNION_TYPE)
6207404b540aSrobert 	       && DECL_C_BIT_FIELD (field)
6208404b540aSrobert 	       && TREE_CODE (value) != INTEGER_CST))
6209404b540aSrobert     constructor_simple = 0;
6210404b540aSrobert 
6211404b540aSrobert   if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
6212404b540aSrobert     {
6213404b540aSrobert       if (require_constant_value)
6214404b540aSrobert 	{
6215404b540aSrobert 	  error_init ("initializer element is not constant");
6216404b540aSrobert 	  value = error_mark_node;
6217404b540aSrobert 	}
6218404b540aSrobert       else if (require_constant_elements)
6219404b540aSrobert 	pedwarn ("initializer element is not computable at load time");
6220404b540aSrobert     }
6221404b540aSrobert 
6222404b540aSrobert   /* If this field is empty (and not at the end of structure),
6223404b540aSrobert      don't do anything other than checking the initializer.  */
6224404b540aSrobert   if (field
6225404b540aSrobert       && (TREE_TYPE (field) == error_mark_node
6226404b540aSrobert 	  || (COMPLETE_TYPE_P (TREE_TYPE (field))
6227404b540aSrobert 	      && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))
6228404b540aSrobert 	      && (TREE_CODE (constructor_type) == ARRAY_TYPE
6229404b540aSrobert 		  || TREE_CHAIN (field)))))
6230404b540aSrobert     return;
6231404b540aSrobert 
6232404b540aSrobert   value = digest_init (type, value, strict_string, require_constant_value);
6233404b540aSrobert   if (value == error_mark_node)
6234404b540aSrobert     {
6235404b540aSrobert       constructor_erroneous = 1;
6236404b540aSrobert       return;
6237404b540aSrobert     }
6238404b540aSrobert 
6239404b540aSrobert   /* If this element doesn't come next in sequence,
6240404b540aSrobert      put it on constructor_pending_elts.  */
6241404b540aSrobert   if (TREE_CODE (constructor_type) == ARRAY_TYPE
6242404b540aSrobert       && (!constructor_incremental
6243404b540aSrobert 	  || !tree_int_cst_equal (field, constructor_unfilled_index)))
6244404b540aSrobert     {
6245404b540aSrobert       if (constructor_incremental
6246404b540aSrobert 	  && tree_int_cst_lt (field, constructor_unfilled_index))
6247404b540aSrobert 	set_nonincremental_init ();
6248404b540aSrobert 
6249404b540aSrobert       add_pending_init (field, value);
6250404b540aSrobert       return;
6251404b540aSrobert     }
6252404b540aSrobert   else if (TREE_CODE (constructor_type) == RECORD_TYPE
6253404b540aSrobert 	   && (!constructor_incremental
6254404b540aSrobert 	       || field != constructor_unfilled_fields))
6255404b540aSrobert     {
6256404b540aSrobert       /* We do this for records but not for unions.  In a union,
6257404b540aSrobert 	 no matter which field is specified, it can be initialized
6258404b540aSrobert 	 right away since it starts at the beginning of the union.  */
6259404b540aSrobert       if (constructor_incremental)
6260404b540aSrobert 	{
6261404b540aSrobert 	  if (!constructor_unfilled_fields)
6262404b540aSrobert 	    set_nonincremental_init ();
6263404b540aSrobert 	  else
6264404b540aSrobert 	    {
6265404b540aSrobert 	      tree bitpos, unfillpos;
6266404b540aSrobert 
6267404b540aSrobert 	      bitpos = bit_position (field);
6268404b540aSrobert 	      unfillpos = bit_position (constructor_unfilled_fields);
6269404b540aSrobert 
6270404b540aSrobert 	      if (tree_int_cst_lt (bitpos, unfillpos))
6271404b540aSrobert 		set_nonincremental_init ();
6272404b540aSrobert 	    }
6273404b540aSrobert 	}
6274404b540aSrobert 
6275404b540aSrobert       add_pending_init (field, value);
6276404b540aSrobert       return;
6277404b540aSrobert     }
6278404b540aSrobert   else if (TREE_CODE (constructor_type) == UNION_TYPE
6279404b540aSrobert 	   && !VEC_empty (constructor_elt, constructor_elements))
6280404b540aSrobert     {
6281404b540aSrobert       if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
6282404b540aSrobert 				       constructor_elements)->value))
6283404b540aSrobert 	warning_init ("initialized field with side-effects overwritten");
6284404b540aSrobert       else if (warn_override_init)
6285404b540aSrobert 	warning_init ("initialized field overwritten");
6286404b540aSrobert 
6287404b540aSrobert       /* We can have just one union field set.  */
6288404b540aSrobert       constructor_elements = 0;
6289404b540aSrobert     }
6290404b540aSrobert 
6291404b540aSrobert   /* Otherwise, output this element either to
6292404b540aSrobert      constructor_elements or to the assembler file.  */
6293404b540aSrobert 
6294404b540aSrobert   celt = VEC_safe_push (constructor_elt, gc, constructor_elements, NULL);
6295404b540aSrobert   celt->index = field;
6296404b540aSrobert   celt->value = value;
6297404b540aSrobert 
6298404b540aSrobert   /* Advance the variable that indicates sequential elements output.  */
6299404b540aSrobert   if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6300404b540aSrobert     constructor_unfilled_index
6301404b540aSrobert       = size_binop (PLUS_EXPR, constructor_unfilled_index,
6302404b540aSrobert 		    bitsize_one_node);
6303404b540aSrobert   else if (TREE_CODE (constructor_type) == RECORD_TYPE)
6304404b540aSrobert     {
6305404b540aSrobert       constructor_unfilled_fields
6306404b540aSrobert 	= TREE_CHAIN (constructor_unfilled_fields);
6307404b540aSrobert 
6308404b540aSrobert       /* Skip any nameless bit fields.  */
6309404b540aSrobert       while (constructor_unfilled_fields != 0
6310404b540aSrobert 	     && DECL_C_BIT_FIELD (constructor_unfilled_fields)
6311404b540aSrobert 	     && DECL_NAME (constructor_unfilled_fields) == 0)
6312404b540aSrobert 	constructor_unfilled_fields =
6313404b540aSrobert 	  TREE_CHAIN (constructor_unfilled_fields);
6314404b540aSrobert     }
6315404b540aSrobert   else if (TREE_CODE (constructor_type) == UNION_TYPE)
6316404b540aSrobert     constructor_unfilled_fields = 0;
6317404b540aSrobert 
6318404b540aSrobert   /* Now output any pending elements which have become next.  */
6319404b540aSrobert   if (pending)
6320404b540aSrobert     output_pending_init_elements (0);
6321404b540aSrobert }
6322404b540aSrobert 
6323404b540aSrobert /* Output any pending elements which have become next.
6324404b540aSrobert    As we output elements, constructor_unfilled_{fields,index}
6325404b540aSrobert    advances, which may cause other elements to become next;
6326404b540aSrobert    if so, they too are output.
6327404b540aSrobert 
6328404b540aSrobert    If ALL is 0, we return when there are
6329404b540aSrobert    no more pending elements to output now.
6330404b540aSrobert 
6331404b540aSrobert    If ALL is 1, we output space as necessary so that
6332404b540aSrobert    we can output all the pending elements.  */
6333404b540aSrobert 
6334404b540aSrobert static void
output_pending_init_elements(int all)6335404b540aSrobert output_pending_init_elements (int all)
6336404b540aSrobert {
6337404b540aSrobert   struct init_node *elt = constructor_pending_elts;
6338404b540aSrobert   tree next;
6339404b540aSrobert 
6340404b540aSrobert  retry:
6341404b540aSrobert 
6342404b540aSrobert   /* Look through the whole pending tree.
6343404b540aSrobert      If we find an element that should be output now,
6344404b540aSrobert      output it.  Otherwise, set NEXT to the element
6345404b540aSrobert      that comes first among those still pending.  */
6346404b540aSrobert 
6347404b540aSrobert   next = 0;
6348404b540aSrobert   while (elt)
6349404b540aSrobert     {
6350404b540aSrobert       if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6351404b540aSrobert 	{
6352404b540aSrobert 	  if (tree_int_cst_equal (elt->purpose,
6353404b540aSrobert 				  constructor_unfilled_index))
6354404b540aSrobert 	    output_init_element (elt->value, true,
6355404b540aSrobert 				 TREE_TYPE (constructor_type),
6356404b540aSrobert 				 constructor_unfilled_index, 0);
6357404b540aSrobert 	  else if (tree_int_cst_lt (constructor_unfilled_index,
6358404b540aSrobert 				    elt->purpose))
6359404b540aSrobert 	    {
6360404b540aSrobert 	      /* Advance to the next smaller node.  */
6361404b540aSrobert 	      if (elt->left)
6362404b540aSrobert 		elt = elt->left;
6363404b540aSrobert 	      else
6364404b540aSrobert 		{
6365404b540aSrobert 		  /* We have reached the smallest node bigger than the
6366404b540aSrobert 		     current unfilled index.  Fill the space first.  */
6367404b540aSrobert 		  next = elt->purpose;
6368404b540aSrobert 		  break;
6369404b540aSrobert 		}
6370404b540aSrobert 	    }
6371404b540aSrobert 	  else
6372404b540aSrobert 	    {
6373404b540aSrobert 	      /* Advance to the next bigger node.  */
6374404b540aSrobert 	      if (elt->right)
6375404b540aSrobert 		elt = elt->right;
6376404b540aSrobert 	      else
6377404b540aSrobert 		{
6378404b540aSrobert 		  /* We have reached the biggest node in a subtree.  Find
6379404b540aSrobert 		     the parent of it, which is the next bigger node.  */
6380404b540aSrobert 		  while (elt->parent && elt->parent->right == elt)
6381404b540aSrobert 		    elt = elt->parent;
6382404b540aSrobert 		  elt = elt->parent;
6383404b540aSrobert 		  if (elt && tree_int_cst_lt (constructor_unfilled_index,
6384404b540aSrobert 					      elt->purpose))
6385404b540aSrobert 		    {
6386404b540aSrobert 		      next = elt->purpose;
6387404b540aSrobert 		      break;
6388404b540aSrobert 		    }
6389404b540aSrobert 		}
6390404b540aSrobert 	    }
6391404b540aSrobert 	}
6392404b540aSrobert       else if (TREE_CODE (constructor_type) == RECORD_TYPE
6393404b540aSrobert 	       || TREE_CODE (constructor_type) == UNION_TYPE)
6394404b540aSrobert 	{
6395404b540aSrobert 	  tree ctor_unfilled_bitpos, elt_bitpos;
6396404b540aSrobert 
6397404b540aSrobert 	  /* If the current record is complete we are done.  */
6398404b540aSrobert 	  if (constructor_unfilled_fields == 0)
6399404b540aSrobert 	    break;
6400404b540aSrobert 
6401404b540aSrobert 	  ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields);
6402404b540aSrobert 	  elt_bitpos = bit_position (elt->purpose);
6403404b540aSrobert 	  /* We can't compare fields here because there might be empty
6404404b540aSrobert 	     fields in between.  */
6405404b540aSrobert 	  if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
6406404b540aSrobert 	    {
6407404b540aSrobert 	      constructor_unfilled_fields = elt->purpose;
6408404b540aSrobert 	      output_init_element (elt->value, true, TREE_TYPE (elt->purpose),
6409404b540aSrobert 				   elt->purpose, 0);
6410404b540aSrobert 	    }
6411404b540aSrobert 	  else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
6412404b540aSrobert 	    {
6413404b540aSrobert 	      /* Advance to the next smaller node.  */
6414404b540aSrobert 	      if (elt->left)
6415404b540aSrobert 		elt = elt->left;
6416404b540aSrobert 	      else
6417404b540aSrobert 		{
6418404b540aSrobert 		  /* We have reached the smallest node bigger than the
6419404b540aSrobert 		     current unfilled field.  Fill the space first.  */
6420404b540aSrobert 		  next = elt->purpose;
6421404b540aSrobert 		  break;
6422404b540aSrobert 		}
6423404b540aSrobert 	    }
6424404b540aSrobert 	  else
6425404b540aSrobert 	    {
6426404b540aSrobert 	      /* Advance to the next bigger node.  */
6427404b540aSrobert 	      if (elt->right)
6428404b540aSrobert 		elt = elt->right;
6429404b540aSrobert 	      else
6430404b540aSrobert 		{
6431404b540aSrobert 		  /* We have reached the biggest node in a subtree.  Find
6432404b540aSrobert 		     the parent of it, which is the next bigger node.  */
6433404b540aSrobert 		  while (elt->parent && elt->parent->right == elt)
6434404b540aSrobert 		    elt = elt->parent;
6435404b540aSrobert 		  elt = elt->parent;
6436404b540aSrobert 		  if (elt
6437404b540aSrobert 		      && (tree_int_cst_lt (ctor_unfilled_bitpos,
6438404b540aSrobert 					   bit_position (elt->purpose))))
6439404b540aSrobert 		    {
6440404b540aSrobert 		      next = elt->purpose;
6441404b540aSrobert 		      break;
6442404b540aSrobert 		    }
6443404b540aSrobert 		}
6444404b540aSrobert 	    }
6445404b540aSrobert 	}
6446404b540aSrobert     }
6447404b540aSrobert 
6448404b540aSrobert   /* Ordinarily return, but not if we want to output all
6449404b540aSrobert      and there are elements left.  */
6450404b540aSrobert   if (!(all && next != 0))
6451404b540aSrobert     return;
6452404b540aSrobert 
6453404b540aSrobert   /* If it's not incremental, just skip over the gap, so that after
6454404b540aSrobert      jumping to retry we will output the next successive element.  */
6455404b540aSrobert   if (TREE_CODE (constructor_type) == RECORD_TYPE
6456404b540aSrobert       || TREE_CODE (constructor_type) == UNION_TYPE)
6457404b540aSrobert     constructor_unfilled_fields = next;
6458404b540aSrobert   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6459404b540aSrobert     constructor_unfilled_index = next;
6460404b540aSrobert 
6461404b540aSrobert   /* ELT now points to the node in the pending tree with the next
6462404b540aSrobert      initializer to output.  */
6463404b540aSrobert   goto retry;
6464404b540aSrobert }
6465404b540aSrobert 
6466404b540aSrobert /* Add one non-braced element to the current constructor level.
6467404b540aSrobert    This adjusts the current position within the constructor's type.
6468404b540aSrobert    This may also start or terminate implicit levels
6469404b540aSrobert    to handle a partly-braced initializer.
6470404b540aSrobert 
6471404b540aSrobert    Once this has found the correct level for the new element,
6472404b540aSrobert    it calls output_init_element.  */
6473404b540aSrobert 
6474404b540aSrobert void
process_init_element(struct c_expr value)6475404b540aSrobert process_init_element (struct c_expr value)
6476404b540aSrobert {
6477404b540aSrobert   tree orig_value = value.value;
6478404b540aSrobert   int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
6479404b540aSrobert   bool strict_string = value.original_code == STRING_CST;
6480404b540aSrobert 
6481404b540aSrobert   designator_depth = 0;
6482404b540aSrobert   designator_erroneous = 0;
6483404b540aSrobert 
6484404b540aSrobert   /* Handle superfluous braces around string cst as in
6485404b540aSrobert      char x[] = {"foo"}; */
6486404b540aSrobert   if (string_flag
6487404b540aSrobert       && constructor_type
6488404b540aSrobert       && TREE_CODE (constructor_type) == ARRAY_TYPE
6489404b540aSrobert       && INTEGRAL_TYPE_P (TREE_TYPE (constructor_type))
6490404b540aSrobert       && integer_zerop (constructor_unfilled_index))
6491404b540aSrobert     {
6492404b540aSrobert       if (constructor_stack->replacement_value.value)
6493404b540aSrobert 	error_init ("excess elements in char array initializer");
6494404b540aSrobert       constructor_stack->replacement_value = value;
6495404b540aSrobert       return;
6496404b540aSrobert     }
6497404b540aSrobert 
6498404b540aSrobert   if (constructor_stack->replacement_value.value != 0)
6499404b540aSrobert     {
6500404b540aSrobert       error_init ("excess elements in struct initializer");
6501404b540aSrobert       return;
6502404b540aSrobert     }
6503404b540aSrobert 
6504404b540aSrobert   /* Ignore elements of a brace group if it is entirely superfluous
6505404b540aSrobert      and has already been diagnosed.  */
6506404b540aSrobert   if (constructor_type == 0)
6507404b540aSrobert     return;
6508404b540aSrobert 
6509404b540aSrobert   /* If we've exhausted any levels that didn't have braces,
6510404b540aSrobert      pop them now.  */
6511404b540aSrobert   while (constructor_stack->implicit)
6512404b540aSrobert     {
6513404b540aSrobert       if ((TREE_CODE (constructor_type) == RECORD_TYPE
6514404b540aSrobert 	   || TREE_CODE (constructor_type) == UNION_TYPE)
6515404b540aSrobert 	  && constructor_fields == 0)
6516404b540aSrobert 	process_init_element (pop_init_level (1));
6517404b540aSrobert       else if (TREE_CODE (constructor_type) == ARRAY_TYPE
6518404b540aSrobert 	       && (constructor_max_index == 0
6519404b540aSrobert 		   || tree_int_cst_lt (constructor_max_index,
6520404b540aSrobert 				       constructor_index)))
6521404b540aSrobert 	process_init_element (pop_init_level (1));
6522404b540aSrobert       else
6523404b540aSrobert 	break;
6524404b540aSrobert     }
6525404b540aSrobert 
6526404b540aSrobert   /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once.  */
6527404b540aSrobert   if (constructor_range_stack)
6528404b540aSrobert     {
6529404b540aSrobert       /* If value is a compound literal and we'll be just using its
6530404b540aSrobert 	 content, don't put it into a SAVE_EXPR.  */
6531404b540aSrobert       if (TREE_CODE (value.value) != COMPOUND_LITERAL_EXPR
6532404b540aSrobert 	  || !require_constant_value
6533404b540aSrobert 	  || flag_isoc99)
6534404b540aSrobert 	value.value = save_expr (value.value);
6535404b540aSrobert     }
6536404b540aSrobert 
6537404b540aSrobert   while (1)
6538404b540aSrobert     {
6539404b540aSrobert       if (TREE_CODE (constructor_type) == RECORD_TYPE)
6540404b540aSrobert 	{
6541404b540aSrobert 	  tree fieldtype;
6542404b540aSrobert 	  enum tree_code fieldcode;
6543404b540aSrobert 
6544404b540aSrobert 	  if (constructor_fields == 0)
6545404b540aSrobert 	    {
6546404b540aSrobert 	      pedwarn_init ("excess elements in struct initializer");
6547404b540aSrobert 	      break;
6548404b540aSrobert 	    }
6549404b540aSrobert 
6550404b540aSrobert 	  fieldtype = TREE_TYPE (constructor_fields);
6551404b540aSrobert 	  if (fieldtype != error_mark_node)
6552404b540aSrobert 	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
6553404b540aSrobert 	  fieldcode = TREE_CODE (fieldtype);
6554404b540aSrobert 
6555404b540aSrobert 	  /* Error for non-static initialization of a flexible array member.  */
6556404b540aSrobert 	  if (fieldcode == ARRAY_TYPE
6557404b540aSrobert 	      && !require_constant_value
6558404b540aSrobert 	      && TYPE_SIZE (fieldtype) == NULL_TREE
6559404b540aSrobert 	      && TREE_CHAIN (constructor_fields) == NULL_TREE)
6560404b540aSrobert 	    {
6561404b540aSrobert 	      error_init ("non-static initialization of a flexible array member");
6562404b540aSrobert 	      break;
6563404b540aSrobert 	    }
6564404b540aSrobert 
6565404b540aSrobert 	  /* Accept a string constant to initialize a subarray.  */
6566404b540aSrobert 	  if (value.value != 0
6567404b540aSrobert 	      && fieldcode == ARRAY_TYPE
6568404b540aSrobert 	      && INTEGRAL_TYPE_P (TREE_TYPE (fieldtype))
6569404b540aSrobert 	      && string_flag)
6570404b540aSrobert 	    value.value = orig_value;
6571404b540aSrobert 	  /* Otherwise, if we have come to a subaggregate,
6572404b540aSrobert 	     and we don't have an element of its type, push into it.  */
6573404b540aSrobert 	  else if (value.value != 0
6574404b540aSrobert 		   && value.value != error_mark_node
6575404b540aSrobert 		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
6576404b540aSrobert 		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
6577404b540aSrobert 		       || fieldcode == UNION_TYPE))
6578404b540aSrobert 	    {
6579404b540aSrobert 	      push_init_level (1);
6580404b540aSrobert 	      continue;
6581404b540aSrobert 	    }
6582404b540aSrobert 
6583404b540aSrobert 	  if (value.value)
6584404b540aSrobert 	    {
6585404b540aSrobert 	      push_member_name (constructor_fields);
6586404b540aSrobert 	      output_init_element (value.value, strict_string,
6587404b540aSrobert 				   fieldtype, constructor_fields, 1);
6588404b540aSrobert 	      RESTORE_SPELLING_DEPTH (constructor_depth);
6589404b540aSrobert 	    }
6590404b540aSrobert 	  else
6591404b540aSrobert 	    /* Do the bookkeeping for an element that was
6592404b540aSrobert 	       directly output as a constructor.  */
6593404b540aSrobert 	    {
6594404b540aSrobert 	      /* For a record, keep track of end position of last field.  */
6595404b540aSrobert 	      if (DECL_SIZE (constructor_fields))
6596404b540aSrobert 		constructor_bit_index
6597404b540aSrobert 		  = size_binop (PLUS_EXPR,
6598404b540aSrobert 				bit_position (constructor_fields),
6599404b540aSrobert 				DECL_SIZE (constructor_fields));
6600404b540aSrobert 
6601404b540aSrobert 	      /* If the current field was the first one not yet written out,
6602404b540aSrobert 		 it isn't now, so update.  */
6603404b540aSrobert 	      if (constructor_unfilled_fields == constructor_fields)
6604404b540aSrobert 		{
6605404b540aSrobert 		  constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
6606404b540aSrobert 		  /* Skip any nameless bit fields.  */
6607404b540aSrobert 		  while (constructor_unfilled_fields != 0
6608404b540aSrobert 			 && DECL_C_BIT_FIELD (constructor_unfilled_fields)
6609404b540aSrobert 			 && DECL_NAME (constructor_unfilled_fields) == 0)
6610404b540aSrobert 		    constructor_unfilled_fields =
6611404b540aSrobert 		      TREE_CHAIN (constructor_unfilled_fields);
6612404b540aSrobert 		}
6613404b540aSrobert 	    }
6614404b540aSrobert 
6615404b540aSrobert 	  constructor_fields = TREE_CHAIN (constructor_fields);
6616404b540aSrobert 	  /* Skip any nameless bit fields at the beginning.  */
6617404b540aSrobert 	  while (constructor_fields != 0
6618404b540aSrobert 		 && DECL_C_BIT_FIELD (constructor_fields)
6619404b540aSrobert 		 && DECL_NAME (constructor_fields) == 0)
6620404b540aSrobert 	    constructor_fields = TREE_CHAIN (constructor_fields);
6621404b540aSrobert 	}
6622404b540aSrobert       else if (TREE_CODE (constructor_type) == UNION_TYPE)
6623404b540aSrobert 	{
6624404b540aSrobert 	  tree fieldtype;
6625404b540aSrobert 	  enum tree_code fieldcode;
6626404b540aSrobert 
6627404b540aSrobert 	  if (constructor_fields == 0)
6628404b540aSrobert 	    {
6629404b540aSrobert 	      pedwarn_init ("excess elements in union initializer");
6630404b540aSrobert 	      break;
6631404b540aSrobert 	    }
6632404b540aSrobert 
6633404b540aSrobert 	  fieldtype = TREE_TYPE (constructor_fields);
6634404b540aSrobert 	  if (fieldtype != error_mark_node)
6635404b540aSrobert 	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
6636404b540aSrobert 	  fieldcode = TREE_CODE (fieldtype);
6637404b540aSrobert 
6638404b540aSrobert 	  /* Warn that traditional C rejects initialization of unions.
6639404b540aSrobert 	     We skip the warning if the value is zero.  This is done
6640404b540aSrobert 	     under the assumption that the zero initializer in user
6641404b540aSrobert 	     code appears conditioned on e.g. __STDC__ to avoid
6642404b540aSrobert 	     "missing initializer" warnings and relies on default
6643404b540aSrobert 	     initialization to zero in the traditional C case.
6644404b540aSrobert 	     We also skip the warning if the initializer is designated,
6645404b540aSrobert 	     again on the assumption that this must be conditional on
6646404b540aSrobert 	     __STDC__ anyway (and we've already complained about the
6647404b540aSrobert 	     member-designator already).  */
6648404b540aSrobert 	  if (!in_system_header && !constructor_designated
6649404b540aSrobert 	      && !(value.value && (integer_zerop (value.value)
6650404b540aSrobert 				   || real_zerop (value.value))))
6651404b540aSrobert 	    warning (OPT_Wtraditional, "traditional C rejects initialization "
6652404b540aSrobert 		     "of unions");
6653404b540aSrobert 
6654404b540aSrobert 	  /* Accept a string constant to initialize a subarray.  */
6655404b540aSrobert 	  if (value.value != 0
6656404b540aSrobert 	      && fieldcode == ARRAY_TYPE
6657404b540aSrobert 	      && INTEGRAL_TYPE_P (TREE_TYPE (fieldtype))
6658404b540aSrobert 	      && string_flag)
6659404b540aSrobert 	    value.value = orig_value;
6660404b540aSrobert 	  /* Otherwise, if we have come to a subaggregate,
6661404b540aSrobert 	     and we don't have an element of its type, push into it.  */
6662404b540aSrobert 	  else if (value.value != 0
6663404b540aSrobert 		   && value.value != error_mark_node
6664404b540aSrobert 		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
6665404b540aSrobert 		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
6666404b540aSrobert 		       || fieldcode == UNION_TYPE))
6667404b540aSrobert 	    {
6668404b540aSrobert 	      push_init_level (1);
6669404b540aSrobert 	      continue;
6670404b540aSrobert 	    }
6671404b540aSrobert 
6672404b540aSrobert 	  if (value.value)
6673404b540aSrobert 	    {
6674404b540aSrobert 	      push_member_name (constructor_fields);
6675404b540aSrobert 	      output_init_element (value.value, strict_string,
6676404b540aSrobert 				   fieldtype, constructor_fields, 1);
6677404b540aSrobert 	      RESTORE_SPELLING_DEPTH (constructor_depth);
6678404b540aSrobert 	    }
6679404b540aSrobert 	  else
6680404b540aSrobert 	    /* Do the bookkeeping for an element that was
6681404b540aSrobert 	       directly output as a constructor.  */
6682404b540aSrobert 	    {
6683404b540aSrobert 	      constructor_bit_index = DECL_SIZE (constructor_fields);
6684404b540aSrobert 	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
6685404b540aSrobert 	    }
6686404b540aSrobert 
6687404b540aSrobert 	  constructor_fields = 0;
6688404b540aSrobert 	}
6689404b540aSrobert       else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
6690404b540aSrobert 	{
6691404b540aSrobert 	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
6692404b540aSrobert 	  enum tree_code eltcode = TREE_CODE (elttype);
6693404b540aSrobert 
6694404b540aSrobert 	  /* Accept a string constant to initialize a subarray.  */
6695404b540aSrobert 	  if (value.value != 0
6696404b540aSrobert 	      && eltcode == ARRAY_TYPE
6697404b540aSrobert 	      && INTEGRAL_TYPE_P (TREE_TYPE (elttype))
6698404b540aSrobert 	      && string_flag)
6699404b540aSrobert 	    value.value = orig_value;
6700404b540aSrobert 	  /* Otherwise, if we have come to a subaggregate,
6701404b540aSrobert 	     and we don't have an element of its type, push into it.  */
6702404b540aSrobert 	  else if (value.value != 0
6703404b540aSrobert 		   && value.value != error_mark_node
6704404b540aSrobert 		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype
6705404b540aSrobert 		   && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
6706404b540aSrobert 		       || eltcode == UNION_TYPE))
6707404b540aSrobert 	    {
6708404b540aSrobert 	      push_init_level (1);
6709404b540aSrobert 	      continue;
6710404b540aSrobert 	    }
6711404b540aSrobert 
6712404b540aSrobert 	  if (constructor_max_index != 0
6713404b540aSrobert 	      && (tree_int_cst_lt (constructor_max_index, constructor_index)
6714404b540aSrobert 		  || integer_all_onesp (constructor_max_index)))
6715404b540aSrobert 	    {
6716404b540aSrobert 	      pedwarn_init ("excess elements in array initializer");
6717404b540aSrobert 	      break;
6718404b540aSrobert 	    }
6719404b540aSrobert 
6720404b540aSrobert 	  /* Now output the actual element.  */
6721404b540aSrobert 	  if (value.value)
6722404b540aSrobert 	    {
6723404b540aSrobert 	      push_array_bounds (tree_low_cst (constructor_index, 1));
6724404b540aSrobert 	      output_init_element (value.value, strict_string,
6725404b540aSrobert 				   elttype, constructor_index, 1);
6726404b540aSrobert 	      RESTORE_SPELLING_DEPTH (constructor_depth);
6727404b540aSrobert 	    }
6728404b540aSrobert 
6729404b540aSrobert 	  constructor_index
6730404b540aSrobert 	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
6731404b540aSrobert 
6732404b540aSrobert 	  if (!value.value)
6733404b540aSrobert 	    /* If we are doing the bookkeeping for an element that was
6734404b540aSrobert 	       directly output as a constructor, we must update
6735404b540aSrobert 	       constructor_unfilled_index.  */
6736404b540aSrobert 	    constructor_unfilled_index = constructor_index;
6737404b540aSrobert 	}
6738404b540aSrobert       else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
6739404b540aSrobert 	{
6740404b540aSrobert 	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
6741404b540aSrobert 
6742404b540aSrobert 	 /* Do a basic check of initializer size.  Note that vectors
6743404b540aSrobert 	    always have a fixed size derived from their type.  */
6744404b540aSrobert 	  if (tree_int_cst_lt (constructor_max_index, constructor_index))
6745404b540aSrobert 	    {
6746404b540aSrobert 	      pedwarn_init ("excess elements in vector initializer");
6747404b540aSrobert 	      break;
6748404b540aSrobert 	    }
6749404b540aSrobert 
6750404b540aSrobert 	  /* Now output the actual element.  */
6751404b540aSrobert 	  if (value.value)
6752404b540aSrobert 	    output_init_element (value.value, strict_string,
6753404b540aSrobert 				 elttype, constructor_index, 1);
6754404b540aSrobert 
6755404b540aSrobert 	  constructor_index
6756404b540aSrobert 	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
6757404b540aSrobert 
6758404b540aSrobert 	  if (!value.value)
6759404b540aSrobert 	    /* If we are doing the bookkeeping for an element that was
6760404b540aSrobert 	       directly output as a constructor, we must update
6761404b540aSrobert 	       constructor_unfilled_index.  */
6762404b540aSrobert 	    constructor_unfilled_index = constructor_index;
6763404b540aSrobert 	}
6764404b540aSrobert 
6765404b540aSrobert       /* Handle the sole element allowed in a braced initializer
6766404b540aSrobert 	 for a scalar variable.  */
6767404b540aSrobert       else if (constructor_type != error_mark_node
6768404b540aSrobert 	       && constructor_fields == 0)
6769404b540aSrobert 	{
6770404b540aSrobert 	  pedwarn_init ("excess elements in scalar initializer");
6771404b540aSrobert 	  break;
6772404b540aSrobert 	}
6773404b540aSrobert       else
6774404b540aSrobert 	{
6775404b540aSrobert 	  if (value.value)
6776404b540aSrobert 	    output_init_element (value.value, strict_string,
6777404b540aSrobert 				 constructor_type, NULL_TREE, 1);
6778404b540aSrobert 	  constructor_fields = 0;
6779404b540aSrobert 	}
6780404b540aSrobert 
6781404b540aSrobert       /* Handle range initializers either at this level or anywhere higher
6782404b540aSrobert 	 in the designator stack.  */
6783404b540aSrobert       if (constructor_range_stack)
6784404b540aSrobert 	{
6785404b540aSrobert 	  struct constructor_range_stack *p, *range_stack;
6786404b540aSrobert 	  int finish = 0;
6787404b540aSrobert 
6788404b540aSrobert 	  range_stack = constructor_range_stack;
6789404b540aSrobert 	  constructor_range_stack = 0;
6790404b540aSrobert 	  while (constructor_stack != range_stack->stack)
6791404b540aSrobert 	    {
6792404b540aSrobert 	      gcc_assert (constructor_stack->implicit);
6793404b540aSrobert 	      process_init_element (pop_init_level (1));
6794404b540aSrobert 	    }
6795404b540aSrobert 	  for (p = range_stack;
6796404b540aSrobert 	       !p->range_end || tree_int_cst_equal (p->index, p->range_end);
6797404b540aSrobert 	       p = p->prev)
6798404b540aSrobert 	    {
6799404b540aSrobert 	      gcc_assert (constructor_stack->implicit);
6800404b540aSrobert 	      process_init_element (pop_init_level (1));
6801404b540aSrobert 	    }
6802404b540aSrobert 
6803404b540aSrobert 	  p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node);
6804404b540aSrobert 	  if (tree_int_cst_equal (p->index, p->range_end) && !p->prev)
6805404b540aSrobert 	    finish = 1;
6806404b540aSrobert 
6807404b540aSrobert 	  while (1)
6808404b540aSrobert 	    {
6809404b540aSrobert 	      constructor_index = p->index;
6810404b540aSrobert 	      constructor_fields = p->fields;
6811404b540aSrobert 	      if (finish && p->range_end && p->index == p->range_start)
6812404b540aSrobert 		{
6813404b540aSrobert 		  finish = 0;
6814404b540aSrobert 		  p->prev = 0;
6815404b540aSrobert 		}
6816404b540aSrobert 	      p = p->next;
6817404b540aSrobert 	      if (!p)
6818404b540aSrobert 		break;
6819404b540aSrobert 	      push_init_level (2);
6820404b540aSrobert 	      p->stack = constructor_stack;
6821404b540aSrobert 	      if (p->range_end && tree_int_cst_equal (p->index, p->range_end))
6822404b540aSrobert 		p->index = p->range_start;
6823404b540aSrobert 	    }
6824404b540aSrobert 
6825404b540aSrobert 	  if (!finish)
6826404b540aSrobert 	    constructor_range_stack = range_stack;
6827404b540aSrobert 	  continue;
6828404b540aSrobert 	}
6829404b540aSrobert 
6830404b540aSrobert       break;
6831404b540aSrobert     }
6832404b540aSrobert 
6833404b540aSrobert   constructor_range_stack = 0;
6834404b540aSrobert }
6835404b540aSrobert 
6836404b540aSrobert /* Build a complete asm-statement, whose components are a CV_QUALIFIER
6837404b540aSrobert    (guaranteed to be 'volatile' or null) and ARGS (represented using
6838404b540aSrobert    an ASM_EXPR node).  */
6839404b540aSrobert tree
build_asm_stmt(tree cv_qualifier,tree args)6840404b540aSrobert build_asm_stmt (tree cv_qualifier, tree args)
6841404b540aSrobert {
6842404b540aSrobert   if (!ASM_VOLATILE_P (args) && cv_qualifier)
6843404b540aSrobert     ASM_VOLATILE_P (args) = 1;
6844404b540aSrobert   return add_stmt (args);
6845404b540aSrobert }
6846404b540aSrobert 
6847404b540aSrobert /* Build an asm-expr, whose components are a STRING, some OUTPUTS,
6848404b540aSrobert    some INPUTS, and some CLOBBERS.  The latter three may be NULL.
6849404b540aSrobert    SIMPLE indicates whether there was anything at all after the
6850404b540aSrobert    string in the asm expression -- asm("blah") and asm("blah" : )
6851404b540aSrobert    are subtly different.  We use a ASM_EXPR node to represent this.  */
6852404b540aSrobert tree
build_asm_expr(tree string,tree outputs,tree inputs,tree clobbers,bool simple)6853404b540aSrobert build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
6854404b540aSrobert 		bool simple)
6855404b540aSrobert {
6856404b540aSrobert   tree tail;
6857404b540aSrobert   tree args;
6858404b540aSrobert   int i;
6859404b540aSrobert   const char *constraint;
6860404b540aSrobert   const char **oconstraints;
6861404b540aSrobert   bool allows_mem, allows_reg, is_inout;
6862404b540aSrobert   int ninputs, noutputs;
6863404b540aSrobert 
6864404b540aSrobert   ninputs = list_length (inputs);
6865404b540aSrobert   noutputs = list_length (outputs);
6866404b540aSrobert   oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
6867404b540aSrobert 
6868404b540aSrobert   string = resolve_asm_operand_names (string, outputs, inputs);
6869404b540aSrobert 
6870404b540aSrobert   /* Remove output conversions that change the type but not the mode.  */
6871404b540aSrobert   for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
6872404b540aSrobert     {
6873404b540aSrobert       tree output = TREE_VALUE (tail);
6874404b540aSrobert 
6875404b540aSrobert       /* ??? Really, this should not be here.  Users should be using a
6876404b540aSrobert 	 proper lvalue, dammit.  But there's a long history of using casts
6877404b540aSrobert 	 in the output operands.  In cases like longlong.h, this becomes a
6878404b540aSrobert 	 primitive form of typechecking -- if the cast can be removed, then
6879404b540aSrobert 	 the output operand had a type of the proper width; otherwise we'll
6880404b540aSrobert 	 get an error.  Gross, but ...  */
6881404b540aSrobert       STRIP_NOPS (output);
6882404b540aSrobert 
6883404b540aSrobert       if (!lvalue_or_else (output, lv_asm))
6884404b540aSrobert 	output = error_mark_node;
6885404b540aSrobert 
6886404b540aSrobert       if (output != error_mark_node
6887404b540aSrobert 	  && (TREE_READONLY (output)
6888404b540aSrobert 	      || TYPE_READONLY (TREE_TYPE (output))
6889404b540aSrobert 	      || ((TREE_CODE (TREE_TYPE (output)) == RECORD_TYPE
6890404b540aSrobert 		   || TREE_CODE (TREE_TYPE (output)) == UNION_TYPE)
6891404b540aSrobert 		  && C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
6892404b540aSrobert 	readonly_error (output, lv_asm);
6893404b540aSrobert 
6894404b540aSrobert       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
6895404b540aSrobert       oconstraints[i] = constraint;
6896404b540aSrobert 
6897404b540aSrobert       if (parse_output_constraint (&constraint, i, ninputs, noutputs,
6898404b540aSrobert 				   &allows_mem, &allows_reg, &is_inout))
6899404b540aSrobert 	{
6900404b540aSrobert 	  /* If the operand is going to end up in memory,
6901404b540aSrobert 	     mark it addressable.  */
6902404b540aSrobert 	  if (!allows_reg && !c_mark_addressable (output))
6903404b540aSrobert 	    output = error_mark_node;
6904404b540aSrobert 	}
6905404b540aSrobert       else
6906404b540aSrobert 	output = error_mark_node;
6907404b540aSrobert 
6908404b540aSrobert       TREE_VALUE (tail) = output;
6909404b540aSrobert     }
6910404b540aSrobert 
6911404b540aSrobert   for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
6912404b540aSrobert     {
6913404b540aSrobert       tree input;
6914404b540aSrobert 
6915404b540aSrobert       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
6916404b540aSrobert       input = TREE_VALUE (tail);
6917404b540aSrobert 
6918404b540aSrobert       if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
6919404b540aSrobert 				  oconstraints, &allows_mem, &allows_reg))
6920404b540aSrobert 	{
6921404b540aSrobert 	  /* If the operand is going to end up in memory,
6922404b540aSrobert 	     mark it addressable.  */
6923404b540aSrobert 	  if (!allows_reg && allows_mem)
6924404b540aSrobert 	    {
6925404b540aSrobert 	      /* Strip the nops as we allow this case.  FIXME, this really
6926404b540aSrobert 		 should be rejected or made deprecated.  */
6927404b540aSrobert 	      STRIP_NOPS (input);
6928404b540aSrobert 	      if (!c_mark_addressable (input))
6929404b540aSrobert 		input = error_mark_node;
6930404b540aSrobert 	  }
6931404b540aSrobert 	}
6932404b540aSrobert       else
6933404b540aSrobert 	input = error_mark_node;
6934404b540aSrobert 
6935404b540aSrobert       TREE_VALUE (tail) = input;
6936404b540aSrobert     }
6937404b540aSrobert 
6938404b540aSrobert   args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
6939404b540aSrobert 
6940404b540aSrobert   /* asm statements without outputs, including simple ones, are treated
6941404b540aSrobert      as volatile.  */
6942404b540aSrobert   ASM_INPUT_P (args) = simple;
6943404b540aSrobert   ASM_VOLATILE_P (args) = (noutputs == 0);
6944404b540aSrobert 
6945404b540aSrobert   return args;
6946404b540aSrobert }
6947404b540aSrobert 
6948404b540aSrobert /* Generate a goto statement to LABEL.  */
6949404b540aSrobert 
6950404b540aSrobert tree
c_finish_goto_label(tree label)6951404b540aSrobert c_finish_goto_label (tree label)
6952404b540aSrobert {
6953404b540aSrobert   tree decl = lookup_label (label);
6954404b540aSrobert   if (!decl)
6955404b540aSrobert     return NULL_TREE;
6956404b540aSrobert 
6957404b540aSrobert   if (C_DECL_UNJUMPABLE_STMT_EXPR (decl))
6958404b540aSrobert     {
6959404b540aSrobert       error ("jump into statement expression");
6960404b540aSrobert       return NULL_TREE;
6961404b540aSrobert     }
6962404b540aSrobert 
6963404b540aSrobert   if (C_DECL_UNJUMPABLE_VM (decl))
6964404b540aSrobert     {
6965404b540aSrobert       error ("jump into scope of identifier with variably modified type");
6966404b540aSrobert       return NULL_TREE;
6967404b540aSrobert     }
6968404b540aSrobert 
6969404b540aSrobert   if (!C_DECL_UNDEFINABLE_STMT_EXPR (decl))
6970404b540aSrobert     {
6971404b540aSrobert       /* No jump from outside this statement expression context, so
6972404b540aSrobert 	 record that there is a jump from within this context.  */
6973404b540aSrobert       struct c_label_list *nlist;
6974404b540aSrobert       nlist = XOBNEW (&parser_obstack, struct c_label_list);
6975404b540aSrobert       nlist->next = label_context_stack_se->labels_used;
6976404b540aSrobert       nlist->label = decl;
6977404b540aSrobert       label_context_stack_se->labels_used = nlist;
6978404b540aSrobert     }
6979404b540aSrobert 
6980404b540aSrobert   if (!C_DECL_UNDEFINABLE_VM (decl))
6981404b540aSrobert     {
6982404b540aSrobert       /* No jump from outside this context context of identifiers with
6983404b540aSrobert 	 variably modified type, so record that there is a jump from
6984404b540aSrobert 	 within this context.  */
6985404b540aSrobert       struct c_label_list *nlist;
6986404b540aSrobert       nlist = XOBNEW (&parser_obstack, struct c_label_list);
6987404b540aSrobert       nlist->next = label_context_stack_vm->labels_used;
6988404b540aSrobert       nlist->label = decl;
6989404b540aSrobert       label_context_stack_vm->labels_used = nlist;
6990404b540aSrobert     }
6991404b540aSrobert 
6992404b540aSrobert   TREE_USED (decl) = 1;
6993404b540aSrobert   return add_stmt (build1 (GOTO_EXPR, void_type_node, decl));
6994404b540aSrobert }
6995404b540aSrobert 
6996404b540aSrobert /* Generate a computed goto statement to EXPR.  */
6997404b540aSrobert 
6998404b540aSrobert tree
c_finish_goto_ptr(tree expr)6999404b540aSrobert c_finish_goto_ptr (tree expr)
7000404b540aSrobert {
7001404b540aSrobert   if (pedantic)
7002404b540aSrobert     pedwarn ("ISO C forbids %<goto *expr;%>");
7003404b540aSrobert   expr = convert (ptr_type_node, expr);
7004404b540aSrobert   return add_stmt (build1 (GOTO_EXPR, void_type_node, expr));
7005404b540aSrobert }
7006404b540aSrobert 
7007404b540aSrobert /* Generate a C `return' statement.  RETVAL is the expression for what
7008404b540aSrobert    to return, or a null pointer for `return;' with no value.  */
7009404b540aSrobert 
7010404b540aSrobert tree
c_finish_return(tree retval)7011404b540aSrobert c_finish_return (tree retval)
7012404b540aSrobert {
7013404b540aSrobert   tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
7014404b540aSrobert   bool no_warning = false;
7015404b540aSrobert 
7016404b540aSrobert   if (TREE_THIS_VOLATILE (current_function_decl))
7017404b540aSrobert     warning (0, "function declared %<noreturn%> has a %<return%> statement");
7018404b540aSrobert 
7019404b540aSrobert   if (!retval)
7020404b540aSrobert     {
7021404b540aSrobert       current_function_returns_null = 1;
7022404b540aSrobert       if ((warn_return_type || flag_isoc99)
7023404b540aSrobert 	  && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
7024404b540aSrobert 	{
7025404b540aSrobert 	  pedwarn_c99 ("%<return%> with no value, in "
7026404b540aSrobert 		       "function returning non-void");
7027404b540aSrobert 	  no_warning = true;
7028404b540aSrobert 	}
7029404b540aSrobert     }
7030404b540aSrobert   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
7031404b540aSrobert     {
7032404b540aSrobert       current_function_returns_null = 1;
7033404b540aSrobert       if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
7034404b540aSrobert 	pedwarn ("%<return%> with a value, in function returning void");
7035404b540aSrobert     }
7036404b540aSrobert   else
7037404b540aSrobert     {
7038404b540aSrobert       tree t = convert_for_assignment (valtype, retval, ic_return,
7039404b540aSrobert 				       NULL_TREE, NULL_TREE, 0);
7040404b540aSrobert       tree res = DECL_RESULT (current_function_decl);
7041404b540aSrobert       tree inner;
7042404b540aSrobert 
7043404b540aSrobert       current_function_returns_value = 1;
7044404b540aSrobert       if (t == error_mark_node)
7045404b540aSrobert 	return NULL_TREE;
7046404b540aSrobert 
7047404b540aSrobert       inner = t = convert (TREE_TYPE (res), t);
7048404b540aSrobert 
7049404b540aSrobert       /* Strip any conversions, additions, and subtractions, and see if
7050404b540aSrobert 	 we are returning the address of a local variable.  Warn if so.  */
7051404b540aSrobert       while (1)
7052404b540aSrobert 	{
7053404b540aSrobert 	  switch (TREE_CODE (inner))
7054404b540aSrobert 	    {
7055404b540aSrobert 	    case NOP_EXPR:   case NON_LVALUE_EXPR:  case CONVERT_EXPR:
7056404b540aSrobert 	    case PLUS_EXPR:
7057404b540aSrobert 	      inner = TREE_OPERAND (inner, 0);
7058404b540aSrobert 	      continue;
7059404b540aSrobert 
7060404b540aSrobert 	    case MINUS_EXPR:
7061404b540aSrobert 	      /* If the second operand of the MINUS_EXPR has a pointer
7062404b540aSrobert 		 type (or is converted from it), this may be valid, so
7063404b540aSrobert 		 don't give a warning.  */
7064404b540aSrobert 	      {
7065404b540aSrobert 		tree op1 = TREE_OPERAND (inner, 1);
7066404b540aSrobert 
7067404b540aSrobert 		while (!POINTER_TYPE_P (TREE_TYPE (op1))
7068404b540aSrobert 		       && (TREE_CODE (op1) == NOP_EXPR
7069404b540aSrobert 			   || TREE_CODE (op1) == NON_LVALUE_EXPR
7070404b540aSrobert 			   || TREE_CODE (op1) == CONVERT_EXPR))
7071404b540aSrobert 		  op1 = TREE_OPERAND (op1, 0);
7072404b540aSrobert 
7073404b540aSrobert 		if (POINTER_TYPE_P (TREE_TYPE (op1)))
7074404b540aSrobert 		  break;
7075404b540aSrobert 
7076404b540aSrobert 		inner = TREE_OPERAND (inner, 0);
7077404b540aSrobert 		continue;
7078404b540aSrobert 	      }
7079404b540aSrobert 
7080404b540aSrobert 	    case ADDR_EXPR:
7081404b540aSrobert 	      inner = TREE_OPERAND (inner, 0);
7082404b540aSrobert 
7083404b540aSrobert 	      while (REFERENCE_CLASS_P (inner)
7084404b540aSrobert 		     && TREE_CODE (inner) != INDIRECT_REF)
7085404b540aSrobert 		inner = TREE_OPERAND (inner, 0);
7086404b540aSrobert 
7087404b540aSrobert 	      if (DECL_P (inner)
7088404b540aSrobert 		  && !DECL_EXTERNAL (inner)
7089404b540aSrobert 		  && !TREE_STATIC (inner)
7090404b540aSrobert 		  && DECL_CONTEXT (inner) == current_function_decl)
7091404b540aSrobert 		warning (0, "function returns address of local variable");
7092404b540aSrobert 	      break;
7093404b540aSrobert 
7094404b540aSrobert 	    default:
7095404b540aSrobert 	      break;
7096404b540aSrobert 	    }
7097404b540aSrobert 
7098404b540aSrobert 	  break;
7099404b540aSrobert 	}
7100404b540aSrobert 
7101404b540aSrobert       retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
7102404b540aSrobert     }
7103404b540aSrobert 
7104404b540aSrobert   ret_stmt = build_stmt (RETURN_EXPR, retval);
7105404b540aSrobert   TREE_NO_WARNING (ret_stmt) |= no_warning;
7106404b540aSrobert   return add_stmt (ret_stmt);
7107404b540aSrobert }
7108404b540aSrobert 
7109404b540aSrobert struct c_switch {
7110404b540aSrobert   /* The SWITCH_EXPR being built.  */
7111404b540aSrobert   tree switch_expr;
7112404b540aSrobert 
7113404b540aSrobert   /* The original type of the testing expression, i.e. before the
7114404b540aSrobert      default conversion is applied.  */
7115404b540aSrobert   tree orig_type;
7116404b540aSrobert 
7117404b540aSrobert   /* A splay-tree mapping the low element of a case range to the high
7118404b540aSrobert      element, or NULL_TREE if there is no high element.  Used to
7119404b540aSrobert      determine whether or not a new case label duplicates an old case
7120404b540aSrobert      label.  We need a tree, rather than simply a hash table, because
7121404b540aSrobert      of the GNU case range extension.  */
7122404b540aSrobert   splay_tree cases;
7123404b540aSrobert 
7124404b540aSrobert   /* Number of nested statement expressions within this switch
7125404b540aSrobert      statement; if nonzero, case and default labels may not
7126404b540aSrobert      appear.  */
7127404b540aSrobert   unsigned int blocked_stmt_expr;
7128404b540aSrobert 
7129404b540aSrobert   /* Scope of outermost declarations of identifiers with variably
7130404b540aSrobert      modified type within this switch statement; if nonzero, case and
7131404b540aSrobert      default labels may not appear.  */
7132404b540aSrobert   unsigned int blocked_vm;
7133404b540aSrobert 
7134404b540aSrobert   /* The next node on the stack.  */
7135404b540aSrobert   struct c_switch *next;
7136404b540aSrobert };
7137404b540aSrobert 
7138404b540aSrobert /* A stack of the currently active switch statements.  The innermost
7139404b540aSrobert    switch statement is on the top of the stack.  There is no need to
7140404b540aSrobert    mark the stack for garbage collection because it is only active
7141404b540aSrobert    during the processing of the body of a function, and we never
7142404b540aSrobert    collect at that point.  */
7143404b540aSrobert 
7144404b540aSrobert struct c_switch *c_switch_stack;
7145404b540aSrobert 
7146404b540aSrobert /* Start a C switch statement, testing expression EXP.  Return the new
7147404b540aSrobert    SWITCH_EXPR.  */
7148404b540aSrobert 
7149404b540aSrobert tree
c_start_case(tree exp)7150404b540aSrobert c_start_case (tree exp)
7151404b540aSrobert {
7152404b540aSrobert   tree orig_type = error_mark_node;
7153404b540aSrobert   struct c_switch *cs;
7154404b540aSrobert 
7155404b540aSrobert   if (exp != error_mark_node)
7156404b540aSrobert     {
7157404b540aSrobert       orig_type = TREE_TYPE (exp);
7158404b540aSrobert 
7159404b540aSrobert       if (!INTEGRAL_TYPE_P (orig_type))
7160404b540aSrobert 	{
7161404b540aSrobert 	  if (orig_type != error_mark_node)
7162404b540aSrobert 	    {
7163404b540aSrobert 	      error ("switch quantity not an integer");
7164404b540aSrobert 	      orig_type = error_mark_node;
7165404b540aSrobert 	    }
7166404b540aSrobert 	  exp = integer_zero_node;
7167404b540aSrobert 	}
7168404b540aSrobert       else
7169404b540aSrobert 	{
7170404b540aSrobert 	  tree type = TYPE_MAIN_VARIANT (orig_type);
7171404b540aSrobert 
7172404b540aSrobert 	  if (!in_system_header
7173404b540aSrobert 	      && (type == long_integer_type_node
7174404b540aSrobert 		  || type == long_unsigned_type_node))
7175404b540aSrobert 	    warning (OPT_Wtraditional, "%<long%> switch expression not "
7176404b540aSrobert 		     "converted to %<int%> in ISO C");
7177404b540aSrobert 
7178404b540aSrobert 	  exp = default_conversion (exp);
7179404b540aSrobert 	}
7180404b540aSrobert     }
7181404b540aSrobert 
7182404b540aSrobert   /* Add this new SWITCH_EXPR to the stack.  */
7183404b540aSrobert   cs = XNEW (struct c_switch);
7184404b540aSrobert   cs->switch_expr = build3 (SWITCH_EXPR, orig_type, exp, NULL_TREE, NULL_TREE);
7185404b540aSrobert   cs->orig_type = orig_type;
7186404b540aSrobert   cs->cases = splay_tree_new (case_compare, NULL, NULL);
7187404b540aSrobert   cs->blocked_stmt_expr = 0;
7188404b540aSrobert   cs->blocked_vm = 0;
7189404b540aSrobert   cs->next = c_switch_stack;
7190404b540aSrobert   c_switch_stack = cs;
7191404b540aSrobert 
7192404b540aSrobert   return add_stmt (cs->switch_expr);
7193404b540aSrobert }
7194404b540aSrobert 
7195404b540aSrobert /* Process a case label.  */
7196404b540aSrobert 
7197404b540aSrobert tree
do_case(tree low_value,tree high_value)7198404b540aSrobert do_case (tree low_value, tree high_value)
7199404b540aSrobert {
7200404b540aSrobert   tree label = NULL_TREE;
7201404b540aSrobert 
7202404b540aSrobert   if (c_switch_stack && !c_switch_stack->blocked_stmt_expr
7203404b540aSrobert       && !c_switch_stack->blocked_vm)
7204404b540aSrobert     {
7205404b540aSrobert       label = c_add_case_label (c_switch_stack->cases,
7206404b540aSrobert 				SWITCH_COND (c_switch_stack->switch_expr),
7207404b540aSrobert 				c_switch_stack->orig_type,
7208404b540aSrobert 				low_value, high_value);
7209404b540aSrobert       if (label == error_mark_node)
7210404b540aSrobert 	label = NULL_TREE;
7211404b540aSrobert     }
7212404b540aSrobert   else if (c_switch_stack && c_switch_stack->blocked_stmt_expr)
7213404b540aSrobert     {
7214404b540aSrobert       if (low_value)
7215404b540aSrobert 	error ("case label in statement expression not containing "
7216404b540aSrobert 	       "enclosing switch statement");
7217404b540aSrobert       else
7218404b540aSrobert 	error ("%<default%> label in statement expression not containing "
7219404b540aSrobert 	       "enclosing switch statement");
7220404b540aSrobert     }
7221404b540aSrobert   else if (c_switch_stack && c_switch_stack->blocked_vm)
7222404b540aSrobert     {
7223404b540aSrobert       if (low_value)
7224404b540aSrobert 	error ("case label in scope of identifier with variably modified "
7225404b540aSrobert 	       "type not containing enclosing switch statement");
7226404b540aSrobert       else
7227404b540aSrobert 	error ("%<default%> label in scope of identifier with variably "
7228404b540aSrobert 	       "modified type not containing enclosing switch statement");
7229404b540aSrobert     }
7230404b540aSrobert   else if (low_value)
7231404b540aSrobert     error ("case label not within a switch statement");
7232404b540aSrobert   else
7233404b540aSrobert     error ("%<default%> label not within a switch statement");
7234404b540aSrobert 
7235404b540aSrobert   return label;
7236404b540aSrobert }
7237404b540aSrobert 
7238404b540aSrobert /* Finish the switch statement.  */
7239404b540aSrobert 
7240404b540aSrobert void
c_finish_case(tree body)7241404b540aSrobert c_finish_case (tree body)
7242404b540aSrobert {
7243404b540aSrobert   struct c_switch *cs = c_switch_stack;
7244404b540aSrobert   location_t switch_location;
7245404b540aSrobert 
7246404b540aSrobert   SWITCH_BODY (cs->switch_expr) = body;
7247404b540aSrobert 
7248404b540aSrobert   /* We must not be within a statement expression nested in the switch
7249404b540aSrobert      at this point; we might, however, be within the scope of an
7250404b540aSrobert      identifier with variably modified type nested in the switch.  */
7251404b540aSrobert   gcc_assert (!cs->blocked_stmt_expr);
7252404b540aSrobert 
7253404b540aSrobert   /* Emit warnings as needed.  */
7254404b540aSrobert   if (EXPR_HAS_LOCATION (cs->switch_expr))
7255404b540aSrobert     switch_location = EXPR_LOCATION (cs->switch_expr);
7256404b540aSrobert   else
7257404b540aSrobert     switch_location = input_location;
7258404b540aSrobert   c_do_switch_warnings (cs->cases, switch_location,
7259404b540aSrobert 			TREE_TYPE (cs->switch_expr),
7260404b540aSrobert 			SWITCH_COND (cs->switch_expr));
7261404b540aSrobert 
7262404b540aSrobert   /* Pop the stack.  */
7263404b540aSrobert   c_switch_stack = cs->next;
7264404b540aSrobert   splay_tree_delete (cs->cases);
7265404b540aSrobert   XDELETE (cs);
7266404b540aSrobert }
7267404b540aSrobert 
7268404b540aSrobert /* Emit an if statement.  IF_LOCUS is the location of the 'if'.  COND,
7269404b540aSrobert    THEN_BLOCK and ELSE_BLOCK are expressions to be used; ELSE_BLOCK
7270404b540aSrobert    may be null.  NESTED_IF is true if THEN_BLOCK contains another IF
7271404b540aSrobert    statement, and was not surrounded with parenthesis.  */
7272404b540aSrobert 
7273404b540aSrobert void
c_finish_if_stmt(location_t if_locus,tree cond,tree then_block,tree else_block,bool nested_if)7274404b540aSrobert c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
7275404b540aSrobert 		  tree else_block, bool nested_if)
7276404b540aSrobert {
7277404b540aSrobert   tree stmt;
7278404b540aSrobert 
7279404b540aSrobert   /* Diagnose an ambiguous else if if-then-else is nested inside if-then.  */
7280404b540aSrobert   if (warn_parentheses && nested_if && else_block == NULL)
7281404b540aSrobert     {
7282404b540aSrobert       tree inner_if = then_block;
7283404b540aSrobert 
7284404b540aSrobert       /* We know from the grammar productions that there is an IF nested
7285404b540aSrobert 	 within THEN_BLOCK.  Due to labels and c99 conditional declarations,
7286404b540aSrobert 	 it might not be exactly THEN_BLOCK, but should be the last
7287404b540aSrobert 	 non-container statement within.  */
7288404b540aSrobert       while (1)
7289404b540aSrobert 	switch (TREE_CODE (inner_if))
7290404b540aSrobert 	  {
7291404b540aSrobert 	  case COND_EXPR:
7292404b540aSrobert 	    goto found;
7293404b540aSrobert 	  case BIND_EXPR:
7294404b540aSrobert 	    inner_if = BIND_EXPR_BODY (inner_if);
7295404b540aSrobert 	    break;
7296404b540aSrobert 	  case STATEMENT_LIST:
7297404b540aSrobert 	    inner_if = expr_last (then_block);
7298404b540aSrobert 	    break;
7299404b540aSrobert 	  case TRY_FINALLY_EXPR:
7300404b540aSrobert 	  case TRY_CATCH_EXPR:
7301404b540aSrobert 	    inner_if = TREE_OPERAND (inner_if, 0);
7302404b540aSrobert 	    break;
7303404b540aSrobert 	  default:
7304404b540aSrobert 	    gcc_unreachable ();
7305404b540aSrobert 	  }
7306404b540aSrobert     found:
7307404b540aSrobert 
7308404b540aSrobert       if (COND_EXPR_ELSE (inner_if))
7309404b540aSrobert 	 warning (OPT_Wparentheses,
7310404b540aSrobert 		  "%Hsuggest explicit braces to avoid ambiguous %<else%>",
7311404b540aSrobert 		  &if_locus);
7312404b540aSrobert     }
7313404b540aSrobert 
7314404b540aSrobert   empty_body_warning (then_block, else_block);
7315404b540aSrobert 
7316404b540aSrobert   stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
7317404b540aSrobert   SET_EXPR_LOCATION (stmt, if_locus);
7318404b540aSrobert   add_stmt (stmt);
7319404b540aSrobert }
7320404b540aSrobert 
7321404b540aSrobert /* Emit a general-purpose loop construct.  START_LOCUS is the location of
7322404b540aSrobert    the beginning of the loop.  COND is the loop condition.  COND_IS_FIRST
7323404b540aSrobert    is false for DO loops.  INCR is the FOR increment expression.  BODY is
7324404b540aSrobert    the statement controlled by the loop.  BLAB is the break label.  CLAB is
7325404b540aSrobert    the continue label.  Everything is allowed to be NULL.  */
7326404b540aSrobert 
7327404b540aSrobert void
c_finish_loop(location_t start_locus,tree cond,tree incr,tree body,tree blab,tree clab,bool cond_is_first)7328404b540aSrobert c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
7329404b540aSrobert 	       tree blab, tree clab, bool cond_is_first)
7330404b540aSrobert {
7331404b540aSrobert   tree entry = NULL, exit = NULL, t;
7332404b540aSrobert 
7333404b540aSrobert   /* If the condition is zero don't generate a loop construct.  */
7334404b540aSrobert   if (cond && integer_zerop (cond))
7335404b540aSrobert     {
7336404b540aSrobert       if (cond_is_first)
7337404b540aSrobert 	{
7338404b540aSrobert 	  t = build_and_jump (&blab);
7339404b540aSrobert 	  SET_EXPR_LOCATION (t, start_locus);
7340404b540aSrobert 	  add_stmt (t);
7341404b540aSrobert 	}
7342404b540aSrobert     }
7343404b540aSrobert   else
7344404b540aSrobert     {
7345404b540aSrobert       tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
7346404b540aSrobert 
7347404b540aSrobert       /* If we have an exit condition, then we build an IF with gotos either
7348404b540aSrobert 	 out of the loop, or to the top of it.  If there's no exit condition,
7349404b540aSrobert 	 then we just build a jump back to the top.  */
7350404b540aSrobert       exit = build_and_jump (&LABEL_EXPR_LABEL (top));
7351404b540aSrobert 
7352404b540aSrobert       if (cond && !integer_nonzerop (cond))
7353404b540aSrobert 	{
7354404b540aSrobert 	  /* Canonicalize the loop condition to the end.  This means
7355404b540aSrobert 	     generating a branch to the loop condition.  Reuse the
7356404b540aSrobert 	     continue label, if possible.  */
7357404b540aSrobert 	  if (cond_is_first)
7358404b540aSrobert 	    {
7359404b540aSrobert 	      if (incr || !clab)
7360404b540aSrobert 		{
7361404b540aSrobert 		  entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
7362404b540aSrobert 		  t = build_and_jump (&LABEL_EXPR_LABEL (entry));
7363404b540aSrobert 		}
7364404b540aSrobert 	      else
7365404b540aSrobert 		t = build1 (GOTO_EXPR, void_type_node, clab);
7366404b540aSrobert 	      SET_EXPR_LOCATION (t, start_locus);
7367404b540aSrobert 	      add_stmt (t);
7368404b540aSrobert 	    }
7369404b540aSrobert 
7370404b540aSrobert 	  t = build_and_jump (&blab);
7371404b540aSrobert 	  exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
7372404b540aSrobert 	  if (cond_is_first)
7373404b540aSrobert 	    SET_EXPR_LOCATION (exit, start_locus);
7374404b540aSrobert 	  else
7375404b540aSrobert 	    SET_EXPR_LOCATION (exit, input_location);
7376404b540aSrobert 	}
7377404b540aSrobert 
7378404b540aSrobert       add_stmt (top);
7379404b540aSrobert     }
7380404b540aSrobert 
7381404b540aSrobert   if (body)
7382404b540aSrobert     add_stmt (body);
7383404b540aSrobert   if (clab)
7384404b540aSrobert     add_stmt (build1 (LABEL_EXPR, void_type_node, clab));
7385404b540aSrobert   if (incr)
7386404b540aSrobert     add_stmt (incr);
7387404b540aSrobert   if (entry)
7388404b540aSrobert     add_stmt (entry);
7389404b540aSrobert   if (exit)
7390404b540aSrobert     add_stmt (exit);
7391404b540aSrobert   if (blab)
7392404b540aSrobert     add_stmt (build1 (LABEL_EXPR, void_type_node, blab));
7393404b540aSrobert }
7394404b540aSrobert 
7395404b540aSrobert tree
c_finish_bc_stmt(tree * label_p,bool is_break)7396404b540aSrobert c_finish_bc_stmt (tree *label_p, bool is_break)
7397404b540aSrobert {
7398404b540aSrobert   bool skip;
7399404b540aSrobert   tree label = *label_p;
7400404b540aSrobert 
7401404b540aSrobert   /* In switch statements break is sometimes stylistically used after
7402404b540aSrobert      a return statement.  This can lead to spurious warnings about
7403404b540aSrobert      control reaching the end of a non-void function when it is
7404404b540aSrobert      inlined.  Note that we are calling block_may_fallthru with
7405404b540aSrobert      language specific tree nodes; this works because
7406404b540aSrobert      block_may_fallthru returns true when given something it does not
7407404b540aSrobert      understand.  */
7408404b540aSrobert   skip = !block_may_fallthru (cur_stmt_list);
7409404b540aSrobert 
7410404b540aSrobert   if (!label)
7411404b540aSrobert     {
7412404b540aSrobert       if (!skip)
7413404b540aSrobert 	*label_p = label = create_artificial_label ();
7414404b540aSrobert     }
7415404b540aSrobert   else if (TREE_CODE (label) == LABEL_DECL)
7416404b540aSrobert     ;
7417404b540aSrobert   else switch (TREE_INT_CST_LOW (label))
7418404b540aSrobert     {
7419404b540aSrobert     case 0:
7420404b540aSrobert       if (is_break)
7421404b540aSrobert 	error ("break statement not within loop or switch");
7422404b540aSrobert       else
7423404b540aSrobert 	error ("continue statement not within a loop");
7424404b540aSrobert       return NULL_TREE;
7425404b540aSrobert 
7426404b540aSrobert     case 1:
7427404b540aSrobert       gcc_assert (is_break);
7428404b540aSrobert       error ("break statement used with OpenMP for loop");
7429404b540aSrobert       return NULL_TREE;
7430404b540aSrobert 
7431404b540aSrobert     default:
7432404b540aSrobert       gcc_unreachable ();
7433404b540aSrobert     }
7434404b540aSrobert 
7435404b540aSrobert   if (skip)
7436404b540aSrobert     return NULL_TREE;
7437404b540aSrobert 
7438404b540aSrobert   return add_stmt (build1 (GOTO_EXPR, void_type_node, label));
7439404b540aSrobert }
7440404b540aSrobert 
7441404b540aSrobert /* A helper routine for c_process_expr_stmt and c_finish_stmt_expr.  */
7442404b540aSrobert 
7443404b540aSrobert static void
emit_side_effect_warnings(tree expr)7444404b540aSrobert emit_side_effect_warnings (tree expr)
7445404b540aSrobert {
7446404b540aSrobert   if (expr == error_mark_node)
7447404b540aSrobert     ;
7448404b540aSrobert   else if (!TREE_SIDE_EFFECTS (expr))
7449404b540aSrobert     {
7450404b540aSrobert       if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
7451404b540aSrobert 	warning (0, "%Hstatement with no effect",
7452404b540aSrobert 		 EXPR_HAS_LOCATION (expr) ? EXPR_LOCUS (expr) : &input_location);
7453404b540aSrobert     }
7454404b540aSrobert   else if (warn_unused_value)
7455404b540aSrobert     warn_if_unused_value (expr, input_location);
7456404b540aSrobert }
7457404b540aSrobert 
7458404b540aSrobert /* Process an expression as if it were a complete statement.  Emit
7459404b540aSrobert    diagnostics, but do not call ADD_STMT.  */
7460404b540aSrobert 
7461404b540aSrobert tree
c_process_expr_stmt(tree expr)7462404b540aSrobert c_process_expr_stmt (tree expr)
7463404b540aSrobert {
7464404b540aSrobert   if (!expr)
7465404b540aSrobert     return NULL_TREE;
7466404b540aSrobert 
7467404b540aSrobert   if (warn_sequence_point)
7468404b540aSrobert     verify_sequence_points (expr);
7469404b540aSrobert 
7470404b540aSrobert   if (TREE_TYPE (expr) != error_mark_node
7471404b540aSrobert       && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
7472404b540aSrobert       && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
7473404b540aSrobert     error ("expression statement has incomplete type");
7474404b540aSrobert 
7475404b540aSrobert   /* If we're not processing a statement expression, warn about unused values.
7476404b540aSrobert      Warnings for statement expressions will be emitted later, once we figure
7477404b540aSrobert      out which is the result.  */
7478404b540aSrobert   if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
7479404b540aSrobert       && (extra_warnings || warn_unused_value))
7480404b540aSrobert     emit_side_effect_warnings (expr);
7481404b540aSrobert 
7482404b540aSrobert   /* If the expression is not of a type to which we cannot assign a line
7483404b540aSrobert      number, wrap the thing in a no-op NOP_EXPR.  */
7484404b540aSrobert   if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
7485404b540aSrobert     expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
7486404b540aSrobert 
7487404b540aSrobert   if (EXPR_P (expr))
7488404b540aSrobert     SET_EXPR_LOCATION (expr, input_location);
7489404b540aSrobert 
7490404b540aSrobert   return expr;
7491404b540aSrobert }
7492404b540aSrobert 
7493404b540aSrobert /* Emit an expression as a statement.  */
7494404b540aSrobert 
7495404b540aSrobert tree
c_finish_expr_stmt(tree expr)7496404b540aSrobert c_finish_expr_stmt (tree expr)
7497404b540aSrobert {
7498404b540aSrobert   if (expr)
7499404b540aSrobert     return add_stmt (c_process_expr_stmt (expr));
7500404b540aSrobert   else
7501404b540aSrobert     return NULL;
7502404b540aSrobert }
7503404b540aSrobert 
7504404b540aSrobert /* Do the opposite and emit a statement as an expression.  To begin,
7505404b540aSrobert    create a new binding level and return it.  */
7506404b540aSrobert 
7507404b540aSrobert tree
c_begin_stmt_expr(void)7508404b540aSrobert c_begin_stmt_expr (void)
7509404b540aSrobert {
7510404b540aSrobert   tree ret;
7511404b540aSrobert   struct c_label_context_se *nstack;
7512404b540aSrobert   struct c_label_list *glist;
7513404b540aSrobert 
7514404b540aSrobert   /* We must force a BLOCK for this level so that, if it is not expanded
7515404b540aSrobert      later, there is a way to turn off the entire subtree of blocks that
7516404b540aSrobert      are contained in it.  */
7517404b540aSrobert   keep_next_level ();
7518404b540aSrobert   ret = c_begin_compound_stmt (true);
7519404b540aSrobert   if (c_switch_stack)
7520404b540aSrobert     {
7521404b540aSrobert       c_switch_stack->blocked_stmt_expr++;
7522404b540aSrobert       gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
7523404b540aSrobert     }
7524404b540aSrobert   for (glist = label_context_stack_se->labels_used;
7525404b540aSrobert        glist != NULL;
7526404b540aSrobert        glist = glist->next)
7527404b540aSrobert     {
7528404b540aSrobert       C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 1;
7529404b540aSrobert     }
7530404b540aSrobert   nstack = XOBNEW (&parser_obstack, struct c_label_context_se);
7531404b540aSrobert   nstack->labels_def = NULL;
7532404b540aSrobert   nstack->labels_used = NULL;
7533404b540aSrobert   nstack->next = label_context_stack_se;
7534404b540aSrobert   label_context_stack_se = nstack;
7535404b540aSrobert 
7536404b540aSrobert   /* Mark the current statement list as belonging to a statement list.  */
7537404b540aSrobert   STATEMENT_LIST_STMT_EXPR (ret) = 1;
7538404b540aSrobert 
7539404b540aSrobert   return ret;
7540404b540aSrobert }
7541404b540aSrobert 
7542404b540aSrobert tree
c_finish_stmt_expr(tree body)7543404b540aSrobert c_finish_stmt_expr (tree body)
7544404b540aSrobert {
7545404b540aSrobert   tree last, type, tmp, val;
7546404b540aSrobert   tree *last_p;
7547404b540aSrobert   struct c_label_list *dlist, *glist, *glist_prev = NULL;
7548404b540aSrobert 
7549404b540aSrobert   body = c_end_compound_stmt (body, true);
7550404b540aSrobert   if (c_switch_stack)
7551404b540aSrobert     {
7552404b540aSrobert       gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
7553404b540aSrobert       c_switch_stack->blocked_stmt_expr--;
7554404b540aSrobert     }
7555404b540aSrobert   /* It is no longer possible to jump to labels defined within this
7556404b540aSrobert      statement expression.  */
7557404b540aSrobert   for (dlist = label_context_stack_se->labels_def;
7558404b540aSrobert        dlist != NULL;
7559404b540aSrobert        dlist = dlist->next)
7560404b540aSrobert     {
7561404b540aSrobert       C_DECL_UNJUMPABLE_STMT_EXPR (dlist->label) = 1;
7562404b540aSrobert     }
7563404b540aSrobert   /* It is again possible to define labels with a goto just outside
7564404b540aSrobert      this statement expression.  */
7565404b540aSrobert   for (glist = label_context_stack_se->next->labels_used;
7566404b540aSrobert        glist != NULL;
7567404b540aSrobert        glist = glist->next)
7568404b540aSrobert     {
7569404b540aSrobert       C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 0;
7570404b540aSrobert       glist_prev = glist;
7571404b540aSrobert     }
7572404b540aSrobert   if (glist_prev != NULL)
7573404b540aSrobert     glist_prev->next = label_context_stack_se->labels_used;
7574404b540aSrobert   else
7575404b540aSrobert     label_context_stack_se->next->labels_used
7576404b540aSrobert       = label_context_stack_se->labels_used;
7577404b540aSrobert   label_context_stack_se = label_context_stack_se->next;
7578404b540aSrobert 
7579404b540aSrobert   /* Locate the last statement in BODY.  See c_end_compound_stmt
7580404b540aSrobert      about always returning a BIND_EXPR.  */
7581404b540aSrobert   last_p = &BIND_EXPR_BODY (body);
7582404b540aSrobert   last = BIND_EXPR_BODY (body);
7583404b540aSrobert 
7584404b540aSrobert  continue_searching:
7585404b540aSrobert   if (TREE_CODE (last) == STATEMENT_LIST)
7586404b540aSrobert     {
7587404b540aSrobert       tree_stmt_iterator i;
7588404b540aSrobert 
7589404b540aSrobert       /* This can happen with degenerate cases like ({ }).  No value.  */
7590404b540aSrobert       if (!TREE_SIDE_EFFECTS (last))
7591404b540aSrobert 	return body;
7592404b540aSrobert 
7593404b540aSrobert       /* If we're supposed to generate side effects warnings, process
7594404b540aSrobert 	 all of the statements except the last.  */
7595404b540aSrobert       if (extra_warnings || warn_unused_value)
7596404b540aSrobert 	{
7597404b540aSrobert 	  for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i))
7598404b540aSrobert 	    emit_side_effect_warnings (tsi_stmt (i));
7599404b540aSrobert 	}
7600404b540aSrobert       else
7601404b540aSrobert 	i = tsi_last (last);
7602404b540aSrobert       last_p = tsi_stmt_ptr (i);
7603404b540aSrobert       last = *last_p;
7604404b540aSrobert     }
7605404b540aSrobert 
7606404b540aSrobert   /* If the end of the list is exception related, then the list was split
7607404b540aSrobert      by a call to push_cleanup.  Continue searching.  */
7608404b540aSrobert   if (TREE_CODE (last) == TRY_FINALLY_EXPR
7609404b540aSrobert       || TREE_CODE (last) == TRY_CATCH_EXPR)
7610404b540aSrobert     {
7611404b540aSrobert       last_p = &TREE_OPERAND (last, 0);
7612404b540aSrobert       last = *last_p;
7613404b540aSrobert       goto continue_searching;
7614404b540aSrobert     }
7615404b540aSrobert 
7616404b540aSrobert   /* In the case that the BIND_EXPR is not necessary, return the
7617404b540aSrobert      expression out from inside it.  */
7618404b540aSrobert   if (last == error_mark_node
7619404b540aSrobert       || (last == BIND_EXPR_BODY (body)
7620404b540aSrobert 	  && BIND_EXPR_VARS (body) == NULL))
7621404b540aSrobert     {
7622404b540aSrobert       /* Do not warn if the return value of a statement expression is
7623404b540aSrobert 	 unused.  */
7624404b540aSrobert       if (EXPR_P (last))
7625404b540aSrobert 	TREE_NO_WARNING (last) = 1;
7626404b540aSrobert       return last;
7627404b540aSrobert     }
7628404b540aSrobert 
7629404b540aSrobert   /* Extract the type of said expression.  */
7630404b540aSrobert   type = TREE_TYPE (last);
7631404b540aSrobert 
7632404b540aSrobert   /* If we're not returning a value at all, then the BIND_EXPR that
7633404b540aSrobert      we already have is a fine expression to return.  */
7634404b540aSrobert   if (!type || VOID_TYPE_P (type))
7635404b540aSrobert     return body;
7636404b540aSrobert 
7637404b540aSrobert   /* Now that we've located the expression containing the value, it seems
7638404b540aSrobert      silly to make voidify_wrapper_expr repeat the process.  Create a
7639404b540aSrobert      temporary of the appropriate type and stick it in a TARGET_EXPR.  */
7640404b540aSrobert   tmp = create_tmp_var_raw (type, NULL);
7641404b540aSrobert 
7642404b540aSrobert   /* Unwrap a no-op NOP_EXPR as added by c_finish_expr_stmt.  This avoids
7643404b540aSrobert      tree_expr_nonnegative_p giving up immediately.  */
7644404b540aSrobert   val = last;
7645404b540aSrobert   if (TREE_CODE (val) == NOP_EXPR
7646404b540aSrobert       && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)))
7647404b540aSrobert     val = TREE_OPERAND (val, 0);
7648404b540aSrobert 
7649404b540aSrobert   *last_p = build2 (MODIFY_EXPR, void_type_node, tmp, val);
7650404b540aSrobert   SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last));
7651404b540aSrobert 
7652404b540aSrobert   return build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
7653404b540aSrobert }
7654404b540aSrobert 
7655404b540aSrobert /* Begin the scope of an identifier of variably modified type, scope
7656404b540aSrobert    number SCOPE.  Jumping from outside this scope to inside it is not
7657404b540aSrobert    permitted.  */
7658404b540aSrobert 
7659404b540aSrobert void
c_begin_vm_scope(unsigned int scope)7660404b540aSrobert c_begin_vm_scope (unsigned int scope)
7661404b540aSrobert {
7662404b540aSrobert   struct c_label_context_vm *nstack;
7663404b540aSrobert   struct c_label_list *glist;
7664404b540aSrobert 
7665404b540aSrobert   gcc_assert (scope > 0);
7666404b540aSrobert 
7667404b540aSrobert   /* At file_scope, we don't have to do any processing.  */
7668404b540aSrobert   if (label_context_stack_vm == NULL)
7669404b540aSrobert     return;
7670404b540aSrobert 
7671404b540aSrobert   if (c_switch_stack && !c_switch_stack->blocked_vm)
7672404b540aSrobert     c_switch_stack->blocked_vm = scope;
7673404b540aSrobert   for (glist = label_context_stack_vm->labels_used;
7674404b540aSrobert        glist != NULL;
7675404b540aSrobert        glist = glist->next)
7676404b540aSrobert     {
7677404b540aSrobert       C_DECL_UNDEFINABLE_VM (glist->label) = 1;
7678404b540aSrobert     }
7679404b540aSrobert   nstack = XOBNEW (&parser_obstack, struct c_label_context_vm);
7680404b540aSrobert   nstack->labels_def = NULL;
7681404b540aSrobert   nstack->labels_used = NULL;
7682404b540aSrobert   nstack->scope = scope;
7683404b540aSrobert   nstack->next = label_context_stack_vm;
7684404b540aSrobert   label_context_stack_vm = nstack;
7685404b540aSrobert }
7686404b540aSrobert 
7687404b540aSrobert /* End a scope which may contain identifiers of variably modified
7688404b540aSrobert    type, scope number SCOPE.  */
7689404b540aSrobert 
7690404b540aSrobert void
c_end_vm_scope(unsigned int scope)7691404b540aSrobert c_end_vm_scope (unsigned int scope)
7692404b540aSrobert {
7693404b540aSrobert   if (label_context_stack_vm == NULL)
7694404b540aSrobert     return;
7695404b540aSrobert   if (c_switch_stack && c_switch_stack->blocked_vm == scope)
7696404b540aSrobert     c_switch_stack->blocked_vm = 0;
7697404b540aSrobert   /* We may have a number of nested scopes of identifiers with
7698404b540aSrobert      variably modified type, all at this depth.  Pop each in turn.  */
7699404b540aSrobert   while (label_context_stack_vm->scope == scope)
7700404b540aSrobert     {
7701404b540aSrobert       struct c_label_list *dlist, *glist, *glist_prev = NULL;
7702404b540aSrobert 
7703404b540aSrobert       /* It is no longer possible to jump to labels defined within this
7704404b540aSrobert 	 scope.  */
7705404b540aSrobert       for (dlist = label_context_stack_vm->labels_def;
7706404b540aSrobert 	   dlist != NULL;
7707404b540aSrobert 	   dlist = dlist->next)
7708404b540aSrobert 	{
7709404b540aSrobert 	  C_DECL_UNJUMPABLE_VM (dlist->label) = 1;
7710404b540aSrobert 	}
7711404b540aSrobert       /* It is again possible to define labels with a goto just outside
7712404b540aSrobert 	 this scope.  */
7713404b540aSrobert       for (glist = label_context_stack_vm->next->labels_used;
7714404b540aSrobert 	   glist != NULL;
7715404b540aSrobert 	   glist = glist->next)
7716404b540aSrobert 	{
7717404b540aSrobert 	  C_DECL_UNDEFINABLE_VM (glist->label) = 0;
7718404b540aSrobert 	  glist_prev = glist;
7719404b540aSrobert 	}
7720404b540aSrobert       if (glist_prev != NULL)
7721404b540aSrobert 	glist_prev->next = label_context_stack_vm->labels_used;
7722404b540aSrobert       else
7723404b540aSrobert 	label_context_stack_vm->next->labels_used
7724404b540aSrobert 	  = label_context_stack_vm->labels_used;
7725404b540aSrobert       label_context_stack_vm = label_context_stack_vm->next;
7726404b540aSrobert     }
7727404b540aSrobert }
7728404b540aSrobert 
7729404b540aSrobert /* Begin and end compound statements.  This is as simple as pushing
7730404b540aSrobert    and popping new statement lists from the tree.  */
7731404b540aSrobert 
7732404b540aSrobert tree
c_begin_compound_stmt(bool do_scope)7733404b540aSrobert c_begin_compound_stmt (bool do_scope)
7734404b540aSrobert {
7735404b540aSrobert   tree stmt = push_stmt_list ();
7736404b540aSrobert   if (do_scope)
7737404b540aSrobert     push_scope ();
7738404b540aSrobert   return stmt;
7739404b540aSrobert }
7740404b540aSrobert 
7741404b540aSrobert tree
c_end_compound_stmt(tree stmt,bool do_scope)7742404b540aSrobert c_end_compound_stmt (tree stmt, bool do_scope)
7743404b540aSrobert {
7744404b540aSrobert   tree block = NULL;
7745404b540aSrobert 
7746404b540aSrobert   if (do_scope)
7747404b540aSrobert     {
7748404b540aSrobert       if (c_dialect_objc ())
7749404b540aSrobert 	objc_clear_super_receiver ();
7750404b540aSrobert       block = pop_scope ();
7751404b540aSrobert     }
7752404b540aSrobert 
7753404b540aSrobert   stmt = pop_stmt_list (stmt);
7754404b540aSrobert   stmt = c_build_bind_expr (block, stmt);
7755404b540aSrobert 
7756404b540aSrobert   /* If this compound statement is nested immediately inside a statement
7757404b540aSrobert      expression, then force a BIND_EXPR to be created.  Otherwise we'll
7758404b540aSrobert      do the wrong thing for ({ { 1; } }) or ({ 1; { } }).  In particular,
7759404b540aSrobert      STATEMENT_LISTs merge, and thus we can lose track of what statement
7760404b540aSrobert      was really last.  */
7761404b540aSrobert   if (cur_stmt_list
7762404b540aSrobert       && STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
7763404b540aSrobert       && TREE_CODE (stmt) != BIND_EXPR)
7764404b540aSrobert     {
7765404b540aSrobert       stmt = build3 (BIND_EXPR, void_type_node, NULL, stmt, NULL);
7766404b540aSrobert       TREE_SIDE_EFFECTS (stmt) = 1;
7767404b540aSrobert     }
7768404b540aSrobert 
7769404b540aSrobert   return stmt;
7770404b540aSrobert }
7771404b540aSrobert 
7772404b540aSrobert /* Queue a cleanup.  CLEANUP is an expression/statement to be executed
7773404b540aSrobert    when the current scope is exited.  EH_ONLY is true when this is not
7774404b540aSrobert    meant to apply to normal control flow transfer.  */
7775404b540aSrobert 
7776404b540aSrobert void
push_cleanup(tree ARG_UNUSED (decl),tree cleanup,bool eh_only)7777404b540aSrobert push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only)
7778404b540aSrobert {
7779404b540aSrobert   enum tree_code code;
7780404b540aSrobert   tree stmt, list;
7781404b540aSrobert   bool stmt_expr;
7782404b540aSrobert 
7783404b540aSrobert   code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
7784404b540aSrobert   stmt = build_stmt (code, NULL, cleanup);
7785404b540aSrobert   add_stmt (stmt);
7786404b540aSrobert   stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list);
7787404b540aSrobert   list = push_stmt_list ();
7788404b540aSrobert   TREE_OPERAND (stmt, 0) = list;
7789404b540aSrobert   STATEMENT_LIST_STMT_EXPR (list) = stmt_expr;
7790404b540aSrobert }
7791404b540aSrobert 
7792404b540aSrobert /* Build a binary-operation expression without default conversions.
7793404b540aSrobert    CODE is the kind of expression to build.
7794404b540aSrobert    This function differs from `build' in several ways:
7795404b540aSrobert    the data type of the result is computed and recorded in it,
7796404b540aSrobert    warnings are generated if arg data types are invalid,
7797404b540aSrobert    special handling for addition and subtraction of pointers is known,
7798404b540aSrobert    and some optimization is done (operations on narrow ints
7799404b540aSrobert    are done in the narrower type when that gives the same result).
7800404b540aSrobert    Constant folding is also done before the result is returned.
7801404b540aSrobert 
7802404b540aSrobert    Note that the operands will never have enumeral types, or function
7803404b540aSrobert    or array types, because either they will have the default conversions
7804404b540aSrobert    performed or they have both just been converted to some other type in which
7805404b540aSrobert    the arithmetic is to be done.  */
7806404b540aSrobert 
7807404b540aSrobert tree
build_binary_op(enum tree_code code,tree orig_op0,tree orig_op1,int convert_p)7808404b540aSrobert build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
7809404b540aSrobert 		 int convert_p)
7810404b540aSrobert {
7811404b540aSrobert   tree type0, type1;
7812404b540aSrobert   enum tree_code code0, code1;
7813404b540aSrobert   tree op0, op1;
7814404b540aSrobert   const char *invalid_op_diag;
7815404b540aSrobert 
7816404b540aSrobert   /* Expression code to give to the expression when it is built.
7817404b540aSrobert      Normally this is CODE, which is what the caller asked for,
7818404b540aSrobert      but in some special cases we change it.  */
7819404b540aSrobert   enum tree_code resultcode = code;
7820404b540aSrobert 
7821404b540aSrobert   /* Data type in which the computation is to be performed.
7822404b540aSrobert      In the simplest cases this is the common type of the arguments.  */
7823404b540aSrobert   tree result_type = NULL;
7824404b540aSrobert 
7825404b540aSrobert   /* Nonzero means operands have already been type-converted
7826404b540aSrobert      in whatever way is necessary.
7827404b540aSrobert      Zero means they need to be converted to RESULT_TYPE.  */
7828404b540aSrobert   int converted = 0;
7829404b540aSrobert 
7830404b540aSrobert   /* Nonzero means create the expression with this type, rather than
7831404b540aSrobert      RESULT_TYPE.  */
7832404b540aSrobert   tree build_type = 0;
7833404b540aSrobert 
7834404b540aSrobert   /* Nonzero means after finally constructing the expression
7835404b540aSrobert      convert it to this type.  */
7836404b540aSrobert   tree final_type = 0;
7837404b540aSrobert 
7838404b540aSrobert   /* Nonzero if this is an operation like MIN or MAX which can
7839404b540aSrobert      safely be computed in short if both args are promoted shorts.
7840404b540aSrobert      Also implies COMMON.
7841404b540aSrobert      -1 indicates a bitwise operation; this makes a difference
7842404b540aSrobert      in the exact conditions for when it is safe to do the operation
7843404b540aSrobert      in a narrower mode.  */
7844404b540aSrobert   int shorten = 0;
7845404b540aSrobert 
7846404b540aSrobert   /* Nonzero if this is a comparison operation;
7847404b540aSrobert      if both args are promoted shorts, compare the original shorts.
7848404b540aSrobert      Also implies COMMON.  */
7849404b540aSrobert   int short_compare = 0;
7850404b540aSrobert 
7851404b540aSrobert   /* Nonzero if this is a right-shift operation, which can be computed on the
7852404b540aSrobert      original short and then promoted if the operand is a promoted short.  */
7853404b540aSrobert   int short_shift = 0;
7854404b540aSrobert 
7855404b540aSrobert   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
7856404b540aSrobert   int common = 0;
7857404b540aSrobert 
7858404b540aSrobert   /* True means types are compatible as far as ObjC is concerned.  */
7859404b540aSrobert   bool objc_ok;
7860404b540aSrobert 
7861404b540aSrobert   if (convert_p)
7862404b540aSrobert     {
7863404b540aSrobert       op0 = default_conversion (orig_op0);
7864404b540aSrobert       op1 = default_conversion (orig_op1);
7865404b540aSrobert     }
7866404b540aSrobert   else
7867404b540aSrobert     {
7868404b540aSrobert       op0 = orig_op0;
7869404b540aSrobert       op1 = orig_op1;
7870404b540aSrobert     }
7871404b540aSrobert 
7872404b540aSrobert   type0 = TREE_TYPE (op0);
7873404b540aSrobert   type1 = TREE_TYPE (op1);
7874404b540aSrobert 
7875404b540aSrobert   /* The expression codes of the data types of the arguments tell us
7876404b540aSrobert      whether the arguments are integers, floating, pointers, etc.  */
7877404b540aSrobert   code0 = TREE_CODE (type0);
7878404b540aSrobert   code1 = TREE_CODE (type1);
7879404b540aSrobert 
7880404b540aSrobert   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
7881404b540aSrobert   STRIP_TYPE_NOPS (op0);
7882404b540aSrobert   STRIP_TYPE_NOPS (op1);
7883404b540aSrobert 
7884404b540aSrobert   /* If an error was already reported for one of the arguments,
7885404b540aSrobert      avoid reporting another error.  */
7886404b540aSrobert 
7887404b540aSrobert   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
7888404b540aSrobert     return error_mark_node;
7889404b540aSrobert 
7890404b540aSrobert   if ((invalid_op_diag
7891404b540aSrobert        = targetm.invalid_binary_op (code, type0, type1)))
7892404b540aSrobert     {
7893404b540aSrobert       error (invalid_op_diag);
7894404b540aSrobert       return error_mark_node;
7895404b540aSrobert     }
7896404b540aSrobert 
7897404b540aSrobert   objc_ok = objc_compare_types (type0, type1, -3, NULL_TREE);
7898404b540aSrobert 
7899404b540aSrobert   switch (code)
7900404b540aSrobert     {
7901404b540aSrobert     case PLUS_EXPR:
7902404b540aSrobert       /* Handle the pointer + int case.  */
7903404b540aSrobert       if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
7904404b540aSrobert 	return pointer_int_sum (PLUS_EXPR, op0, op1);
7905404b540aSrobert       else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
7906404b540aSrobert 	return pointer_int_sum (PLUS_EXPR, op1, op0);
7907404b540aSrobert       else
7908404b540aSrobert 	common = 1;
7909404b540aSrobert       break;
7910404b540aSrobert 
7911404b540aSrobert     case MINUS_EXPR:
7912404b540aSrobert       /* Subtraction of two similar pointers.
7913404b540aSrobert 	 We must subtract them as integers, then divide by object size.  */
7914404b540aSrobert       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
7915404b540aSrobert 	  && comp_target_types (type0, type1))
7916404b540aSrobert 	return pointer_diff (op0, op1);
7917404b540aSrobert       /* Handle pointer minus int.  Just like pointer plus int.  */
7918404b540aSrobert       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
7919404b540aSrobert 	return pointer_int_sum (MINUS_EXPR, op0, op1);
7920404b540aSrobert       else
7921404b540aSrobert 	common = 1;
7922404b540aSrobert       break;
7923404b540aSrobert 
7924404b540aSrobert     case MULT_EXPR:
7925404b540aSrobert       common = 1;
7926404b540aSrobert       break;
7927404b540aSrobert 
7928404b540aSrobert     case TRUNC_DIV_EXPR:
7929404b540aSrobert     case CEIL_DIV_EXPR:
7930404b540aSrobert     case FLOOR_DIV_EXPR:
7931404b540aSrobert     case ROUND_DIV_EXPR:
7932404b540aSrobert     case EXACT_DIV_EXPR:
7933404b540aSrobert       /* Floating point division by zero is a legitimate way to obtain
7934404b540aSrobert 	 infinities and NaNs.  */
7935404b540aSrobert       if (skip_evaluation == 0 && integer_zerop (op1))
7936404b540aSrobert 	warning (OPT_Wdiv_by_zero, "division by zero");
7937404b540aSrobert 
7938404b540aSrobert       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
7939404b540aSrobert 	   || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
7940404b540aSrobert 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
7941404b540aSrobert 	      || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
7942404b540aSrobert 	{
7943404b540aSrobert 	  enum tree_code tcode0 = code0, tcode1 = code1;
7944404b540aSrobert 
7945404b540aSrobert 	  if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
7946404b540aSrobert 	    tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
7947404b540aSrobert 	  if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
7948404b540aSrobert 	    tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
7949404b540aSrobert 
7950404b540aSrobert 	  if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
7951404b540aSrobert 	    resultcode = RDIV_EXPR;
7952404b540aSrobert 	  else
7953404b540aSrobert 	    /* Although it would be tempting to shorten always here, that
7954404b540aSrobert 	       loses on some targets, since the modulo instruction is
7955404b540aSrobert 	       undefined if the quotient can't be represented in the
7956404b540aSrobert 	       computation mode.  We shorten only if unsigned or if
7957404b540aSrobert 	       dividing by something we know != -1.  */
7958404b540aSrobert 	    shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
7959404b540aSrobert 		       || (TREE_CODE (op1) == INTEGER_CST
7960404b540aSrobert 			   && !integer_all_onesp (op1)));
7961404b540aSrobert 	  common = 1;
7962404b540aSrobert 	}
7963404b540aSrobert       break;
7964404b540aSrobert 
7965404b540aSrobert     case BIT_AND_EXPR:
7966404b540aSrobert     case BIT_IOR_EXPR:
7967404b540aSrobert     case BIT_XOR_EXPR:
7968404b540aSrobert       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
7969404b540aSrobert 	shorten = -1;
7970404b540aSrobert       else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
7971404b540aSrobert 	common = 1;
7972404b540aSrobert       break;
7973404b540aSrobert 
7974404b540aSrobert     case TRUNC_MOD_EXPR:
7975404b540aSrobert     case FLOOR_MOD_EXPR:
7976404b540aSrobert       if (skip_evaluation == 0 && integer_zerop (op1))
7977404b540aSrobert 	warning (OPT_Wdiv_by_zero, "division by zero");
7978404b540aSrobert 
7979404b540aSrobert       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
7980404b540aSrobert 	{
7981404b540aSrobert 	  /* Although it would be tempting to shorten always here, that loses
7982404b540aSrobert 	     on some targets, since the modulo instruction is undefined if the
7983404b540aSrobert 	     quotient can't be represented in the computation mode.  We shorten
7984404b540aSrobert 	     only if unsigned or if dividing by something we know != -1.  */
7985404b540aSrobert 	  shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
7986404b540aSrobert 		     || (TREE_CODE (op1) == INTEGER_CST
7987404b540aSrobert 			 && !integer_all_onesp (op1)));
7988404b540aSrobert 	  common = 1;
7989404b540aSrobert 	}
7990404b540aSrobert       break;
7991404b540aSrobert 
7992404b540aSrobert     case TRUTH_ANDIF_EXPR:
7993404b540aSrobert     case TRUTH_ORIF_EXPR:
7994404b540aSrobert     case TRUTH_AND_EXPR:
7995404b540aSrobert     case TRUTH_OR_EXPR:
7996404b540aSrobert     case TRUTH_XOR_EXPR:
7997404b540aSrobert       if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
7998404b540aSrobert 	   || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
7999404b540aSrobert 	  && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
8000404b540aSrobert 	      || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
8001404b540aSrobert 	{
8002404b540aSrobert 	  /* Result of these operations is always an int,
8003404b540aSrobert 	     but that does not mean the operands should be
8004404b540aSrobert 	     converted to ints!  */
8005404b540aSrobert 	  result_type = integer_type_node;
8006404b540aSrobert 	  op0 = c_common_truthvalue_conversion (op0);
8007404b540aSrobert 	  op1 = c_common_truthvalue_conversion (op1);
8008404b540aSrobert 	  converted = 1;
8009404b540aSrobert 	}
8010404b540aSrobert       break;
8011404b540aSrobert 
8012404b540aSrobert       /* Shift operations: result has same type as first operand;
8013404b540aSrobert 	 always convert second operand to int.
8014404b540aSrobert 	 Also set SHORT_SHIFT if shifting rightward.  */
8015404b540aSrobert 
8016404b540aSrobert     case RSHIFT_EXPR:
8017404b540aSrobert       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
8018404b540aSrobert 	{
8019404b540aSrobert 	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
8020404b540aSrobert 	    {
8021404b540aSrobert 	      if (tree_int_cst_sgn (op1) < 0)
8022404b540aSrobert 		warning (0, "right shift count is negative");
8023404b540aSrobert 	      else
8024404b540aSrobert 		{
8025404b540aSrobert 		  if (!integer_zerop (op1))
8026404b540aSrobert 		    short_shift = 1;
8027404b540aSrobert 
8028404b540aSrobert 		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
8029404b540aSrobert 		    warning (0, "right shift count >= width of type");
8030404b540aSrobert 		}
8031404b540aSrobert 	    }
8032404b540aSrobert 
8033404b540aSrobert 	  /* Use the type of the value to be shifted.  */
8034404b540aSrobert 	  result_type = type0;
8035404b540aSrobert 	  /* Convert the shift-count to an integer, regardless of size
8036404b540aSrobert 	     of value being shifted.  */
8037404b540aSrobert 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
8038404b540aSrobert 	    op1 = convert (integer_type_node, op1);
8039404b540aSrobert 	  /* Avoid converting op1 to result_type later.  */
8040404b540aSrobert 	  converted = 1;
8041404b540aSrobert 	}
8042404b540aSrobert       break;
8043404b540aSrobert 
8044404b540aSrobert     case LSHIFT_EXPR:
8045404b540aSrobert       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
8046404b540aSrobert 	{
8047404b540aSrobert 	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
8048404b540aSrobert 	    {
8049404b540aSrobert 	      if (tree_int_cst_sgn (op1) < 0)
8050404b540aSrobert 		warning (0, "left shift count is negative");
8051404b540aSrobert 
8052404b540aSrobert 	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
8053404b540aSrobert 		warning (0, "left shift count >= width of type");
8054404b540aSrobert 	    }
8055404b540aSrobert 
8056404b540aSrobert 	  /* Use the type of the value to be shifted.  */
8057404b540aSrobert 	  result_type = type0;
8058404b540aSrobert 	  /* Convert the shift-count to an integer, regardless of size
8059404b540aSrobert 	     of value being shifted.  */
8060404b540aSrobert 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
8061404b540aSrobert 	    op1 = convert (integer_type_node, op1);
8062404b540aSrobert 	  /* Avoid converting op1 to result_type later.  */
8063404b540aSrobert 	  converted = 1;
8064404b540aSrobert 	}
8065404b540aSrobert       break;
8066404b540aSrobert 
8067404b540aSrobert     case EQ_EXPR:
8068404b540aSrobert     case NE_EXPR:
8069404b540aSrobert       if (code0 == REAL_TYPE || code1 == REAL_TYPE)
8070404b540aSrobert 	warning (OPT_Wfloat_equal,
8071404b540aSrobert 		 "comparing floating point with == or != is unsafe");
8072404b540aSrobert       /* Result of comparison is always int,
8073404b540aSrobert 	 but don't convert the args to int!  */
8074404b540aSrobert       build_type = integer_type_node;
8075404b540aSrobert       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
8076404b540aSrobert 	   || code0 == COMPLEX_TYPE)
8077404b540aSrobert 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
8078404b540aSrobert 	      || code1 == COMPLEX_TYPE))
8079404b540aSrobert 	short_compare = 1;
8080404b540aSrobert       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
8081404b540aSrobert 	{
8082404b540aSrobert 	  tree tt0 = TREE_TYPE (type0);
8083404b540aSrobert 	  tree tt1 = TREE_TYPE (type1);
8084404b540aSrobert 	  /* Anything compares with void *.  void * compares with anything.
8085404b540aSrobert 	     Otherwise, the targets must be compatible
8086404b540aSrobert 	     and both must be object or both incomplete.  */
8087404b540aSrobert 	  if (comp_target_types (type0, type1))
8088404b540aSrobert 	    result_type = common_pointer_type (type0, type1);
8089404b540aSrobert 	  else if (VOID_TYPE_P (tt0))
8090404b540aSrobert 	    {
8091404b540aSrobert 	      /* op0 != orig_op0 detects the case of something
8092404b540aSrobert 		 whose value is 0 but which isn't a valid null ptr const.  */
8093404b540aSrobert 	      if (pedantic && !null_pointer_constant_p (orig_op0)
8094404b540aSrobert 		  && TREE_CODE (tt1) == FUNCTION_TYPE)
8095404b540aSrobert 		pedwarn ("ISO C forbids comparison of %<void *%>"
8096404b540aSrobert 			 " with function pointer");
8097404b540aSrobert 	    }
8098404b540aSrobert 	  else if (VOID_TYPE_P (tt1))
8099404b540aSrobert 	    {
8100404b540aSrobert 	      if (pedantic && !null_pointer_constant_p (orig_op1)
8101404b540aSrobert 		  && TREE_CODE (tt0) == FUNCTION_TYPE)
8102404b540aSrobert 		pedwarn ("ISO C forbids comparison of %<void *%>"
8103404b540aSrobert 			 " with function pointer");
8104404b540aSrobert 	    }
8105404b540aSrobert 	  else
8106404b540aSrobert 	    /* Avoid warning about the volatile ObjC EH puts on decls.  */
8107404b540aSrobert 	    if (!objc_ok)
8108404b540aSrobert 	      pedwarn ("comparison of distinct pointer types lacks a cast");
8109404b540aSrobert 
8110404b540aSrobert 	  if (result_type == NULL_TREE)
8111404b540aSrobert 	    result_type = ptr_type_node;
8112404b540aSrobert 	}
8113404b540aSrobert       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
8114404b540aSrobert 	{
8115404b540aSrobert 	  if (TREE_CODE (op0) == ADDR_EXPR
8116404b540aSrobert 	      && DECL_P (TREE_OPERAND (op0, 0))
8117404b540aSrobert 	      && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL
8118404b540aSrobert 		  || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL
8119404b540aSrobert 		  || !DECL_WEAK (TREE_OPERAND (op0, 0))))
8120404b540aSrobert 	    warning (OPT_Waddress, "the address of %qD will never be NULL",
8121404b540aSrobert 		     TREE_OPERAND (op0, 0));
8122404b540aSrobert 	  result_type = type0;
8123404b540aSrobert 	}
8124404b540aSrobert       else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
8125404b540aSrobert 	{
8126404b540aSrobert 	  if (TREE_CODE (op1) == ADDR_EXPR
8127404b540aSrobert 	      && DECL_P (TREE_OPERAND (op1, 0))
8128404b540aSrobert 	      && (TREE_CODE (TREE_OPERAND (op1, 0)) == PARM_DECL
8129404b540aSrobert 		  || TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL
8130404b540aSrobert 		  || !DECL_WEAK (TREE_OPERAND (op1, 0))))
8131404b540aSrobert 	    warning (OPT_Waddress, "the address of %qD will never be NULL",
8132404b540aSrobert 		     TREE_OPERAND (op1, 0));
8133404b540aSrobert 	  result_type = type1;
8134404b540aSrobert 	}
8135404b540aSrobert       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
8136404b540aSrobert 	{
8137404b540aSrobert 	  result_type = type0;
8138404b540aSrobert 	  pedwarn ("comparison between pointer and integer");
8139404b540aSrobert 	}
8140404b540aSrobert       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
8141404b540aSrobert 	{
8142404b540aSrobert 	  result_type = type1;
8143404b540aSrobert 	  pedwarn ("comparison between pointer and integer");
8144404b540aSrobert 	}
8145404b540aSrobert       break;
8146404b540aSrobert 
8147404b540aSrobert     case LE_EXPR:
8148404b540aSrobert     case GE_EXPR:
8149404b540aSrobert     case LT_EXPR:
8150404b540aSrobert     case GT_EXPR:
8151404b540aSrobert       build_type = integer_type_node;
8152404b540aSrobert       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
8153404b540aSrobert 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
8154404b540aSrobert 	short_compare = 1;
8155404b540aSrobert       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
8156404b540aSrobert 	{
8157404b540aSrobert 	  if (comp_target_types (type0, type1))
8158404b540aSrobert 	    {
8159404b540aSrobert 	      result_type = common_pointer_type (type0, type1);
8160404b540aSrobert 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
8161404b540aSrobert 		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
8162404b540aSrobert 		pedwarn ("comparison of complete and incomplete pointers");
8163404b540aSrobert 	      else if (pedantic
8164404b540aSrobert 		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
8165404b540aSrobert 		pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
8166404b540aSrobert 	    }
8167404b540aSrobert 	  else
8168404b540aSrobert 	    {
8169404b540aSrobert 	      result_type = ptr_type_node;
8170404b540aSrobert 	      pedwarn ("comparison of distinct pointer types lacks a cast");
8171404b540aSrobert 	    }
8172404b540aSrobert 	}
8173404b540aSrobert       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
8174404b540aSrobert 	{
8175404b540aSrobert 	  result_type = type0;
8176404b540aSrobert 	  if (pedantic || extra_warnings)
8177404b540aSrobert 	    pedwarn ("ordered comparison of pointer with integer zero");
8178404b540aSrobert 	}
8179404b540aSrobert       else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
8180404b540aSrobert 	{
8181404b540aSrobert 	  result_type = type1;
8182404b540aSrobert 	  if (pedantic)
8183404b540aSrobert 	    pedwarn ("ordered comparison of pointer with integer zero");
8184404b540aSrobert 	}
8185404b540aSrobert       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
8186404b540aSrobert 	{
8187404b540aSrobert 	  result_type = type0;
8188404b540aSrobert 	  pedwarn ("comparison between pointer and integer");
8189404b540aSrobert 	}
8190404b540aSrobert       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
8191404b540aSrobert 	{
8192404b540aSrobert 	  result_type = type1;
8193404b540aSrobert 	  pedwarn ("comparison between pointer and integer");
8194404b540aSrobert 	}
8195404b540aSrobert       break;
8196404b540aSrobert 
8197404b540aSrobert     default:
8198404b540aSrobert       gcc_unreachable ();
8199404b540aSrobert     }
8200404b540aSrobert 
8201404b540aSrobert   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
8202404b540aSrobert     return error_mark_node;
8203404b540aSrobert 
8204404b540aSrobert   if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
8205404b540aSrobert       && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
8206404b540aSrobert 	  || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
8207404b540aSrobert 						    TREE_TYPE (type1))))
8208404b540aSrobert     {
8209404b540aSrobert       binary_op_error (code);
8210404b540aSrobert       return error_mark_node;
8211404b540aSrobert     }
8212404b540aSrobert 
8213404b540aSrobert   if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
8214404b540aSrobert        || code0 == VECTOR_TYPE)
8215404b540aSrobert       &&
8216404b540aSrobert       (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
8217404b540aSrobert        || code1 == VECTOR_TYPE))
8218404b540aSrobert     {
8219404b540aSrobert       int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
8220404b540aSrobert 
8221404b540aSrobert       if (shorten || common || short_compare)
8222404b540aSrobert 	result_type = c_common_type (type0, type1);
8223404b540aSrobert 
8224404b540aSrobert       /* For certain operations (which identify themselves by shorten != 0)
8225404b540aSrobert 	 if both args were extended from the same smaller type,
8226404b540aSrobert 	 do the arithmetic in that type and then extend.
8227404b540aSrobert 
8228404b540aSrobert 	 shorten !=0 and !=1 indicates a bitwise operation.
8229404b540aSrobert 	 For them, this optimization is safe only if
8230404b540aSrobert 	 both args are zero-extended or both are sign-extended.
8231404b540aSrobert 	 Otherwise, we might change the result.
8232404b540aSrobert 	 Eg, (short)-1 | (unsigned short)-1 is (int)-1
8233404b540aSrobert 	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
8234404b540aSrobert 
8235404b540aSrobert       if (shorten && none_complex)
8236404b540aSrobert 	{
8237404b540aSrobert 	  int unsigned0, unsigned1;
8238404b540aSrobert 	  tree arg0, arg1;
8239404b540aSrobert 	  int uns;
8240404b540aSrobert 	  tree type;
8241404b540aSrobert 
8242404b540aSrobert 	  /* Cast OP0 and OP1 to RESULT_TYPE.  Doing so prevents
8243404b540aSrobert 	     excessive narrowing when we call get_narrower below.  For
8244404b540aSrobert 	     example, suppose that OP0 is of unsigned int extended
8245404b540aSrobert 	     from signed char and that RESULT_TYPE is long long int.
8246404b540aSrobert 	     If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
8247404b540aSrobert 	     like
8248404b540aSrobert 
8249404b540aSrobert 	       (long long int) (unsigned int) signed_char
8250404b540aSrobert 
8251404b540aSrobert 	     which get_narrower would narrow down to
8252404b540aSrobert 
8253404b540aSrobert 	       (unsigned int) signed char
8254404b540aSrobert 
8255404b540aSrobert 	     If we do not cast OP0 first, get_narrower would return
8256404b540aSrobert 	     signed_char, which is inconsistent with the case of the
8257404b540aSrobert 	     explicit cast.  */
8258404b540aSrobert 	  op0 = convert (result_type, op0);
8259404b540aSrobert 	  op1 = convert (result_type, op1);
8260404b540aSrobert 
8261404b540aSrobert 	  arg0 = get_narrower (op0, &unsigned0);
8262404b540aSrobert 	  arg1 = get_narrower (op1, &unsigned1);
8263404b540aSrobert 
8264404b540aSrobert 	  /* UNS is 1 if the operation to be done is an unsigned one.  */
8265404b540aSrobert 	  uns = TYPE_UNSIGNED (result_type);
8266404b540aSrobert 
8267404b540aSrobert 	  final_type = result_type;
8268404b540aSrobert 
8269404b540aSrobert 	  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
8270404b540aSrobert 	     but it *requires* conversion to FINAL_TYPE.  */
8271404b540aSrobert 
8272404b540aSrobert 	  if ((TYPE_PRECISION (TREE_TYPE (op0))
8273404b540aSrobert 	       == TYPE_PRECISION (TREE_TYPE (arg0)))
8274404b540aSrobert 	      && TREE_TYPE (op0) != final_type)
8275404b540aSrobert 	    unsigned0 = TYPE_UNSIGNED (TREE_TYPE (op0));
8276404b540aSrobert 	  if ((TYPE_PRECISION (TREE_TYPE (op1))
8277404b540aSrobert 	       == TYPE_PRECISION (TREE_TYPE (arg1)))
8278404b540aSrobert 	      && TREE_TYPE (op1) != final_type)
8279404b540aSrobert 	    unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
8280404b540aSrobert 
8281404b540aSrobert 	  /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
8282404b540aSrobert 
8283404b540aSrobert 	  /* For bitwise operations, signedness of nominal type
8284404b540aSrobert 	     does not matter.  Consider only how operands were extended.  */
8285404b540aSrobert 	  if (shorten == -1)
8286404b540aSrobert 	    uns = unsigned0;
8287404b540aSrobert 
8288404b540aSrobert 	  /* Note that in all three cases below we refrain from optimizing
8289404b540aSrobert 	     an unsigned operation on sign-extended args.
8290404b540aSrobert 	     That would not be valid.  */
8291404b540aSrobert 
8292404b540aSrobert 	  /* Both args variable: if both extended in same way
8293404b540aSrobert 	     from same width, do it in that width.
8294404b540aSrobert 	     Do it unsigned if args were zero-extended.  */
8295404b540aSrobert 	  if ((TYPE_PRECISION (TREE_TYPE (arg0))
8296404b540aSrobert 	       < TYPE_PRECISION (result_type))
8297404b540aSrobert 	      && (TYPE_PRECISION (TREE_TYPE (arg1))
8298404b540aSrobert 		  == TYPE_PRECISION (TREE_TYPE (arg0)))
8299404b540aSrobert 	      && unsigned0 == unsigned1
8300404b540aSrobert 	      && (unsigned0 || !uns))
8301404b540aSrobert 	    result_type
8302404b540aSrobert 	      = c_common_signed_or_unsigned_type
8303404b540aSrobert 	      (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
8304404b540aSrobert 	  else if (TREE_CODE (arg0) == INTEGER_CST
8305404b540aSrobert 		   && (unsigned1 || !uns)
8306404b540aSrobert 		   && (TYPE_PRECISION (TREE_TYPE (arg1))
8307404b540aSrobert 		       < TYPE_PRECISION (result_type))
8308404b540aSrobert 		   && (type
8309404b540aSrobert 		       = c_common_signed_or_unsigned_type (unsigned1,
8310404b540aSrobert 							   TREE_TYPE (arg1)),
8311404b540aSrobert 		       int_fits_type_p (arg0, type)))
8312404b540aSrobert 	    result_type = type;
8313404b540aSrobert 	  else if (TREE_CODE (arg1) == INTEGER_CST
8314404b540aSrobert 		   && (unsigned0 || !uns)
8315404b540aSrobert 		   && (TYPE_PRECISION (TREE_TYPE (arg0))
8316404b540aSrobert 		       < TYPE_PRECISION (result_type))
8317404b540aSrobert 		   && (type
8318404b540aSrobert 		       = c_common_signed_or_unsigned_type (unsigned0,
8319404b540aSrobert 							   TREE_TYPE (arg0)),
8320404b540aSrobert 		       int_fits_type_p (arg1, type)))
8321404b540aSrobert 	    result_type = type;
8322404b540aSrobert 	}
8323404b540aSrobert 
8324404b540aSrobert       /* Shifts can be shortened if shifting right.  */
8325404b540aSrobert 
8326404b540aSrobert       if (short_shift)
8327404b540aSrobert 	{
8328404b540aSrobert 	  int unsigned_arg;
8329404b540aSrobert 	  tree arg0 = get_narrower (op0, &unsigned_arg);
8330404b540aSrobert 
8331404b540aSrobert 	  final_type = result_type;
8332404b540aSrobert 
8333404b540aSrobert 	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
8334404b540aSrobert 	    unsigned_arg = TYPE_UNSIGNED (TREE_TYPE (op0));
8335404b540aSrobert 
8336404b540aSrobert 	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
8337404b540aSrobert 	      /* We can shorten only if the shift count is less than the
8338404b540aSrobert 		 number of bits in the smaller type size.  */
8339404b540aSrobert 	      && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
8340404b540aSrobert 	      /* We cannot drop an unsigned shift after sign-extension.  */
8341404b540aSrobert 	      && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
8342404b540aSrobert 	    {
8343404b540aSrobert 	      /* Do an unsigned shift if the operand was zero-extended.  */
8344404b540aSrobert 	      result_type
8345404b540aSrobert 		= c_common_signed_or_unsigned_type (unsigned_arg,
8346404b540aSrobert 						    TREE_TYPE (arg0));
8347404b540aSrobert 	      /* Convert value-to-be-shifted to that type.  */
8348404b540aSrobert 	      if (TREE_TYPE (op0) != result_type)
8349404b540aSrobert 		op0 = convert (result_type, op0);
8350404b540aSrobert 	      converted = 1;
8351404b540aSrobert 	    }
8352404b540aSrobert 	}
8353404b540aSrobert 
8354404b540aSrobert       /* Comparison operations are shortened too but differently.
8355404b540aSrobert 	 They identify themselves by setting short_compare = 1.  */
8356404b540aSrobert 
8357404b540aSrobert       if (short_compare)
8358404b540aSrobert 	{
8359404b540aSrobert 	  /* Don't write &op0, etc., because that would prevent op0
8360404b540aSrobert 	     from being kept in a register.
8361404b540aSrobert 	     Instead, make copies of the our local variables and
8362404b540aSrobert 	     pass the copies by reference, then copy them back afterward.  */
8363404b540aSrobert 	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
8364404b540aSrobert 	  enum tree_code xresultcode = resultcode;
8365404b540aSrobert 	  tree val
8366404b540aSrobert 	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
8367404b540aSrobert 
8368404b540aSrobert 	  if (val != 0)
8369404b540aSrobert 	    return val;
8370404b540aSrobert 
8371404b540aSrobert 	  op0 = xop0, op1 = xop1;
8372404b540aSrobert 	  converted = 1;
8373404b540aSrobert 	  resultcode = xresultcode;
8374404b540aSrobert 
8375404b540aSrobert 	  if (warn_sign_compare && skip_evaluation == 0)
8376404b540aSrobert 	    {
8377404b540aSrobert 	      int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0));
8378404b540aSrobert 	      int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1));
8379404b540aSrobert 	      int unsignedp0, unsignedp1;
8380404b540aSrobert 	      tree primop0 = get_narrower (op0, &unsignedp0);
8381404b540aSrobert 	      tree primop1 = get_narrower (op1, &unsignedp1);
8382404b540aSrobert 
8383404b540aSrobert 	      xop0 = orig_op0;
8384404b540aSrobert 	      xop1 = orig_op1;
8385404b540aSrobert 	      STRIP_TYPE_NOPS (xop0);
8386404b540aSrobert 	      STRIP_TYPE_NOPS (xop1);
8387404b540aSrobert 
8388404b540aSrobert 	      /* Give warnings for comparisons between signed and unsigned
8389404b540aSrobert 		 quantities that may fail.
8390404b540aSrobert 
8391404b540aSrobert 		 Do the checking based on the original operand trees, so that
8392404b540aSrobert 		 casts will be considered, but default promotions won't be.
8393404b540aSrobert 
8394404b540aSrobert 		 Do not warn if the comparison is being done in a signed type,
8395404b540aSrobert 		 since the signed type will only be chosen if it can represent
8396404b540aSrobert 		 all the values of the unsigned type.  */
8397404b540aSrobert 	      if (!TYPE_UNSIGNED (result_type))
8398404b540aSrobert 		/* OK */;
8399404b540aSrobert 	      /* Do not warn if both operands are the same signedness.  */
8400404b540aSrobert 	      else if (op0_signed == op1_signed)
8401404b540aSrobert 		/* OK */;
8402404b540aSrobert 	      else
8403404b540aSrobert 		{
8404404b540aSrobert 		  tree sop, uop;
8405404b540aSrobert 		  bool ovf;
8406404b540aSrobert 
8407404b540aSrobert 		  if (op0_signed)
8408404b540aSrobert 		    sop = xop0, uop = xop1;
8409404b540aSrobert 		  else
8410404b540aSrobert 		    sop = xop1, uop = xop0;
8411404b540aSrobert 
8412404b540aSrobert 		  /* Do not warn if the signed quantity is an
8413404b540aSrobert 		     unsuffixed integer literal (or some static
8414404b540aSrobert 		     constant expression involving such literals or a
8415404b540aSrobert 		     conditional expression involving such literals)
8416404b540aSrobert 		     and it is non-negative.  */
8417404b540aSrobert 		  if (tree_expr_nonnegative_warnv_p (sop, &ovf))
8418404b540aSrobert 		    /* OK */;
8419404b540aSrobert 		  /* Do not warn if the comparison is an equality operation,
8420404b540aSrobert 		     the unsigned quantity is an integral constant, and it
8421404b540aSrobert 		     would fit in the result if the result were signed.  */
8422404b540aSrobert 		  else if (TREE_CODE (uop) == INTEGER_CST
8423404b540aSrobert 			   && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
8424404b540aSrobert 			   && int_fits_type_p
8425404b540aSrobert 			   (uop, c_common_signed_type (result_type)))
8426404b540aSrobert 		    /* OK */;
8427404b540aSrobert 		  /* Do not warn if the unsigned quantity is an enumeration
8428404b540aSrobert 		     constant and its maximum value would fit in the result
8429404b540aSrobert 		     if the result were signed.  */
8430404b540aSrobert 		  else if (TREE_CODE (uop) == INTEGER_CST
8431404b540aSrobert 			   && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
8432404b540aSrobert 			   && int_fits_type_p
8433404b540aSrobert 			   (TYPE_MAX_VALUE (TREE_TYPE (uop)),
8434404b540aSrobert 			    c_common_signed_type (result_type)))
8435404b540aSrobert 		    /* OK */;
8436404b540aSrobert 		  else
8437404b540aSrobert 		    warning (0, "comparison between signed and unsigned");
8438404b540aSrobert 		}
8439404b540aSrobert 
8440404b540aSrobert 	      /* Warn if two unsigned values are being compared in a size
8441404b540aSrobert 		 larger than their original size, and one (and only one) is the
8442404b540aSrobert 		 result of a `~' operator.  This comparison will always fail.
8443404b540aSrobert 
8444404b540aSrobert 		 Also warn if one operand is a constant, and the constant
8445404b540aSrobert 		 does not have all bits set that are set in the ~ operand
8446404b540aSrobert 		 when it is extended.  */
8447404b540aSrobert 
8448404b540aSrobert 	      if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
8449404b540aSrobert 		  != (TREE_CODE (primop1) == BIT_NOT_EXPR))
8450404b540aSrobert 		{
8451404b540aSrobert 		  if (TREE_CODE (primop0) == BIT_NOT_EXPR)
8452404b540aSrobert 		    primop0 = get_narrower (TREE_OPERAND (primop0, 0),
8453404b540aSrobert 					    &unsignedp0);
8454404b540aSrobert 		  else
8455404b540aSrobert 		    primop1 = get_narrower (TREE_OPERAND (primop1, 0),
8456404b540aSrobert 					    &unsignedp1);
8457404b540aSrobert 
8458404b540aSrobert 		  if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
8459404b540aSrobert 		    {
8460404b540aSrobert 		      tree primop;
8461404b540aSrobert 		      HOST_WIDE_INT constant, mask;
8462404b540aSrobert 		      int unsignedp, bits;
8463404b540aSrobert 
8464404b540aSrobert 		      if (host_integerp (primop0, 0))
8465404b540aSrobert 			{
8466404b540aSrobert 			  primop = primop1;
8467404b540aSrobert 			  unsignedp = unsignedp1;
8468404b540aSrobert 			  constant = tree_low_cst (primop0, 0);
8469404b540aSrobert 			}
8470404b540aSrobert 		      else
8471404b540aSrobert 			{
8472404b540aSrobert 			  primop = primop0;
8473404b540aSrobert 			  unsignedp = unsignedp0;
8474404b540aSrobert 			  constant = tree_low_cst (primop1, 0);
8475404b540aSrobert 			}
8476404b540aSrobert 
8477404b540aSrobert 		      bits = TYPE_PRECISION (TREE_TYPE (primop));
8478404b540aSrobert 		      if (bits < TYPE_PRECISION (result_type)
8479404b540aSrobert 			  && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
8480404b540aSrobert 			{
8481404b540aSrobert 			  mask = (~(HOST_WIDE_INT) 0) << bits;
8482404b540aSrobert 			  if ((mask & constant) != mask)
8483404b540aSrobert 			    warning (0, "comparison of promoted ~unsigned with constant");
8484404b540aSrobert 			}
8485404b540aSrobert 		    }
8486404b540aSrobert 		  else if (unsignedp0 && unsignedp1
8487404b540aSrobert 			   && (TYPE_PRECISION (TREE_TYPE (primop0))
8488404b540aSrobert 			       < TYPE_PRECISION (result_type))
8489404b540aSrobert 			   && (TYPE_PRECISION (TREE_TYPE (primop1))
8490404b540aSrobert 			       < TYPE_PRECISION (result_type)))
8491404b540aSrobert 		    warning (0, "comparison of promoted ~unsigned with unsigned");
8492404b540aSrobert 		}
8493404b540aSrobert 	    }
8494404b540aSrobert 	}
8495404b540aSrobert     }
8496404b540aSrobert 
8497404b540aSrobert   /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
8498404b540aSrobert      If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
8499404b540aSrobert      Then the expression will be built.
8500404b540aSrobert      It will be given type FINAL_TYPE if that is nonzero;
8501404b540aSrobert      otherwise, it will be given type RESULT_TYPE.  */
8502404b540aSrobert 
8503404b540aSrobert   if (!result_type)
8504404b540aSrobert     {
8505404b540aSrobert       binary_op_error (code);
8506404b540aSrobert       return error_mark_node;
8507404b540aSrobert     }
8508404b540aSrobert 
8509404b540aSrobert   if (!converted)
8510404b540aSrobert     {
8511404b540aSrobert       if (TREE_TYPE (op0) != result_type)
8512404b540aSrobert 	op0 = convert_and_check (result_type, op0);
8513404b540aSrobert       if (TREE_TYPE (op1) != result_type)
8514404b540aSrobert 	op1 = convert_and_check (result_type, op1);
8515404b540aSrobert 
8516404b540aSrobert       /* This can happen if one operand has a vector type, and the other
8517404b540aSrobert 	 has a different type.  */
8518404b540aSrobert       if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
8519404b540aSrobert 	return error_mark_node;
8520404b540aSrobert     }
8521404b540aSrobert 
8522404b540aSrobert   if (build_type == NULL_TREE)
8523404b540aSrobert     build_type = result_type;
8524404b540aSrobert 
8525404b540aSrobert   {
8526404b540aSrobert     /* Treat expressions in initializers specially as they can't trap.  */
8527404b540aSrobert     tree result = require_constant_value ? fold_build2_initializer (resultcode,
8528404b540aSrobert 								    build_type,
8529404b540aSrobert 								    op0, op1)
8530404b540aSrobert 					 : fold_build2 (resultcode, build_type,
8531404b540aSrobert 							op0, op1);
8532404b540aSrobert 
8533404b540aSrobert     if (final_type != 0)
8534404b540aSrobert       result = convert (final_type, result);
8535404b540aSrobert     return result;
8536404b540aSrobert   }
8537404b540aSrobert }
8538404b540aSrobert 
8539404b540aSrobert 
8540404b540aSrobert /* Convert EXPR to be a truth-value, validating its type for this
8541404b540aSrobert    purpose.  */
8542404b540aSrobert 
8543404b540aSrobert tree
c_objc_common_truthvalue_conversion(tree expr)8544404b540aSrobert c_objc_common_truthvalue_conversion (tree expr)
8545404b540aSrobert {
8546404b540aSrobert   switch (TREE_CODE (TREE_TYPE (expr)))
8547404b540aSrobert     {
8548404b540aSrobert     case ARRAY_TYPE:
8549404b540aSrobert       error ("used array that cannot be converted to pointer where scalar is required");
8550404b540aSrobert       return error_mark_node;
8551404b540aSrobert 
8552404b540aSrobert     case RECORD_TYPE:
8553404b540aSrobert       error ("used struct type value where scalar is required");
8554404b540aSrobert       return error_mark_node;
8555404b540aSrobert 
8556404b540aSrobert     case UNION_TYPE:
8557404b540aSrobert       error ("used union type value where scalar is required");
8558404b540aSrobert       return error_mark_node;
8559404b540aSrobert 
8560404b540aSrobert     case FUNCTION_TYPE:
8561404b540aSrobert       gcc_unreachable ();
8562404b540aSrobert 
8563404b540aSrobert     default:
8564404b540aSrobert       break;
8565404b540aSrobert     }
8566404b540aSrobert 
8567404b540aSrobert   /* ??? Should we also give an error for void and vectors rather than
8568404b540aSrobert      leaving those to give errors later?  */
8569404b540aSrobert   return c_common_truthvalue_conversion (expr);
8570404b540aSrobert }
8571404b540aSrobert 
8572404b540aSrobert 
8573404b540aSrobert /* Convert EXPR to a contained DECL, updating *TC, *TI and *SE as
8574404b540aSrobert    required.  */
8575404b540aSrobert 
8576404b540aSrobert tree
c_expr_to_decl(tree expr,bool * tc ATTRIBUTE_UNUSED,bool * ti ATTRIBUTE_UNUSED,bool * se)8577404b540aSrobert c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
8578404b540aSrobert 		bool *ti ATTRIBUTE_UNUSED, bool *se)
8579404b540aSrobert {
8580404b540aSrobert   if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
8581404b540aSrobert     {
8582404b540aSrobert       tree decl = COMPOUND_LITERAL_EXPR_DECL (expr);
8583404b540aSrobert       /* Executing a compound literal inside a function reinitializes
8584404b540aSrobert 	 it.  */
8585404b540aSrobert       if (!TREE_STATIC (decl))
8586404b540aSrobert 	*se = true;
8587404b540aSrobert       return decl;
8588404b540aSrobert     }
8589404b540aSrobert   else
8590404b540aSrobert     return expr;
8591404b540aSrobert }
8592404b540aSrobert 
8593404b540aSrobert /* Like c_begin_compound_stmt, except force the retention of the BLOCK.  */
8594404b540aSrobert 
8595404b540aSrobert tree
c_begin_omp_parallel(void)8596404b540aSrobert c_begin_omp_parallel (void)
8597404b540aSrobert {
8598404b540aSrobert   tree block;
8599404b540aSrobert 
8600404b540aSrobert   keep_next_level ();
8601404b540aSrobert   block = c_begin_compound_stmt (true);
8602404b540aSrobert 
8603404b540aSrobert   return block;
8604404b540aSrobert }
8605404b540aSrobert 
8606404b540aSrobert tree
c_finish_omp_parallel(tree clauses,tree block)8607404b540aSrobert c_finish_omp_parallel (tree clauses, tree block)
8608404b540aSrobert {
8609404b540aSrobert   tree stmt;
8610404b540aSrobert 
8611404b540aSrobert   block = c_end_compound_stmt (block, true);
8612404b540aSrobert 
8613404b540aSrobert   stmt = make_node (OMP_PARALLEL);
8614404b540aSrobert   TREE_TYPE (stmt) = void_type_node;
8615404b540aSrobert   OMP_PARALLEL_CLAUSES (stmt) = clauses;
8616404b540aSrobert   OMP_PARALLEL_BODY (stmt) = block;
8617404b540aSrobert 
8618404b540aSrobert   return add_stmt (stmt);
8619404b540aSrobert }
8620404b540aSrobert 
8621404b540aSrobert /* For all elements of CLAUSES, validate them vs OpenMP constraints.
8622404b540aSrobert    Remove any elements from the list that are invalid.  */
8623404b540aSrobert 
8624404b540aSrobert tree
c_finish_omp_clauses(tree clauses)8625404b540aSrobert c_finish_omp_clauses (tree clauses)
8626404b540aSrobert {
8627404b540aSrobert   bitmap_head generic_head, firstprivate_head, lastprivate_head;
8628404b540aSrobert   tree c, t, *pc = &clauses;
8629404b540aSrobert   const char *name;
8630404b540aSrobert 
8631404b540aSrobert   bitmap_obstack_initialize (NULL);
8632404b540aSrobert   bitmap_initialize (&generic_head, &bitmap_default_obstack);
8633404b540aSrobert   bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
8634404b540aSrobert   bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
8635404b540aSrobert 
8636404b540aSrobert   for (pc = &clauses, c = clauses; c ; c = *pc)
8637404b540aSrobert     {
8638404b540aSrobert       bool remove = false;
8639404b540aSrobert       bool need_complete = false;
8640404b540aSrobert       bool need_implicitly_determined = false;
8641404b540aSrobert 
8642404b540aSrobert       switch (OMP_CLAUSE_CODE (c))
8643404b540aSrobert 	{
8644404b540aSrobert 	case OMP_CLAUSE_SHARED:
8645404b540aSrobert 	  name = "shared";
8646404b540aSrobert 	  need_implicitly_determined = true;
8647404b540aSrobert 	  goto check_dup_generic;
8648404b540aSrobert 
8649404b540aSrobert 	case OMP_CLAUSE_PRIVATE:
8650404b540aSrobert 	  name = "private";
8651404b540aSrobert 	  need_complete = true;
8652404b540aSrobert 	  need_implicitly_determined = true;
8653404b540aSrobert 	  goto check_dup_generic;
8654404b540aSrobert 
8655404b540aSrobert 	case OMP_CLAUSE_REDUCTION:
8656404b540aSrobert 	  name = "reduction";
8657404b540aSrobert 	  need_implicitly_determined = true;
8658404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8659404b540aSrobert 	  if (AGGREGATE_TYPE_P (TREE_TYPE (t))
8660404b540aSrobert 	      || POINTER_TYPE_P (TREE_TYPE (t)))
8661404b540aSrobert 	    {
8662404b540aSrobert 	      error ("%qE has invalid type for %<reduction%>", t);
8663404b540aSrobert 	      remove = true;
8664404b540aSrobert 	    }
8665404b540aSrobert 	  else if (FLOAT_TYPE_P (TREE_TYPE (t)))
8666404b540aSrobert 	    {
8667404b540aSrobert 	      enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
8668404b540aSrobert 	      const char *r_name = NULL;
8669404b540aSrobert 
8670404b540aSrobert 	      switch (r_code)
8671404b540aSrobert 		{
8672404b540aSrobert 		case PLUS_EXPR:
8673404b540aSrobert 		case MULT_EXPR:
8674404b540aSrobert 		case MINUS_EXPR:
8675404b540aSrobert 		  break;
8676404b540aSrobert 		case BIT_AND_EXPR:
8677404b540aSrobert 		  r_name = "&";
8678404b540aSrobert 		  break;
8679404b540aSrobert 		case BIT_XOR_EXPR:
8680404b540aSrobert 		  r_name = "^";
8681404b540aSrobert 		  break;
8682404b540aSrobert 		case BIT_IOR_EXPR:
8683404b540aSrobert 		  r_name = "|";
8684404b540aSrobert 		  break;
8685404b540aSrobert 		case TRUTH_ANDIF_EXPR:
8686404b540aSrobert 		  r_name = "&&";
8687404b540aSrobert 		  break;
8688404b540aSrobert 		case TRUTH_ORIF_EXPR:
8689404b540aSrobert 		  r_name = "||";
8690404b540aSrobert 		  break;
8691404b540aSrobert 		default:
8692404b540aSrobert 		  gcc_unreachable ();
8693404b540aSrobert 		}
8694404b540aSrobert 	      if (r_name)
8695404b540aSrobert 		{
8696404b540aSrobert 		  error ("%qE has invalid type for %<reduction(%s)%>",
8697404b540aSrobert 			 t, r_name);
8698404b540aSrobert 		  remove = true;
8699404b540aSrobert 		}
8700404b540aSrobert 	    }
8701404b540aSrobert 	  goto check_dup_generic;
8702404b540aSrobert 
8703404b540aSrobert 	case OMP_CLAUSE_COPYPRIVATE:
8704404b540aSrobert 	  name = "copyprivate";
8705404b540aSrobert 	  goto check_dup_generic;
8706404b540aSrobert 
8707404b540aSrobert 	case OMP_CLAUSE_COPYIN:
8708404b540aSrobert 	  name = "copyin";
8709404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8710404b540aSrobert 	  if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t))
8711404b540aSrobert 	    {
8712404b540aSrobert 	      error ("%qE must be %<threadprivate%> for %<copyin%>", t);
8713404b540aSrobert 	      remove = true;
8714404b540aSrobert 	    }
8715404b540aSrobert 	  goto check_dup_generic;
8716404b540aSrobert 
8717404b540aSrobert 	check_dup_generic:
8718404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8719404b540aSrobert 	  if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
8720404b540aSrobert 	    {
8721404b540aSrobert 	      error ("%qE is not a variable in clause %qs", t, name);
8722404b540aSrobert 	      remove = true;
8723404b540aSrobert 	    }
8724404b540aSrobert 	  else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8725404b540aSrobert 		   || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8726404b540aSrobert 		   || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8727404b540aSrobert 	    {
8728404b540aSrobert 	      error ("%qE appears more than once in data clauses", t);
8729404b540aSrobert 	      remove = true;
8730404b540aSrobert 	    }
8731404b540aSrobert 	  else
8732404b540aSrobert 	    bitmap_set_bit (&generic_head, DECL_UID (t));
8733404b540aSrobert 	  break;
8734404b540aSrobert 
8735404b540aSrobert 	case OMP_CLAUSE_FIRSTPRIVATE:
8736404b540aSrobert 	  name = "firstprivate";
8737404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8738404b540aSrobert 	  need_complete = true;
8739404b540aSrobert 	  need_implicitly_determined = true;
8740404b540aSrobert 	  if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
8741404b540aSrobert 	    {
8742404b540aSrobert 	      error ("%qE is not a variable in clause %<firstprivate%>", t);
8743404b540aSrobert 	      remove = true;
8744404b540aSrobert 	    }
8745404b540aSrobert 	  else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8746404b540aSrobert 		   || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
8747404b540aSrobert 	    {
8748404b540aSrobert 	      error ("%qE appears more than once in data clauses", t);
8749404b540aSrobert 	      remove = true;
8750404b540aSrobert 	    }
8751404b540aSrobert 	  else
8752404b540aSrobert 	    bitmap_set_bit (&firstprivate_head, DECL_UID (t));
8753404b540aSrobert 	  break;
8754404b540aSrobert 
8755404b540aSrobert 	case OMP_CLAUSE_LASTPRIVATE:
8756404b540aSrobert 	  name = "lastprivate";
8757404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8758404b540aSrobert 	  need_complete = true;
8759404b540aSrobert 	  need_implicitly_determined = true;
8760404b540aSrobert 	  if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
8761404b540aSrobert 	    {
8762404b540aSrobert 	      error ("%qE is not a variable in clause %<lastprivate%>", t);
8763404b540aSrobert 	      remove = true;
8764404b540aSrobert 	    }
8765404b540aSrobert 	  else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8766404b540aSrobert 		   || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8767404b540aSrobert 	    {
8768404b540aSrobert 	      error ("%qE appears more than once in data clauses", t);
8769404b540aSrobert 	      remove = true;
8770404b540aSrobert 	    }
8771404b540aSrobert 	  else
8772404b540aSrobert 	    bitmap_set_bit (&lastprivate_head, DECL_UID (t));
8773404b540aSrobert 	  break;
8774404b540aSrobert 
8775404b540aSrobert 	case OMP_CLAUSE_IF:
8776404b540aSrobert 	case OMP_CLAUSE_NUM_THREADS:
8777404b540aSrobert 	case OMP_CLAUSE_SCHEDULE:
8778404b540aSrobert 	case OMP_CLAUSE_NOWAIT:
8779404b540aSrobert 	case OMP_CLAUSE_ORDERED:
8780404b540aSrobert 	case OMP_CLAUSE_DEFAULT:
8781404b540aSrobert 	  pc = &OMP_CLAUSE_CHAIN (c);
8782404b540aSrobert 	  continue;
8783404b540aSrobert 
8784404b540aSrobert 	default:
8785404b540aSrobert 	  gcc_unreachable ();
8786404b540aSrobert 	}
8787404b540aSrobert 
8788404b540aSrobert       if (!remove)
8789404b540aSrobert 	{
8790404b540aSrobert 	  t = OMP_CLAUSE_DECL (c);
8791404b540aSrobert 
8792404b540aSrobert 	  if (need_complete)
8793404b540aSrobert 	    {
8794404b540aSrobert 	      t = require_complete_type (t);
8795404b540aSrobert 	      if (t == error_mark_node)
8796404b540aSrobert 		remove = true;
8797404b540aSrobert 	    }
8798404b540aSrobert 
8799404b540aSrobert 	  if (need_implicitly_determined)
8800404b540aSrobert 	    {
8801404b540aSrobert 	      const char *share_name = NULL;
8802404b540aSrobert 
8803404b540aSrobert 	      if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
8804404b540aSrobert 		share_name = "threadprivate";
8805404b540aSrobert 	      else switch (c_omp_predetermined_sharing (t))
8806404b540aSrobert 		{
8807404b540aSrobert 		case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
8808404b540aSrobert 		  break;
8809404b540aSrobert 		case OMP_CLAUSE_DEFAULT_SHARED:
8810404b540aSrobert 		  share_name = "shared";
8811404b540aSrobert 		  break;
8812404b540aSrobert 		case OMP_CLAUSE_DEFAULT_PRIVATE:
8813404b540aSrobert 		  share_name = "private";
8814404b540aSrobert 		  break;
8815404b540aSrobert 		default:
8816404b540aSrobert 		  gcc_unreachable ();
8817404b540aSrobert 		}
8818404b540aSrobert 	      if (share_name)
8819404b540aSrobert 		{
8820404b540aSrobert 		  error ("%qE is predetermined %qs for %qs",
8821404b540aSrobert 			 t, share_name, name);
8822404b540aSrobert 		  remove = true;
8823404b540aSrobert 		}
8824404b540aSrobert 	    }
8825404b540aSrobert 	}
8826404b540aSrobert 
8827404b540aSrobert       if (remove)
8828404b540aSrobert 	*pc = OMP_CLAUSE_CHAIN (c);
8829404b540aSrobert       else
8830404b540aSrobert 	pc = &OMP_CLAUSE_CHAIN (c);
8831404b540aSrobert     }
8832404b540aSrobert 
8833404b540aSrobert   bitmap_obstack_release (NULL);
8834404b540aSrobert   return clauses;
8835404b540aSrobert }
8836