c-typeck.c revision 96263
118334Speter/* Build expressions with type checking for C compiler.
290075Sobrien   Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
390075Sobrien   1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien02111-1307, USA.  */
2118334Speter
2218334Speter
2318334Speter/* This file is part of the C front end.
2418334Speter   It contains routines to build C expressions given their operands,
2518334Speter   including computing the types of the result, C-specific error checks,
2618334Speter   and some optimization.
2718334Speter
2818334Speter   There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
2918334Speter   and to process initializations in declarations (since they work
3018334Speter   like a strange sort of assignment).  */
3118334Speter
3218334Speter#include "config.h"
3350397Sobrien#include "system.h"
3490075Sobrien#include "rtl.h"
3518334Speter#include "tree.h"
3618334Speter#include "c-tree.h"
3790075Sobrien#include "tm_p.h"
3818334Speter#include "flags.h"
3918334Speter#include "output.h"
4050397Sobrien#include "expr.h"
4150397Sobrien#include "toplev.h"
4252284Sobrien#include "intl.h"
4390075Sobrien#include "ggc.h"
4490075Sobrien#include "target.h"
4518334Speter
4618334Speter/* Nonzero if we've already printed a "missing braces around initializer"
4718334Speter   message within this initializer.  */
4818334Speterstatic int missing_braces_mentioned;
4918334Speter
5090075Sobrien/* 1 if we explained undeclared var errors.  */
5190075Sobrienstatic int undeclared_variable_notice;
5290075Sobrien
5390075Sobrienstatic tree qualify_type		PARAMS ((tree, tree));
5490075Sobrienstatic int comp_target_types		PARAMS ((tree, tree));
5590075Sobrienstatic int function_types_compatible_p	PARAMS ((tree, tree));
5690075Sobrienstatic int type_lists_compatible_p	PARAMS ((tree, tree));
5790075Sobrienstatic tree decl_constant_value_for_broken_optimization PARAMS ((tree));
5890075Sobrienstatic tree default_function_array_conversion	PARAMS ((tree));
5990075Sobrienstatic tree lookup_field		PARAMS ((tree, tree));
6090075Sobrienstatic tree convert_arguments		PARAMS ((tree, tree, tree, tree));
6190075Sobrienstatic tree pointer_diff		PARAMS ((tree, tree));
6290075Sobrienstatic tree unary_complex_lvalue	PARAMS ((enum tree_code, tree, int));
6390075Sobrienstatic void pedantic_lvalue_warning	PARAMS ((enum tree_code));
6490075Sobrienstatic tree internal_build_compound_expr PARAMS ((tree, int));
6590075Sobrienstatic tree convert_for_assignment	PARAMS ((tree, tree, const char *,
6690075Sobrien						 tree, tree, int));
6790075Sobrienstatic void warn_for_assignment		PARAMS ((const char *, const char *,
6890075Sobrien						 tree, int));
6990075Sobrienstatic tree valid_compound_expr_initializer PARAMS ((tree, tree));
7090075Sobrienstatic void push_string			PARAMS ((const char *));
7190075Sobrienstatic void push_member_name		PARAMS ((tree));
7290075Sobrienstatic void push_array_bounds		PARAMS ((int));
7390075Sobrienstatic int spelling_length		PARAMS ((void));
7490075Sobrienstatic char *print_spelling		PARAMS ((char *));
7590075Sobrienstatic void warning_init		PARAMS ((const char *));
7690075Sobrienstatic tree digest_init			PARAMS ((tree, tree, int, int));
7790075Sobrienstatic void output_init_element		PARAMS ((tree, tree, tree, int));
7890075Sobrienstatic void output_pending_init_elements PARAMS ((int));
7990075Sobrienstatic int set_designator		PARAMS ((int));
8090075Sobrienstatic void push_range_stack		PARAMS ((tree));
8190075Sobrienstatic void add_pending_init		PARAMS ((tree, tree));
8290075Sobrienstatic void set_nonincremental_init	PARAMS ((void));
8390075Sobrienstatic void set_nonincremental_init_from_string	PARAMS ((tree));
8490075Sobrienstatic tree find_init_member		PARAMS ((tree));
8518334Speter
8618334Speter/* Do `exp = require_complete_type (exp);' to make sure exp
8718334Speter   does not have an incomplete type.  (That includes void types.)  */
8818334Speter
8918334Spetertree
9018334Speterrequire_complete_type (value)
9118334Speter     tree value;
9218334Speter{
9318334Speter  tree type = TREE_TYPE (value);
9418334Speter
9590075Sobrien  if (value == error_mark_node || type == error_mark_node)
9652284Sobrien    return error_mark_node;
9752284Sobrien
9818334Speter  /* First, detect a valid value with a complete type.  */
9990075Sobrien  if (COMPLETE_TYPE_P (type))
10018334Speter    return value;
10118334Speter
10218334Speter  incomplete_type_error (value, type);
10318334Speter  return error_mark_node;
10418334Speter}
10518334Speter
10618334Speter/* Print an error message for invalid use of an incomplete type.
10718334Speter   VALUE is the expression that was used (or 0 if that isn't known)
10818334Speter   and TYPE is the type that was invalid.  */
10918334Speter
11018334Spetervoid
11118334Speterincomplete_type_error (value, type)
11218334Speter     tree value;
11318334Speter     tree type;
11418334Speter{
11552284Sobrien  const char *type_code_string;
11618334Speter
11718334Speter  /* Avoid duplicate error message.  */
11818334Speter  if (TREE_CODE (type) == ERROR_MARK)
11918334Speter    return;
12018334Speter
12118334Speter  if (value != 0 && (TREE_CODE (value) == VAR_DECL
12218334Speter		     || TREE_CODE (value) == PARM_DECL))
12318334Speter    error ("`%s' has an incomplete type",
12418334Speter	   IDENTIFIER_POINTER (DECL_NAME (value)));
12518334Speter  else
12618334Speter    {
12718334Speter    retry:
12818334Speter      /* We must print an error message.  Be clever about what it says.  */
12918334Speter
13018334Speter      switch (TREE_CODE (type))
13118334Speter	{
13218334Speter	case RECORD_TYPE:
13352284Sobrien	  type_code_string = "struct";
13418334Speter	  break;
13518334Speter
13618334Speter	case UNION_TYPE:
13752284Sobrien	  type_code_string = "union";
13818334Speter	  break;
13918334Speter
14018334Speter	case ENUMERAL_TYPE:
14152284Sobrien	  type_code_string = "enum";
14218334Speter	  break;
14318334Speter
14418334Speter	case VOID_TYPE:
14518334Speter	  error ("invalid use of void expression");
14618334Speter	  return;
14718334Speter
14818334Speter	case ARRAY_TYPE:
14918334Speter	  if (TYPE_DOMAIN (type))
15018334Speter	    {
15196263Sobrien	      if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
15296263Sobrien		{
15396263Sobrien		  error ("invalid use of flexible array member");
15496263Sobrien		  return;
15596263Sobrien		}
15618334Speter	      type = TREE_TYPE (type);
15718334Speter	      goto retry;
15818334Speter	    }
15918334Speter	  error ("invalid use of array with unspecified bounds");
16018334Speter	  return;
16118334Speter
16218334Speter	default:
16318334Speter	  abort ();
16418334Speter	}
16518334Speter
16618334Speter      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
16752284Sobrien	error ("invalid use of undefined type `%s %s'",
16852284Sobrien	       type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
16918334Speter      else
17018334Speter	/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
17118334Speter	error ("invalid use of incomplete typedef `%s'",
17218334Speter	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
17318334Speter    }
17418334Speter}
17518334Speter
17618334Speter/* Return a variant of TYPE which has all the type qualifiers of LIKE
17718334Speter   as well as those of TYPE.  */
17818334Speter
17918334Speterstatic tree
18018334Speterqualify_type (type, like)
18118334Speter     tree type, like;
18218334Speter{
18352750Sobrien  return c_build_qualified_type (type,
18452750Sobrien				 TYPE_QUALS (type) | TYPE_QUALS (like));
18518334Speter}
18618334Speter
18718334Speter/* Return the common type of two types.
18818334Speter   We assume that comptypes has already been done and returned 1;
18918334Speter   if that isn't so, this may crash.  In particular, we assume that qualifiers
19018334Speter   match.
19118334Speter
19218334Speter   This is the type for the result of most arithmetic operations
19318334Speter   if the operands have the given two types.  */
19418334Speter
19518334Spetertree
19618334Spetercommon_type (t1, t2)
19718334Speter     tree t1, t2;
19818334Speter{
19990075Sobrien  enum tree_code code1;
20090075Sobrien  enum tree_code code2;
20118334Speter  tree attributes;
20218334Speter
20318334Speter  /* Save time if the two types are the same.  */
20418334Speter
20518334Speter  if (t1 == t2) return t1;
20618334Speter
20718334Speter  /* If one type is nonsense, use the other.  */
20818334Speter  if (t1 == error_mark_node)
20918334Speter    return t2;
21018334Speter  if (t2 == error_mark_node)
21118334Speter    return t1;
21218334Speter
21350397Sobrien  /* Merge the attributes.  */
21490075Sobrien  attributes = (*targetm.merge_type_attributes) (t1, t2);
21518334Speter
21618334Speter  /* Treat an enum type as the unsigned integer type of the same width.  */
21718334Speter
21818334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
21918334Speter    t1 = type_for_size (TYPE_PRECISION (t1), 1);
22018334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
22118334Speter    t2 = type_for_size (TYPE_PRECISION (t2), 1);
22218334Speter
22318334Speter  code1 = TREE_CODE (t1);
22418334Speter  code2 = TREE_CODE (t2);
22518334Speter
22618334Speter  /* If one type is complex, form the common type of the non-complex
22718334Speter     components, then make that complex.  Use T1 or T2 if it is the
22818334Speter     required type.  */
22918334Speter  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
23018334Speter    {
23118334Speter      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
23218334Speter      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
23318334Speter      tree subtype = common_type (subtype1, subtype2);
23418334Speter
23518334Speter      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
23618334Speter	return build_type_attribute_variant (t1, attributes);
23718334Speter      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
23818334Speter	return build_type_attribute_variant (t2, attributes);
23918334Speter      else
24018334Speter	return build_type_attribute_variant (build_complex_type (subtype),
24118334Speter					     attributes);
24218334Speter    }
24318334Speter
24418334Speter  switch (code1)
24518334Speter    {
24618334Speter    case INTEGER_TYPE:
24718334Speter    case REAL_TYPE:
24818334Speter      /* If only one is real, use it as the result.  */
24918334Speter
25018334Speter      if (code1 == REAL_TYPE && code2 != REAL_TYPE)
25118334Speter	return build_type_attribute_variant (t1, attributes);
25218334Speter
25318334Speter      if (code2 == REAL_TYPE && code1 != REAL_TYPE)
25418334Speter	return build_type_attribute_variant (t2, attributes);
25518334Speter
25618334Speter      /* Both real or both integers; use the one with greater precision.  */
25718334Speter
25818334Speter      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
25918334Speter	return build_type_attribute_variant (t1, attributes);
26018334Speter      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
26118334Speter	return build_type_attribute_variant (t2, attributes);
26218334Speter
26318334Speter      /* Same precision.  Prefer longs to ints even when same size.  */
26418334Speter
26518334Speter      if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
26618334Speter	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
26718334Speter	return build_type_attribute_variant (long_unsigned_type_node,
26818334Speter					     attributes);
26918334Speter
27018334Speter      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
27118334Speter	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
27218334Speter	{
27318334Speter	  /* But preserve unsignedness from the other type,
27418334Speter	     since long cannot hold all the values of an unsigned int.  */
27518334Speter	  if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
27618334Speter	     t1 = long_unsigned_type_node;
27718334Speter	  else
27818334Speter	     t1 = long_integer_type_node;
27918334Speter	  return build_type_attribute_variant (t1, attributes);
28018334Speter	}
28118334Speter
28250397Sobrien      /* Likewise, prefer long double to double even if same size.  */
28350397Sobrien      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
28450397Sobrien	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
28550397Sobrien	return build_type_attribute_variant (long_double_type_node,
28650397Sobrien					     attributes);
28750397Sobrien
28818334Speter      /* Otherwise prefer the unsigned one.  */
28918334Speter
29018334Speter      if (TREE_UNSIGNED (t1))
29118334Speter	return build_type_attribute_variant (t1, attributes);
29218334Speter      else
29318334Speter	return build_type_attribute_variant (t2, attributes);
29418334Speter
29518334Speter    case POINTER_TYPE:
29618334Speter      /* For two pointers, do this recursively on the target type,
29718334Speter	 and combine the qualifiers of the two types' targets.  */
29818334Speter      /* This code was turned off; I don't know why.
29918334Speter	 But ANSI C specifies doing this with the qualifiers.
30018334Speter	 So I turned it on again.  */
30118334Speter      {
30252284Sobrien	tree pointed_to_1 = TREE_TYPE (t1);
30352284Sobrien	tree pointed_to_2 = TREE_TYPE (t2);
30452284Sobrien	tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
30552284Sobrien				   TYPE_MAIN_VARIANT (pointed_to_2));
30652284Sobrien	t1 = build_pointer_type (c_build_qualified_type
30752284Sobrien				 (target,
30852284Sobrien				  TYPE_QUALS (pointed_to_1) |
30952284Sobrien				  TYPE_QUALS (pointed_to_2)));
31018334Speter	return build_type_attribute_variant (t1, attributes);
31118334Speter      }
31218334Speter#if 0
31318334Speter      t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
31418334Speter      return build_type_attribute_variant (t1, attributes);
31518334Speter#endif
31618334Speter
31718334Speter    case ARRAY_TYPE:
31818334Speter      {
31918334Speter	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
32018334Speter	/* Save space: see if the result is identical to one of the args.  */
32118334Speter	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
32218334Speter	  return build_type_attribute_variant (t1, attributes);
32318334Speter	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
32418334Speter	  return build_type_attribute_variant (t2, attributes);
32518334Speter	/* Merge the element types, and have a size if either arg has one.  */
32618334Speter	t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
32718334Speter	return build_type_attribute_variant (t1, attributes);
32818334Speter      }
32918334Speter
33018334Speter    case FUNCTION_TYPE:
33118334Speter      /* Function types: prefer the one that specified arg types.
33218334Speter	 If both do, merge the arg types.  Also merge the return types.  */
33318334Speter      {
33418334Speter	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
33518334Speter	tree p1 = TYPE_ARG_TYPES (t1);
33618334Speter	tree p2 = TYPE_ARG_TYPES (t2);
33718334Speter	int len;
33818334Speter	tree newargs, n;
33918334Speter	int i;
34018334Speter
34118334Speter	/* Save space: see if the result is identical to one of the args.  */
34218334Speter	if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2))
34318334Speter	  return build_type_attribute_variant (t1, attributes);
34418334Speter	if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1))
34518334Speter	  return build_type_attribute_variant (t2, attributes);
34618334Speter
34718334Speter	/* Simple way if one arg fails to specify argument types.  */
34818334Speter	if (TYPE_ARG_TYPES (t1) == 0)
34918334Speter	 {
35018334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2));
35118334Speter	   return build_type_attribute_variant (t1, attributes);
35218334Speter	 }
35318334Speter	if (TYPE_ARG_TYPES (t2) == 0)
35418334Speter	 {
35518334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1));
35618334Speter	   return build_type_attribute_variant (t1, attributes);
35718334Speter	 }
35818334Speter
35918334Speter	/* If both args specify argument types, we must merge the two
36018334Speter	   lists, argument by argument.  */
36118334Speter
36290075Sobrien	pushlevel (0);
36390075Sobrien	declare_parm_level (1);
36490075Sobrien
36518334Speter	len = list_length (p1);
36618334Speter	newargs = 0;
36718334Speter
36818334Speter	for (i = 0; i < len; i++)
36918334Speter	  newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
37018334Speter
37118334Speter	n = newargs;
37218334Speter
37318334Speter	for (; p1;
37418334Speter	     p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
37518334Speter	  {
37618334Speter	    /* A null type means arg type is not specified.
37718334Speter	       Take whatever the other function type has.  */
37818334Speter	    if (TREE_VALUE (p1) == 0)
37918334Speter	      {
38018334Speter		TREE_VALUE (n) = TREE_VALUE (p2);
38118334Speter		goto parm_done;
38218334Speter	      }
38318334Speter	    if (TREE_VALUE (p2) == 0)
38418334Speter	      {
38518334Speter		TREE_VALUE (n) = TREE_VALUE (p1);
38618334Speter		goto parm_done;
38718334Speter	      }
38818334Speter
38918334Speter	    /* Given  wait (union {union wait *u; int *i} *)
39018334Speter	       and  wait (union wait *),
39118334Speter	       prefer  union wait *  as type of parm.  */
39218334Speter	    if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
39318334Speter		&& TREE_VALUE (p1) != TREE_VALUE (p2))
39418334Speter	      {
39518334Speter		tree memb;
39618334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p1));
39718334Speter		     memb; memb = TREE_CHAIN (memb))
39818334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
39918334Speter		    {
40018334Speter		      TREE_VALUE (n) = TREE_VALUE (p2);
40118334Speter		      if (pedantic)
40290075Sobrien			pedwarn ("function types not truly compatible in ISO C");
40318334Speter		      goto parm_done;
40418334Speter		    }
40518334Speter	      }
40618334Speter	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
40718334Speter		&& TREE_VALUE (p2) != TREE_VALUE (p1))
40818334Speter	      {
40918334Speter		tree memb;
41018334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p2));
41118334Speter		     memb; memb = TREE_CHAIN (memb))
41218334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
41318334Speter		    {
41418334Speter		      TREE_VALUE (n) = TREE_VALUE (p1);
41518334Speter		      if (pedantic)
41690075Sobrien			pedwarn ("function types not truly compatible in ISO C");
41718334Speter		      goto parm_done;
41818334Speter		    }
41918334Speter	      }
42018334Speter	    TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
42118334Speter	  parm_done: ;
42218334Speter	  }
42318334Speter
42490075Sobrien	poplevel (0, 0, 0);
42590075Sobrien
42618334Speter	t1 = build_function_type (valtype, newargs);
42750397Sobrien	/* ... falls through ...  */
42818334Speter      }
42918334Speter
43018334Speter    default:
43118334Speter      return build_type_attribute_variant (t1, attributes);
43218334Speter    }
43318334Speter
43418334Speter}
43518334Speter
43618334Speter/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
43718334Speter   or various other operations.  Return 2 if they are compatible
43818334Speter   but a warning may be needed if you use them together.  */
43918334Speter
44018334Speterint
44118334Spetercomptypes (type1, type2)
44218334Speter     tree type1, type2;
44318334Speter{
44490075Sobrien  tree t1 = type1;
44590075Sobrien  tree t2 = type2;
44618334Speter  int attrval, val;
44718334Speter
44818334Speter  /* Suppress errors caused by previously reported errors.  */
44918334Speter
45050397Sobrien  if (t1 == t2 || !t1 || !t2
45150397Sobrien      || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
45218334Speter    return 1;
45318334Speter
45490075Sobrien  /* If either type is the internal version of sizetype, return the
45590075Sobrien     language version.  */
45690075Sobrien  if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
45790075Sobrien      && TYPE_DOMAIN (t1) != 0)
45890075Sobrien    t1 = TYPE_DOMAIN (t1);
45990075Sobrien
46090075Sobrien  if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
46190075Sobrien      && TYPE_DOMAIN (t2) != 0)
46290075Sobrien    t2 = TYPE_DOMAIN (t2);
46390075Sobrien
46418334Speter  /* Treat an enum type as the integer type of the same width and
46518334Speter     signedness.  */
46618334Speter
46718334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
46818334Speter    t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
46918334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
47018334Speter    t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
47118334Speter
47218334Speter  if (t1 == t2)
47318334Speter    return 1;
47418334Speter
47518334Speter  /* Different classes of types can't be compatible.  */
47618334Speter
47718334Speter  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
47818334Speter
47918334Speter  /* Qualifiers must match.  */
48018334Speter
48152284Sobrien  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
48218334Speter    return 0;
48318334Speter
48418334Speter  /* Allow for two different type nodes which have essentially the same
48518334Speter     definition.  Note that we already checked for equality of the type
48650397Sobrien     qualifiers (just above).  */
48718334Speter
48818334Speter  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
48918334Speter    return 1;
49018334Speter
49118334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
49290075Sobrien  if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
49318334Speter     return 0;
49418334Speter
49518334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
49618334Speter  val = 0;
49718334Speter
49818334Speter  switch (TREE_CODE (t1))
49918334Speter    {
50018334Speter    case POINTER_TYPE:
50118334Speter      val = (TREE_TYPE (t1) == TREE_TYPE (t2)
50218334Speter	      ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
50318334Speter      break;
50418334Speter
50518334Speter    case FUNCTION_TYPE:
50618334Speter      val = function_types_compatible_p (t1, t2);
50718334Speter      break;
50818334Speter
50918334Speter    case ARRAY_TYPE:
51018334Speter      {
51118334Speter	tree d1 = TYPE_DOMAIN (t1);
51218334Speter	tree d2 = TYPE_DOMAIN (t2);
51390075Sobrien	bool d1_variable, d2_variable;
51490075Sobrien	bool d1_zero, d2_zero;
51518334Speter	val = 1;
51618334Speter
51718334Speter	/* Target types must match incl. qualifiers.  */
51818334Speter	if (TREE_TYPE (t1) != TREE_TYPE (t2)
51918334Speter	    && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
52018334Speter	  return 0;
52118334Speter
52218334Speter	/* Sizes must match unless one is missing or variable.  */
52390075Sobrien	if (d1 == 0 || d2 == 0 || d1 == d2)
52418334Speter	  break;
52518334Speter
52690075Sobrien	d1_zero = ! TYPE_MAX_VALUE (d1);
52790075Sobrien	d2_zero = ! TYPE_MAX_VALUE (d2);
52890075Sobrien
52990075Sobrien	d1_variable = (! d1_zero
53090075Sobrien		       && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
53190075Sobrien			   || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
53290075Sobrien	d2_variable = (! d2_zero
53390075Sobrien		       && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
53490075Sobrien			   || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
53590075Sobrien
53690075Sobrien	if (d1_variable || d2_variable)
53790075Sobrien	  break;
53890075Sobrien	if (d1_zero && d2_zero)
53990075Sobrien	  break;
54090075Sobrien	if (d1_zero || d2_zero
54190075Sobrien	    || ! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
54290075Sobrien	    || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
54390075Sobrien	  val = 0;
54490075Sobrien
54518334Speter        break;
54618334Speter      }
54718334Speter
54818334Speter    case RECORD_TYPE:
54918334Speter      if (maybe_objc_comptypes (t1, t2, 0) == 1)
55018334Speter	val = 1;
55118334Speter      break;
55250397Sobrien
55350397Sobrien    default:
55450397Sobrien      break;
55518334Speter    }
55618334Speter  return attrval == 2 && val == 1 ? 2 : val;
55718334Speter}
55818334Speter
55918334Speter/* Return 1 if TTL and TTR are pointers to types that are equivalent,
56018334Speter   ignoring their qualifiers.  */
56118334Speter
56218334Speterstatic int
56318334Spetercomp_target_types (ttl, ttr)
56418334Speter     tree ttl, ttr;
56518334Speter{
56618334Speter  int val;
56718334Speter
56818334Speter  /* Give maybe_objc_comptypes a crack at letting these types through.  */
56950397Sobrien  if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0)
57018334Speter    return val;
57118334Speter
57218334Speter  val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
57318334Speter		   TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
57418334Speter
57518334Speter  if (val == 2 && pedantic)
57618334Speter    pedwarn ("types are not quite compatible");
57718334Speter  return val;
57818334Speter}
57918334Speter
58018334Speter/* Subroutines of `comptypes'.  */
58118334Speter
58218334Speter/* Return 1 if two function types F1 and F2 are compatible.
58318334Speter   If either type specifies no argument types,
58418334Speter   the other must specify a fixed number of self-promoting arg types.
58518334Speter   Otherwise, if one type specifies only the number of arguments,
58618334Speter   the other must specify that number of self-promoting arg types.
58718334Speter   Otherwise, the argument types must match.  */
58818334Speter
58918334Speterstatic int
59018334Speterfunction_types_compatible_p (f1, f2)
59118334Speter     tree f1, f2;
59218334Speter{
59318334Speter  tree args1, args2;
59418334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
59518334Speter  int val = 1;
59618334Speter  int val1;
59718334Speter
59818334Speter  if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
59918334Speter	|| (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
60018334Speter    return 0;
60118334Speter
60218334Speter  args1 = TYPE_ARG_TYPES (f1);
60318334Speter  args2 = TYPE_ARG_TYPES (f2);
60418334Speter
60518334Speter  /* An unspecified parmlist matches any specified parmlist
60618334Speter     whose argument types don't need default promotions.  */
60718334Speter
60818334Speter  if (args1 == 0)
60918334Speter    {
61018334Speter      if (!self_promoting_args_p (args2))
61118334Speter	return 0;
61218334Speter      /* If one of these types comes from a non-prototype fn definition,
61318334Speter	 compare that with the other type's arglist.
61418334Speter	 If they don't match, ask for a warning (but no error).  */
61518334Speter      if (TYPE_ACTUAL_ARG_TYPES (f1)
61618334Speter	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
61718334Speter	val = 2;
61818334Speter      return val;
61918334Speter    }
62018334Speter  if (args2 == 0)
62118334Speter    {
62218334Speter      if (!self_promoting_args_p (args1))
62318334Speter	return 0;
62418334Speter      if (TYPE_ACTUAL_ARG_TYPES (f2)
62518334Speter	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
62618334Speter	val = 2;
62718334Speter      return val;
62818334Speter    }
62918334Speter
63018334Speter  /* Both types have argument lists: compare them and propagate results.  */
63118334Speter  val1 = type_lists_compatible_p (args1, args2);
63218334Speter  return val1 != 1 ? val1 : val;
63318334Speter}
63418334Speter
63518334Speter/* Check two lists of types for compatibility,
63618334Speter   returning 0 for incompatible, 1 for compatible,
63718334Speter   or 2 for compatible with warning.  */
63818334Speter
63918334Speterstatic int
64018334Spetertype_lists_compatible_p (args1, args2)
64118334Speter     tree args1, args2;
64218334Speter{
64318334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
64418334Speter  int val = 1;
64518334Speter  int newval = 0;
64618334Speter
64718334Speter  while (1)
64818334Speter    {
64918334Speter      if (args1 == 0 && args2 == 0)
65018334Speter	return val;
65118334Speter      /* If one list is shorter than the other,
65218334Speter	 they fail to match.  */
65318334Speter      if (args1 == 0 || args2 == 0)
65418334Speter	return 0;
65518334Speter      /* A null pointer instead of a type
65618334Speter	 means there is supposed to be an argument
65718334Speter	 but nothing is specified about what type it has.
65818334Speter	 So match anything that self-promotes.  */
65918334Speter      if (TREE_VALUE (args1) == 0)
66018334Speter	{
66190075Sobrien	  if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE)
66218334Speter	    return 0;
66318334Speter	}
66418334Speter      else if (TREE_VALUE (args2) == 0)
66518334Speter	{
66690075Sobrien	  if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
66718334Speter	    return 0;
66818334Speter	}
66990075Sobrien      else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
67090075Sobrien				      TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
67118334Speter	{
67218334Speter	  /* Allow  wait (union {union wait *u; int *i} *)
67318334Speter	     and  wait (union wait *)  to be compatible.  */
67418334Speter	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
67518334Speter	      && (TYPE_NAME (TREE_VALUE (args1)) == 0
67618334Speter		  || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
67718334Speter	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
67818334Speter	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
67918334Speter				     TYPE_SIZE (TREE_VALUE (args2))))
68018334Speter	    {
68118334Speter	      tree memb;
68218334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));
68318334Speter		   memb; memb = TREE_CHAIN (memb))
68418334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
68518334Speter		  break;
68618334Speter	      if (memb == 0)
68718334Speter		return 0;
68818334Speter	    }
68918334Speter	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
69018334Speter		   && (TYPE_NAME (TREE_VALUE (args2)) == 0
69118334Speter		       || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
69218334Speter		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
69318334Speter		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
69418334Speter					  TYPE_SIZE (TREE_VALUE (args1))))
69518334Speter	    {
69618334Speter	      tree memb;
69718334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));
69818334Speter		   memb; memb = TREE_CHAIN (memb))
69918334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
70018334Speter		  break;
70118334Speter	      if (memb == 0)
70218334Speter		return 0;
70318334Speter	    }
70418334Speter	  else
70518334Speter	    return 0;
70618334Speter	}
70718334Speter
70818334Speter      /* comptypes said ok, but record if it said to warn.  */
70918334Speter      if (newval > val)
71018334Speter	val = newval;
71118334Speter
71218334Speter      args1 = TREE_CHAIN (args1);
71318334Speter      args2 = TREE_CHAIN (args2);
71418334Speter    }
71518334Speter}
71618334Speter
71718334Speter/* Compute the value of the `sizeof' operator.  */
71818334Speter
71918334Spetertree
72018334Speterc_sizeof (type)
72118334Speter     tree type;
72218334Speter{
72318334Speter  enum tree_code code = TREE_CODE (type);
72490075Sobrien  tree size;
72518334Speter
72618334Speter  if (code == FUNCTION_TYPE)
72718334Speter    {
72818334Speter      if (pedantic || warn_pointer_arith)
72918334Speter	pedwarn ("sizeof applied to a function type");
73090075Sobrien      size = size_one_node;
73118334Speter    }
73290075Sobrien  else if (code == VOID_TYPE)
73318334Speter    {
73418334Speter      if (pedantic || warn_pointer_arith)
73518334Speter	pedwarn ("sizeof applied to a void type");
73690075Sobrien      size = size_one_node;
73718334Speter    }
73890075Sobrien  else if (code == ERROR_MARK)
73990075Sobrien    size = size_one_node;
74090075Sobrien  else if (!COMPLETE_TYPE_P (type))
74118334Speter    {
74218334Speter      error ("sizeof applied to an incomplete type");
74390075Sobrien      size = size_zero_node;
74418334Speter    }
74590075Sobrien  else
74690075Sobrien    /* Convert in case a char is more than one unit.  */
74790075Sobrien    size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
74890075Sobrien		       size_int (TYPE_PRECISION (char_type_node)
74990075Sobrien			         / BITS_PER_UNIT));
75018334Speter
75190075Sobrien  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
75290075Sobrien     TYPE_IS_SIZETYPE means that certain things (like overflow) will
75390075Sobrien     never happen.  However, this node should really have type
75490075Sobrien     `size_t', which is just a typedef for an ordinary integer type.  */
75590075Sobrien  return fold (build1 (NOP_EXPR, c_size_type_node, size));
75618334Speter}
75718334Speter
75818334Spetertree
75918334Speterc_sizeof_nowarn (type)
76018334Speter     tree type;
76118334Speter{
76218334Speter  enum tree_code code = TREE_CODE (type);
76390075Sobrien  tree size;
76418334Speter
76590075Sobrien  if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
76690075Sobrien    size = size_one_node;
76790075Sobrien  else if (!COMPLETE_TYPE_P (type))
76890075Sobrien    size = size_zero_node;
76990075Sobrien  else
77090075Sobrien    /* Convert in case a char is more than one unit.  */
77190075Sobrien    size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
77290075Sobrien		       size_int (TYPE_PRECISION (char_type_node)
77390075Sobrien			         / BITS_PER_UNIT));
77418334Speter
77590075Sobrien  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
77690075Sobrien     TYPE_IS_SIZETYPE means that certain things (like overflow) will
77790075Sobrien     never happen.  However, this node should really have type
77890075Sobrien     `size_t', which is just a typedef for an ordinary integer type.  */
77990075Sobrien  return fold (build1 (NOP_EXPR, c_size_type_node, size));
78018334Speter}
78118334Speter
78218334Speter/* Compute the size to increment a pointer by.  */
78318334Speter
78418334Spetertree
78518334Speterc_size_in_bytes (type)
78618334Speter     tree type;
78718334Speter{
78818334Speter  enum tree_code code = TREE_CODE (type);
78918334Speter
79090075Sobrien  if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
79190075Sobrien    return size_one_node;
79290075Sobrien
79390075Sobrien  if (!COMPLETE_OR_VOID_TYPE_P (type))
79418334Speter    {
79518334Speter      error ("arithmetic on pointer to an incomplete type");
79690075Sobrien      return size_one_node;
79718334Speter    }
79818334Speter
79918334Speter  /* Convert in case a char is more than one unit.  */
80090075Sobrien  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
80190075Sobrien		     size_int (TYPE_PRECISION (char_type_node)
80290075Sobrien			       / BITS_PER_UNIT));
80318334Speter}
80418334Speter
80590075Sobrien/* Return either DECL or its known constant value (if it has one).  */
80618334Speter
80718334Spetertree
80818334Speterdecl_constant_value (decl)
80918334Speter     tree decl;
81018334Speter{
81150397Sobrien  if (/* Don't change a variable array bound or initial value to a constant
81218334Speter	 in a place where a variable is invalid.  */
81350397Sobrien      current_function_decl != 0
81418334Speter      && ! TREE_THIS_VOLATILE (decl)
81590075Sobrien      && TREE_READONLY (decl)
81618334Speter      && DECL_INITIAL (decl) != 0
81718334Speter      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
81818334Speter      /* This is invalid if initial value is not constant.
81918334Speter	 If it has either a function call, a memory reference,
82018334Speter	 or a variable, then re-evaluating it could give different results.  */
82118334Speter      && TREE_CONSTANT (DECL_INITIAL (decl))
82218334Speter      /* Check for cases where this is sub-optimal, even though valid.  */
82390075Sobrien      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
82418334Speter    return DECL_INITIAL (decl);
82518334Speter  return decl;
82618334Speter}
82718334Speter
82890075Sobrien/* Return either DECL or its known constant value (if it has one), but
82990075Sobrien   return DECL if pedantic or DECL has mode BLKmode.  This is for
83090075Sobrien   bug-compatibility with the old behavior of decl_constant_value
83190075Sobrien   (before GCC 3.0); every use of this function is a bug and it should
83290075Sobrien   be removed before GCC 3.1.  It is not appropriate to use pedantic
83390075Sobrien   in a way that affects optimization, and BLKmode is probably not the
83490075Sobrien   right test for avoiding misoptimizations either.  */
83518334Speter
83690075Sobrienstatic tree
83790075Sobriendecl_constant_value_for_broken_optimization (decl)
83890075Sobrien     tree decl;
83918334Speter{
84090075Sobrien  if (pedantic || DECL_MODE (decl) == BLKmode)
84190075Sobrien    return decl;
84290075Sobrien  else
84390075Sobrien    return decl_constant_value (decl);
84490075Sobrien}
84518334Speter
84618334Speter
84790075Sobrien/* Perform the default conversion of arrays and functions to pointers.
84890075Sobrien   Return the result of converting EXP.  For any other expression, just
84990075Sobrien   return EXP.  */
85018334Speter
85190075Sobrienstatic tree
85290075Sobriendefault_function_array_conversion (exp)
85390075Sobrien     tree exp;
85490075Sobrien{
85590075Sobrien  tree orig_exp;
85690075Sobrien  tree type = TREE_TYPE (exp);
85790075Sobrien  enum tree_code code = TREE_CODE (type);
85890075Sobrien  int not_lvalue = 0;
85990075Sobrien
86018334Speter  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
86190075Sobrien     an lvalue.
86290075Sobrien
86390075Sobrien     Do not use STRIP_NOPS here!  It will remove conversions from pointer
86418334Speter     to integer and cause infinite recursion.  */
86590075Sobrien  orig_exp = exp;
86618334Speter  while (TREE_CODE (exp) == NON_LVALUE_EXPR
86718334Speter	 || (TREE_CODE (exp) == NOP_EXPR
86818334Speter	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
86918334Speter    {
87090075Sobrien      if (TREE_CODE (exp) == NON_LVALUE_EXPR)
87190075Sobrien	not_lvalue = 1;
87290075Sobrien      exp = TREE_OPERAND (exp, 0);
87318334Speter    }
87418334Speter
87590075Sobrien  /* Preserve the original expression code.  */
87690075Sobrien  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp))))
87790075Sobrien    C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp));
87850397Sobrien
87918334Speter  if (code == FUNCTION_TYPE)
88018334Speter    {
88118334Speter      return build_unary_op (ADDR_EXPR, exp, 0);
88218334Speter    }
88318334Speter  if (code == ARRAY_TYPE)
88418334Speter    {
88590075Sobrien      tree adr;
88618334Speter      tree restype = TREE_TYPE (type);
88718334Speter      tree ptrtype;
88818334Speter      int constp = 0;
88918334Speter      int volatilep = 0;
89090075Sobrien      int lvalue_array_p;
89118334Speter
89290075Sobrien      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' || DECL_P (exp))
89318334Speter	{
89418334Speter	  constp = TREE_READONLY (exp);
89518334Speter	  volatilep = TREE_THIS_VOLATILE (exp);
89618334Speter	}
89718334Speter
89852284Sobrien      if (TYPE_QUALS (type) || constp || volatilep)
89952284Sobrien	restype
90052284Sobrien	  = c_build_qualified_type (restype,
90152284Sobrien				    TYPE_QUALS (type)
90252284Sobrien				    | (constp * TYPE_QUAL_CONST)
90352284Sobrien				    | (volatilep * TYPE_QUAL_VOLATILE));
90418334Speter
90518334Speter      if (TREE_CODE (exp) == INDIRECT_REF)
90618334Speter	return convert (TYPE_POINTER_TO (restype),
90718334Speter			TREE_OPERAND (exp, 0));
90818334Speter
90918334Speter      if (TREE_CODE (exp) == COMPOUND_EXPR)
91018334Speter	{
91118334Speter	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));
91218334Speter	  return build (COMPOUND_EXPR, TREE_TYPE (op1),
91318334Speter			TREE_OPERAND (exp, 0), op1);
91418334Speter	}
91518334Speter
91690075Sobrien      lvalue_array_p = !not_lvalue && lvalue_p (exp);
91790075Sobrien      if (!flag_isoc99 && !lvalue_array_p)
91818334Speter	{
91990075Sobrien	  /* Before C99, non-lvalue arrays do not decay to pointers.
92090075Sobrien	     Normally, using such an array would be invalid; but it can
92190075Sobrien	     be used correctly inside sizeof or as a statement expression.
92290075Sobrien	     Thus, do not give an error here; an error will result later.  */
92390075Sobrien	  return exp;
92418334Speter	}
92518334Speter
92618334Speter      ptrtype = build_pointer_type (restype);
92718334Speter
92818334Speter      if (TREE_CODE (exp) == VAR_DECL)
92918334Speter	{
93018334Speter	  /* ??? This is not really quite correct
93118334Speter	     in that the type of the operand of ADDR_EXPR
93218334Speter	     is not the target type of the type of the ADDR_EXPR itself.
93318334Speter	     Question is, can this lossage be avoided?  */
93418334Speter	  adr = build1 (ADDR_EXPR, ptrtype, exp);
93518334Speter	  if (mark_addressable (exp) == 0)
93618334Speter	    return error_mark_node;
93718334Speter	  TREE_CONSTANT (adr) = staticp (exp);
93818334Speter	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
93918334Speter	  return adr;
94018334Speter	}
94118334Speter      /* This way is better for a COMPONENT_REF since it can
94218334Speter	 simplify the offset for a component.  */
94318334Speter      adr = build_unary_op (ADDR_EXPR, exp, 1);
94418334Speter      return convert (ptrtype, adr);
94518334Speter    }
94618334Speter  return exp;
94718334Speter}
94890075Sobrien
94990075Sobrien/* Perform default promotions for C data used in expressions.
95090075Sobrien   Arrays and functions are converted to pointers;
95190075Sobrien   enumeral types or short or char, to int.
95290075Sobrien   In addition, manifest constants symbols are replaced by their values.  */
95390075Sobrien
95490075Sobrientree
95590075Sobriendefault_conversion (exp)
95690075Sobrien     tree exp;
95790075Sobrien{
95890075Sobrien  tree orig_exp;
95990075Sobrien  tree type = TREE_TYPE (exp);
96090075Sobrien  enum tree_code code = TREE_CODE (type);
96190075Sobrien
96290075Sobrien  if (code == FUNCTION_TYPE || code == ARRAY_TYPE)
96390075Sobrien    return default_function_array_conversion (exp);
96490075Sobrien
96590075Sobrien  /* Constants can be used directly unless they're not loadable.  */
96690075Sobrien  if (TREE_CODE (exp) == CONST_DECL)
96790075Sobrien    exp = DECL_INITIAL (exp);
96890075Sobrien
96990075Sobrien  /* Replace a nonvolatile const static variable with its value unless
97090075Sobrien     it is an array, in which case we must be sure that taking the
97190075Sobrien     address of the array produces consistent results.  */
97290075Sobrien  else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
97390075Sobrien    {
97490075Sobrien      exp = decl_constant_value_for_broken_optimization (exp);
97590075Sobrien      type = TREE_TYPE (exp);
97690075Sobrien    }
97790075Sobrien
97890075Sobrien  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
97990075Sobrien     an lvalue.
98090075Sobrien
98190075Sobrien     Do not use STRIP_NOPS here!  It will remove conversions from pointer
98290075Sobrien     to integer and cause infinite recursion.  */
98390075Sobrien  orig_exp = exp;
98490075Sobrien  while (TREE_CODE (exp) == NON_LVALUE_EXPR
98590075Sobrien	 || (TREE_CODE (exp) == NOP_EXPR
98690075Sobrien	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
98790075Sobrien    exp = TREE_OPERAND (exp, 0);
98890075Sobrien
98990075Sobrien  /* Preserve the original expression code.  */
99090075Sobrien  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp))))
99190075Sobrien    C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp));
99290075Sobrien
99390075Sobrien  /* Normally convert enums to int,
99490075Sobrien     but convert wide enums to something wider.  */
99590075Sobrien  if (code == ENUMERAL_TYPE)
99690075Sobrien    {
99790075Sobrien      type = type_for_size (MAX (TYPE_PRECISION (type),
99890075Sobrien				 TYPE_PRECISION (integer_type_node)),
99990075Sobrien			    ((flag_traditional
100090075Sobrien			      || (TYPE_PRECISION (type)
100190075Sobrien				  >= TYPE_PRECISION (integer_type_node)))
100290075Sobrien			     && TREE_UNSIGNED (type)));
100390075Sobrien
100490075Sobrien      return convert (type, exp);
100590075Sobrien    }
100690075Sobrien
100790075Sobrien  if (TREE_CODE (exp) == COMPONENT_REF
100890075Sobrien      && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
100990075Sobrien      /* If it's thinner than an int, promote it like a
101090075Sobrien	 c_promoting_integer_type_p, otherwise leave it alone.  */
101190075Sobrien      && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
101290075Sobrien			       TYPE_PRECISION (integer_type_node)))
101390075Sobrien    return convert (flag_traditional && TREE_UNSIGNED (type)
101490075Sobrien		    ? unsigned_type_node : integer_type_node,
101590075Sobrien		    exp);
101690075Sobrien
101790075Sobrien  if (c_promoting_integer_type_p (type))
101890075Sobrien    {
101990075Sobrien      /* Traditionally, unsignedness is preserved in default promotions.
102090075Sobrien         Also preserve unsignedness if not really getting any wider.  */
102190075Sobrien      if (TREE_UNSIGNED (type)
102290075Sobrien	  && (flag_traditional
102390075Sobrien	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
102490075Sobrien	return convert (unsigned_type_node, exp);
102590075Sobrien
102690075Sobrien      return convert (integer_type_node, exp);
102790075Sobrien    }
102890075Sobrien
102990075Sobrien  if (flag_traditional && !flag_allow_single_precision
103090075Sobrien      && TYPE_MAIN_VARIANT (type) == float_type_node)
103190075Sobrien    return convert (double_type_node, exp);
103290075Sobrien
103390075Sobrien  if (code == VOID_TYPE)
103490075Sobrien    {
103590075Sobrien      error ("void value not ignored as it ought to be");
103690075Sobrien      return error_mark_node;
103790075Sobrien    }
103890075Sobrien  return exp;
103990075Sobrien}
104018334Speter
104190075Sobrien/* Look up COMPONENT in a structure or union DECL.
104218334Speter
104390075Sobrien   If the component name is not found, returns NULL_TREE.  Otherwise,
104490075Sobrien   the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL
104590075Sobrien   stepping down the chain to the component, which is in the last
104690075Sobrien   TREE_VALUE of the list.  Normally the list is of length one, but if
104790075Sobrien   the component is embedded within (nested) anonymous structures or
104890075Sobrien   unions, the list steps down the chain to the component.  */
104918334Speter
105018334Speterstatic tree
105190075Sobrienlookup_field (decl, component)
105290075Sobrien     tree decl, component;
105318334Speter{
105490075Sobrien  tree type = TREE_TYPE (decl);
105518334Speter  tree field;
105618334Speter
105718334Speter  /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
105818334Speter     to the field elements.  Use a binary search on this array to quickly
105918334Speter     find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC
106018334Speter     will always be set for structures which have many elements.  */
106118334Speter
106218334Speter  if (TYPE_LANG_SPECIFIC (type))
106318334Speter    {
106418334Speter      int bot, top, half;
106518334Speter      tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];
106618334Speter
106718334Speter      field = TYPE_FIELDS (type);
106818334Speter      bot = 0;
106918334Speter      top = TYPE_LANG_SPECIFIC (type)->len;
107018334Speter      while (top - bot > 1)
107118334Speter	{
107218334Speter	  half = (top - bot + 1) >> 1;
107318334Speter	  field = field_array[bot+half];
107418334Speter
107518334Speter	  if (DECL_NAME (field) == NULL_TREE)
107618334Speter	    {
107718334Speter	      /* Step through all anon unions in linear fashion.  */
107818334Speter	      while (DECL_NAME (field_array[bot]) == NULL_TREE)
107918334Speter		{
108018334Speter		  field = field_array[bot++];
108150397Sobrien		  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
108250397Sobrien		      || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
108390075Sobrien		    {
108490075Sobrien		      tree anon = lookup_field (field, component);
108550397Sobrien
108690075Sobrien		      if (anon)
108790075Sobrien			return tree_cons (NULL_TREE, field, anon);
108890075Sobrien		    }
108918334Speter		}
109018334Speter
109118334Speter	      /* Entire record is only anon unions.  */
109218334Speter	      if (bot > top)
109318334Speter		return NULL_TREE;
109418334Speter
109518334Speter	      /* Restart the binary search, with new lower bound.  */
109618334Speter	      continue;
109718334Speter	    }
109818334Speter
109918334Speter	  if (DECL_NAME (field) == component)
110018334Speter	    break;
110118334Speter	  if (DECL_NAME (field) < component)
110218334Speter	    bot += half;
110318334Speter	  else
110418334Speter	    top = bot + half;
110518334Speter	}
110618334Speter
110718334Speter      if (DECL_NAME (field_array[bot]) == component)
110818334Speter	field = field_array[bot];
110918334Speter      else if (DECL_NAME (field) != component)
111090075Sobrien	return NULL_TREE;
111118334Speter    }
111218334Speter  else
111318334Speter    {
111418334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
111518334Speter	{
111690075Sobrien	  if (DECL_NAME (field) == NULL_TREE
111790075Sobrien	      && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
111890075Sobrien		  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
111918334Speter	    {
112090075Sobrien	      tree anon = lookup_field (field, component);
112150397Sobrien
112290075Sobrien	      if (anon)
112390075Sobrien		return tree_cons (NULL_TREE, field, anon);
112418334Speter	    }
112518334Speter
112618334Speter	  if (DECL_NAME (field) == component)
112718334Speter	    break;
112818334Speter	}
112990075Sobrien
113090075Sobrien      if (field == NULL_TREE)
113190075Sobrien	return NULL_TREE;
113218334Speter    }
113318334Speter
113490075Sobrien  return tree_cons (NULL_TREE, field, NULL_TREE);
113518334Speter}
113618334Speter
113718334Speter/* Make an expression to refer to the COMPONENT field of
113818334Speter   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
113918334Speter
114018334Spetertree
114118334Speterbuild_component_ref (datum, component)
114218334Speter     tree datum, component;
114318334Speter{
114490075Sobrien  tree type = TREE_TYPE (datum);
114590075Sobrien  enum tree_code code = TREE_CODE (type);
114690075Sobrien  tree field = NULL;
114790075Sobrien  tree ref;
114818334Speter
114990075Sobrien  /* If DATUM is a COMPOUND_EXPR, move our reference inside it.
115090075Sobrien     If pedantic ensure that the arguments are not lvalues; otherwise,
115190075Sobrien     if the component is an array, it would wrongly decay to a pointer in
115290075Sobrien     C89 mode.
115390075Sobrien     We cannot do this with a COND_EXPR, because in a conditional expression
115490075Sobrien     the default promotions are applied to both sides, and this would yield
115590075Sobrien     the wrong type of the result; for example, if the components have
115690075Sobrien     type "char".  */
115718334Speter  switch (TREE_CODE (datum))
115818334Speter    {
115918334Speter    case COMPOUND_EXPR:
116018334Speter      {
116118334Speter	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
116218334Speter	return build (COMPOUND_EXPR, TREE_TYPE (value),
116390075Sobrien		      TREE_OPERAND (datum, 0), pedantic_non_lvalue (value));
116418334Speter      }
116550397Sobrien    default:
116650397Sobrien      break;
116718334Speter    }
116818334Speter
116918334Speter  /* See if there is a field or component with name COMPONENT.  */
117018334Speter
117118334Speter  if (code == RECORD_TYPE || code == UNION_TYPE)
117218334Speter    {
117390075Sobrien      if (!COMPLETE_TYPE_P (type))
117418334Speter	{
117518334Speter	  incomplete_type_error (NULL_TREE, type);
117618334Speter	  return error_mark_node;
117718334Speter	}
117818334Speter
117990075Sobrien      field = lookup_field (datum, component);
118018334Speter
118118334Speter      if (!field)
118218334Speter	{
118390075Sobrien	  error ("%s has no member named `%s'",
118490075Sobrien		 code == RECORD_TYPE ? "structure" : "union",
118518334Speter		 IDENTIFIER_POINTER (component));
118618334Speter	  return error_mark_node;
118718334Speter	}
118818334Speter
118990075Sobrien      /* Chain the COMPONENT_REFs if necessary down to the FIELD.
119090075Sobrien	 This might be better solved in future the way the C++ front
119190075Sobrien	 end does it - by giving the anonymous entities each a
119290075Sobrien	 separate name and type, and then have build_component_ref
119390075Sobrien	 recursively call itself.  We can't do that here.  */
119490075Sobrien      for (; field; field = TREE_CHAIN (field))
119518334Speter	{
119690075Sobrien	  tree subdatum = TREE_VALUE (field);
119790075Sobrien
119890075Sobrien	  if (TREE_TYPE (subdatum) == error_mark_node)
119990075Sobrien	    return error_mark_node;
120090075Sobrien
120190075Sobrien	  ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum);
120290075Sobrien	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
120318334Speter	    TREE_READONLY (ref) = 1;
120490075Sobrien	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum))
120518334Speter	    TREE_THIS_VOLATILE (ref) = 1;
120690075Sobrien
120790075Sobrien	  if (TREE_DEPRECATED (subdatum))
120890075Sobrien	    warn_deprecated_use (subdatum);
120990075Sobrien
121018334Speter	  datum = ref;
121118334Speter	}
121218334Speter
121318334Speter      return ref;
121418334Speter    }
121518334Speter  else if (code != ERROR_MARK)
121618334Speter    error ("request for member `%s' in something not a structure or union",
121718334Speter	    IDENTIFIER_POINTER (component));
121818334Speter
121918334Speter  return error_mark_node;
122018334Speter}
122118334Speter
122218334Speter/* Given an expression PTR for a pointer, return an expression
122318334Speter   for the value pointed to.
122418334Speter   ERRORSTRING is the name of the operator to appear in error messages.  */
122518334Speter
122618334Spetertree
122718334Speterbuild_indirect_ref (ptr, errorstring)
122818334Speter     tree ptr;
122952284Sobrien     const char *errorstring;
123018334Speter{
123190075Sobrien  tree pointer = default_conversion (ptr);
123290075Sobrien  tree type = TREE_TYPE (pointer);
123318334Speter
123418334Speter  if (TREE_CODE (type) == POINTER_TYPE)
123518334Speter    {
123618334Speter      if (TREE_CODE (pointer) == ADDR_EXPR
123718334Speter	  && !flag_volatile
123818334Speter	  && (TREE_TYPE (TREE_OPERAND (pointer, 0))
123918334Speter	      == TREE_TYPE (type)))
124018334Speter	return TREE_OPERAND (pointer, 0);
124118334Speter      else
124218334Speter	{
124318334Speter	  tree t = TREE_TYPE (type);
124490075Sobrien	  tree ref = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (t), pointer);
124518334Speter
124690075Sobrien	  if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
124718334Speter	    {
124818334Speter	      error ("dereferencing pointer to incomplete type");
124918334Speter	      return error_mark_node;
125018334Speter	    }
125190075Sobrien	  if (VOID_TYPE_P (t) && skip_evaluation == 0)
125218334Speter	    warning ("dereferencing `void *' pointer");
125318334Speter
125418334Speter	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
125518334Speter	     so that we get the proper error message if the result is used
125618334Speter	     to assign to.  Also, &* is supposed to be a no-op.
125718334Speter	     And ANSI C seems to specify that the type of the result
125818334Speter	     should be the const type.  */
125918334Speter	  /* A de-reference of a pointer to const is not a const.  It is valid
126018334Speter	     to change it via some other pointer.  */
126118334Speter	  TREE_READONLY (ref) = TYPE_READONLY (t);
126218334Speter	  TREE_SIDE_EFFECTS (ref)
126318334Speter	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
126418334Speter	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
126518334Speter	  return ref;
126618334Speter	}
126718334Speter    }
126818334Speter  else if (TREE_CODE (pointer) != ERROR_MARK)
126918334Speter    error ("invalid type argument of `%s'", errorstring);
127018334Speter  return error_mark_node;
127118334Speter}
127218334Speter
127318334Speter/* This handles expressions of the form "a[i]", which denotes
127418334Speter   an array reference.
127518334Speter
127618334Speter   This is logically equivalent in C to *(a+i), but we may do it differently.
127718334Speter   If A is a variable or a member, we generate a primitive ARRAY_REF.
127818334Speter   This avoids forcing the array out of registers, and can work on
127918334Speter   arrays that are not lvalues (for example, members of structures returned
128018334Speter   by functions).  */
128118334Speter
128218334Spetertree
128318334Speterbuild_array_ref (array, index)
128418334Speter     tree array, index;
128518334Speter{
128618334Speter  if (index == 0)
128718334Speter    {
128818334Speter      error ("subscript missing in array reference");
128918334Speter      return error_mark_node;
129018334Speter    }
129118334Speter
129218334Speter  if (TREE_TYPE (array) == error_mark_node
129318334Speter      || TREE_TYPE (index) == error_mark_node)
129418334Speter    return error_mark_node;
129518334Speter
129618334Speter  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
129718334Speter      && TREE_CODE (array) != INDIRECT_REF)
129818334Speter    {
129918334Speter      tree rval, type;
130018334Speter
130118334Speter      /* Subscripting with type char is likely to lose
130218334Speter	 on a machine where chars are signed.
130318334Speter	 So warn on any machine, but optionally.
130418334Speter	 Don't warn for unsigned char since that type is safe.
130518334Speter	 Don't warn for signed char because anyone who uses that
130618334Speter	 must have done so deliberately.  */
130718334Speter      if (warn_char_subscripts
130818334Speter	  && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
130918334Speter	warning ("array subscript has type `char'");
131018334Speter
131118334Speter      /* Apply default promotions *after* noticing character types.  */
131218334Speter      index = default_conversion (index);
131318334Speter
131418334Speter      /* Require integer *after* promotion, for sake of enums.  */
131518334Speter      if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
131618334Speter	{
131718334Speter	  error ("array subscript is not an integer");
131818334Speter	  return error_mark_node;
131918334Speter	}
132018334Speter
132118334Speter      /* An array that is indexed by a non-constant
132218334Speter	 cannot be stored in a register; we must be able to do
132318334Speter	 address arithmetic on its address.
132418334Speter	 Likewise an array of elements of variable size.  */
132518334Speter      if (TREE_CODE (index) != INTEGER_CST
132690075Sobrien	  || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
132718334Speter	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
132818334Speter	{
132918334Speter	  if (mark_addressable (array) == 0)
133018334Speter	    return error_mark_node;
133118334Speter	}
133218334Speter      /* An array that is indexed by a constant value which is not within
133318334Speter	 the array bounds cannot be stored in a register either; because we
133418334Speter	 would get a crash in store_bit_field/extract_bit_field when trying
133518334Speter	 to access a non-existent part of the register.  */
133618334Speter      if (TREE_CODE (index) == INTEGER_CST
133718334Speter	  && TYPE_VALUES (TREE_TYPE (array))
133818334Speter	  && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array))))
133918334Speter	{
134018334Speter	  if (mark_addressable (array) == 0)
134118334Speter	    return error_mark_node;
134218334Speter	}
134318334Speter
134418334Speter      if (pedantic)
134518334Speter	{
134618334Speter	  tree foo = array;
134718334Speter	  while (TREE_CODE (foo) == COMPONENT_REF)
134818334Speter	    foo = TREE_OPERAND (foo, 0);
134918334Speter	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
135090075Sobrien	    pedwarn ("ISO C forbids subscripting `register' array");
135190075Sobrien	  else if (! flag_isoc99 && ! lvalue_p (foo))
135290075Sobrien	    pedwarn ("ISO C89 forbids subscripting non-lvalue array");
135318334Speter	}
135418334Speter
135518334Speter      type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
135618334Speter      rval = build (ARRAY_REF, type, array, index);
135718334Speter      /* Array ref is const/volatile if the array elements are
135818334Speter         or if the array is.  */
135918334Speter      TREE_READONLY (rval)
136018334Speter	|= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
136118334Speter	    | TREE_READONLY (array));
136218334Speter      TREE_SIDE_EFFECTS (rval)
136318334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
136418334Speter	    | TREE_SIDE_EFFECTS (array));
136518334Speter      TREE_THIS_VOLATILE (rval)
136618334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
136718334Speter	    /* This was added by rms on 16 Nov 91.
136818334Speter	       It fixes  vol struct foo *a;  a->elts[1]
136918334Speter	       in an inline function.
137018334Speter	       Hope it doesn't break something else.  */
137118334Speter	    | TREE_THIS_VOLATILE (array));
137218334Speter      return require_complete_type (fold (rval));
137318334Speter    }
137418334Speter
137518334Speter  {
137618334Speter    tree ar = default_conversion (array);
137718334Speter    tree ind = default_conversion (index);
137818334Speter
137950397Sobrien    /* Do the same warning check as above, but only on the part that's
138050397Sobrien       syntactically the index and only if it is also semantically
138150397Sobrien       the index.  */
138250397Sobrien    if (warn_char_subscripts
138350397Sobrien	&& TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
138450397Sobrien	&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
138550397Sobrien      warning ("subscript has type `char'");
138650397Sobrien
138718334Speter    /* Put the integer in IND to simplify error checking.  */
138818334Speter    if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
138918334Speter      {
139018334Speter	tree temp = ar;
139118334Speter	ar = ind;
139218334Speter	ind = temp;
139318334Speter      }
139418334Speter
139518334Speter    if (ar == error_mark_node)
139618334Speter      return ar;
139718334Speter
139850397Sobrien    if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE
139950397Sobrien	|| TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE)
140018334Speter      {
140118334Speter	error ("subscripted value is neither array nor pointer");
140218334Speter	return error_mark_node;
140318334Speter      }
140418334Speter    if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
140518334Speter      {
140618334Speter	error ("array subscript is not an integer");
140718334Speter	return error_mark_node;
140818334Speter      }
140918334Speter
141018334Speter    return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
141118334Speter			       "array indexing");
141218334Speter  }
141318334Speter}
141418334Speter
141590075Sobrien/* Build an external reference to identifier ID.  FUN indicates
141690075Sobrien   whether this will be used for a function call.  */
141790075Sobrientree
141890075Sobrienbuild_external_ref (id, fun)
141990075Sobrien     tree id;
142090075Sobrien     int fun;
142190075Sobrien{
142290075Sobrien  tree ref;
142390075Sobrien  tree decl = lookup_name (id);
142490075Sobrien  tree objc_ivar = lookup_objc_ivar (id);
142590075Sobrien
142690075Sobrien  if (decl && TREE_DEPRECATED (decl))
142790075Sobrien    warn_deprecated_use (decl);
142890075Sobrien
142990075Sobrien  if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
143090075Sobrien    {
143190075Sobrien      if (objc_ivar)
143290075Sobrien	ref = objc_ivar;
143390075Sobrien      else if (fun)
143490075Sobrien	{
143590075Sobrien	  if (!decl || decl == error_mark_node)
143690075Sobrien	    /* Ordinary implicit function declaration.  */
143790075Sobrien	    ref = implicitly_declare (id);
143890075Sobrien	  else
143990075Sobrien	    {
144090075Sobrien	      /* Implicit declaration of built-in function.  Don't
144190075Sobrien		 change the built-in declaration, but don't let this
144290075Sobrien		 go by silently, either.  */
144390075Sobrien	      implicit_decl_warning (id);
144490075Sobrien
144590075Sobrien	      /* only issue this warning once */
144690075Sobrien	      C_DECL_ANTICIPATED (decl) = 0;
144790075Sobrien	      ref = decl;
144890075Sobrien	    }
144990075Sobrien	}
145090075Sobrien      else
145190075Sobrien	{
145290075Sobrien	  /* Reference to undeclared variable, including reference to
145390075Sobrien	     builtin outside of function-call context.  */
145490075Sobrien	  if (current_function_decl == 0)
145590075Sobrien	    error ("`%s' undeclared here (not in a function)",
145690075Sobrien		   IDENTIFIER_POINTER (id));
145790075Sobrien	  else
145890075Sobrien	    {
145990075Sobrien	      if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node
146090075Sobrien		  || IDENTIFIER_ERROR_LOCUS (id) != current_function_decl)
146190075Sobrien		{
146290075Sobrien		  error ("`%s' undeclared (first use in this function)",
146390075Sobrien			 IDENTIFIER_POINTER (id));
146490075Sobrien
146590075Sobrien		  if (! undeclared_variable_notice)
146690075Sobrien		    {
146790075Sobrien		      error ("(Each undeclared identifier is reported only once");
146890075Sobrien		      error ("for each function it appears in.)");
146990075Sobrien		      undeclared_variable_notice = 1;
147090075Sobrien		    }
147190075Sobrien		}
147290075Sobrien	      IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node;
147390075Sobrien	      IDENTIFIER_ERROR_LOCUS (id) = current_function_decl;
147490075Sobrien	    }
147590075Sobrien	  return error_mark_node;
147690075Sobrien	}
147790075Sobrien    }
147890075Sobrien  else
147990075Sobrien    {
148090075Sobrien      /* Properly declared variable or function reference.  */
148190075Sobrien      if (!objc_ivar)
148290075Sobrien	ref = decl;
148390075Sobrien      else if (decl != objc_ivar && IDENTIFIER_LOCAL_VALUE (id))
148490075Sobrien	{
148590075Sobrien	  warning ("local declaration of `%s' hides instance variable",
148690075Sobrien		   IDENTIFIER_POINTER (id));
148790075Sobrien	  ref = decl;
148890075Sobrien	}
148990075Sobrien      else
149090075Sobrien	ref = objc_ivar;
149190075Sobrien    }
149290075Sobrien
149390075Sobrien  if (TREE_TYPE (ref) == error_mark_node)
149490075Sobrien    return error_mark_node;
149590075Sobrien
149690075Sobrien  assemble_external (ref);
149790075Sobrien  TREE_USED (ref) = 1;
149890075Sobrien
149990075Sobrien  if (TREE_CODE (ref) == CONST_DECL)
150090075Sobrien    {
150190075Sobrien      ref = DECL_INITIAL (ref);
150290075Sobrien      TREE_CONSTANT (ref) = 1;
150390075Sobrien    }
150490075Sobrien
150590075Sobrien  return ref;
150690075Sobrien}
150790075Sobrien
150818334Speter/* Build a function call to function FUNCTION with parameters PARAMS.
150918334Speter   PARAMS is a list--a chain of TREE_LIST nodes--in which the
151018334Speter   TREE_VALUE of each node is a parameter-expression.
151118334Speter   FUNCTION's data type may be a function type or a pointer-to-function.  */
151218334Speter
151318334Spetertree
151418334Speterbuild_function_call (function, params)
151518334Speter     tree function, params;
151618334Speter{
151790075Sobrien  tree fntype, fundecl = 0;
151890075Sobrien  tree coerced_params;
151990075Sobrien  tree name = NULL_TREE, assembler_name = NULL_TREE, result;
152018334Speter
152118334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
152218334Speter  STRIP_TYPE_NOPS (function);
152318334Speter
152418334Speter  /* Convert anything with function type to a pointer-to-function.  */
152518334Speter  if (TREE_CODE (function) == FUNCTION_DECL)
152618334Speter    {
152718334Speter      name = DECL_NAME (function);
152818334Speter      assembler_name = DECL_ASSEMBLER_NAME (function);
152918334Speter
153018334Speter      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
153118334Speter	 (because calling an inline function does not mean the function
153218334Speter	 needs to be separately compiled).  */
153318334Speter      fntype = build_type_variant (TREE_TYPE (function),
153418334Speter				   TREE_READONLY (function),
153518334Speter				   TREE_THIS_VOLATILE (function));
153618334Speter      fundecl = function;
153718334Speter      function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
153818334Speter    }
153918334Speter  else
154018334Speter    function = default_conversion (function);
154118334Speter
154218334Speter  fntype = TREE_TYPE (function);
154318334Speter
154418334Speter  if (TREE_CODE (fntype) == ERROR_MARK)
154518334Speter    return error_mark_node;
154618334Speter
154718334Speter  if (!(TREE_CODE (fntype) == POINTER_TYPE
154818334Speter	&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
154918334Speter    {
155018334Speter      error ("called object is not a function");
155118334Speter      return error_mark_node;
155218334Speter    }
155318334Speter
155496263Sobrien  if (fundecl && TREE_THIS_VOLATILE (fundecl))
155596263Sobrien    current_function_returns_abnormally = 1;
155696263Sobrien
155718334Speter  /* fntype now gets the type of function pointed to.  */
155818334Speter  fntype = TREE_TYPE (fntype);
155918334Speter
156018334Speter  /* Convert the parameters to the types declared in the
156118334Speter     function prototype, or apply default promotions.  */
156218334Speter
156318334Speter  coerced_params
156418334Speter    = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
156518334Speter
156618334Speter  /* Check for errors in format strings.  */
156718334Speter
156890075Sobrien  if (warn_format)
156990075Sobrien    check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
157018334Speter
157118334Speter  /* Recognize certain built-in functions so we can make tree-codes
157218334Speter     other than CALL_EXPR.  We do this when it enables fold-const.c
157318334Speter     to do something useful.  */
157418334Speter
157518334Speter  if (TREE_CODE (function) == ADDR_EXPR
157618334Speter      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
157718334Speter      && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
157890075Sobrien    {
157990075Sobrien      result = expand_tree_builtin (TREE_OPERAND (function, 0),
158090075Sobrien				    params, coerced_params);
158190075Sobrien      if (result)
158290075Sobrien	return result;
158390075Sobrien    }
158418334Speter
158590075Sobrien  result = build (CALL_EXPR, TREE_TYPE (fntype),
158690075Sobrien		  function, coerced_params, NULL_TREE);
158790075Sobrien  TREE_SIDE_EFFECTS (result) = 1;
158890075Sobrien  result = fold (result);
158918334Speter
159090075Sobrien  if (VOID_TYPE_P (TREE_TYPE (result)))
159190075Sobrien    return result;
159290075Sobrien  return require_complete_type (result);
159318334Speter}
159418334Speter
159518334Speter/* Convert the argument expressions in the list VALUES
159618334Speter   to the types in the list TYPELIST.  The result is a list of converted
159718334Speter   argument expressions.
159818334Speter
159918334Speter   If TYPELIST is exhausted, or when an element has NULL as its type,
160018334Speter   perform the default conversions.
160118334Speter
160218334Speter   PARMLIST is the chain of parm decls for the function being called.
160318334Speter   It may be 0, if that info is not available.
160418334Speter   It is used only for generating error messages.
160518334Speter
160618334Speter   NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
160718334Speter
160818334Speter   This is also where warnings about wrong number of args are generated.
160918334Speter
161018334Speter   Both VALUES and the returned value are chains of TREE_LIST nodes
161118334Speter   with the elements of the list in the TREE_VALUE slots of those nodes.  */
161218334Speter
161318334Speterstatic tree
161418334Speterconvert_arguments (typelist, values, name, fundecl)
161518334Speter     tree typelist, values, name, fundecl;
161618334Speter{
161790075Sobrien  tree typetail, valtail;
161890075Sobrien  tree result = NULL;
161918334Speter  int parmnum;
162018334Speter
162118334Speter  /* Scan the given expressions and types, producing individual
162218334Speter     converted arguments and pushing them on RESULT in reverse order.  */
162318334Speter
162418334Speter  for (valtail = values, typetail = typelist, parmnum = 0;
162518334Speter       valtail;
162618334Speter       valtail = TREE_CHAIN (valtail), parmnum++)
162718334Speter    {
162890075Sobrien      tree type = typetail ? TREE_VALUE (typetail) : 0;
162990075Sobrien      tree val = TREE_VALUE (valtail);
163018334Speter
163118334Speter      if (type == void_type_node)
163218334Speter	{
163318334Speter	  if (name)
163418334Speter	    error ("too many arguments to function `%s'",
163518334Speter		   IDENTIFIER_POINTER (name));
163618334Speter	  else
163718334Speter	    error ("too many arguments to function");
163818334Speter	  break;
163918334Speter	}
164018334Speter
164118334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
164218334Speter      /* Do not use STRIP_NOPS here!  We do not want an enumerator with value 0
164318334Speter	 to convert automatically to a pointer.  */
164418334Speter      if (TREE_CODE (val) == NON_LVALUE_EXPR)
164518334Speter	val = TREE_OPERAND (val, 0);
164618334Speter
164790075Sobrien      val = default_function_array_conversion (val);
164818334Speter
164918334Speter      val = require_complete_type (val);
165018334Speter
165118334Speter      if (type != 0)
165218334Speter	{
165318334Speter	  /* Formal parm type is specified by a function prototype.  */
165418334Speter	  tree parmval;
165518334Speter
165690075Sobrien	  if (!COMPLETE_TYPE_P (type))
165718334Speter	    {
165818334Speter	      error ("type of formal parameter %d is incomplete", parmnum + 1);
165918334Speter	      parmval = val;
166018334Speter	    }
166118334Speter	  else
166218334Speter	    {
166318334Speter	      /* Optionally warn about conversions that
166418334Speter		 differ from the default conversions.  */
166590075Sobrien	      if (warn_conversion || warn_traditional)
166618334Speter		{
166718334Speter		  int formal_prec = TYPE_PRECISION (type);
166818334Speter
166918334Speter		  if (INTEGRAL_TYPE_P (type)
167018334Speter		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
167118334Speter		    warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
167290075Sobrien		  if (INTEGRAL_TYPE_P (type)
167390075Sobrien		      && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
167490075Sobrien		    warn_for_assignment ("%s as integer rather than complex due to prototype", (char *) 0, name, parmnum + 1);
167518334Speter		  else if (TREE_CODE (type) == COMPLEX_TYPE
167618334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
167718334Speter		    warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
167818334Speter		  else if (TREE_CODE (type) == REAL_TYPE
167918334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
168018334Speter		    warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
168190075Sobrien		  else if (TREE_CODE (type) == COMPLEX_TYPE
168290075Sobrien			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
168390075Sobrien		    warn_for_assignment ("%s as complex rather than integer due to prototype", (char *) 0, name, parmnum + 1);
168418334Speter		  else if (TREE_CODE (type) == REAL_TYPE
168518334Speter			   && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
168618334Speter		    warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
168718334Speter		  /* ??? At some point, messages should be written about
168818334Speter		     conversions between complex types, but that's too messy
168918334Speter		     to do now.  */
169018334Speter		  else if (TREE_CODE (type) == REAL_TYPE
169118334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
169218334Speter		    {
169318334Speter		      /* Warn if any argument is passed as `float',
169418334Speter			 since without a prototype it would be `double'.  */
169518334Speter		      if (formal_prec == TYPE_PRECISION (float_type_node))
169618334Speter			warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1);
169718334Speter		    }
169890075Sobrien		  /* Detect integer changing in width or signedness.
169990075Sobrien		     These warnings are only activated with
170090075Sobrien		     -Wconversion, not with -Wtraditional.  */
170190075Sobrien		  else if (warn_conversion && INTEGRAL_TYPE_P (type)
170218334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
170318334Speter		    {
170418334Speter		      tree would_have_been = default_conversion (val);
170518334Speter		      tree type1 = TREE_TYPE (would_have_been);
170618334Speter
170718334Speter		      if (TREE_CODE (type) == ENUMERAL_TYPE
170890075Sobrien			  && (TYPE_MAIN_VARIANT (type)
170990075Sobrien			      == TYPE_MAIN_VARIANT (TREE_TYPE (val))))
171018334Speter			/* No warning if function asks for enum
171118334Speter			   and the actual arg is that enum type.  */
171218334Speter			;
171318334Speter		      else if (formal_prec != TYPE_PRECISION (type1))
171418334Speter			warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
171518334Speter		      else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1))
171618334Speter			;
171718334Speter		      /* Don't complain if the formal parameter type
171818334Speter			 is an enum, because we can't tell now whether
171918334Speter			 the value was an enum--even the same enum.  */
172018334Speter		      else if (TREE_CODE (type) == ENUMERAL_TYPE)
172118334Speter			;
172218334Speter		      else if (TREE_CODE (val) == INTEGER_CST
172318334Speter			       && int_fits_type_p (val, type))
172418334Speter			/* Change in signedness doesn't matter
172518334Speter			   if a constant value is unaffected.  */
172618334Speter			;
172718334Speter		      /* Likewise for a constant in a NOP_EXPR.  */
172818334Speter		      else if (TREE_CODE (val) == NOP_EXPR
172918334Speter			       && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST
173018334Speter			       && int_fits_type_p (TREE_OPERAND (val, 0), type))
173118334Speter			;
173218334Speter#if 0 /* We never get such tree structure here.  */
173318334Speter		      else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE
173418334Speter			       && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type)
173518334Speter			       && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type))
173618334Speter			/* Change in signedness doesn't matter
173718334Speter			   if an enum value is unaffected.  */
173818334Speter			;
173918334Speter#endif
174018334Speter		      /* If the value is extended from a narrower
174118334Speter			 unsigned type, it doesn't matter whether we
174218334Speter			 pass it as signed or unsigned; the value
174318334Speter			 certainly is the same either way.  */
174418334Speter		      else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)
174518334Speter			       && TREE_UNSIGNED (TREE_TYPE (val)))
174618334Speter			;
174718334Speter		      else if (TREE_UNSIGNED (type))
174818334Speter			warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
174918334Speter		      else
175018334Speter			warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
175118334Speter		    }
175218334Speter		}
175318334Speter
175418334Speter	      parmval = convert_for_assignment (type, val,
175550397Sobrien					        (char *) 0, /* arg passing  */
175618334Speter						fundecl, name, parmnum + 1);
175718334Speter
175890075Sobrien	      if (PROMOTE_PROTOTYPES
175990075Sobrien		  && INTEGRAL_TYPE_P (type)
176018334Speter		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
176118334Speter		parmval = default_conversion (parmval);
176218334Speter	    }
176318334Speter	  result = tree_cons (NULL_TREE, parmval, result);
176418334Speter	}
176518334Speter      else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
176618334Speter               && (TYPE_PRECISION (TREE_TYPE (val))
176718334Speter	           < TYPE_PRECISION (double_type_node)))
176818334Speter	/* Convert `float' to `double'.  */
176918334Speter	result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
177018334Speter      else
177118334Speter	/* Convert `short' and `char' to full-size `int'.  */
177218334Speter	result = tree_cons (NULL_TREE, default_conversion (val), result);
177318334Speter
177418334Speter      if (typetail)
177518334Speter	typetail = TREE_CHAIN (typetail);
177618334Speter    }
177718334Speter
177818334Speter  if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
177918334Speter    {
178018334Speter      if (name)
178118334Speter	error ("too few arguments to function `%s'",
178218334Speter	       IDENTIFIER_POINTER (name));
178318334Speter      else
178418334Speter	error ("too few arguments to function");
178518334Speter    }
178618334Speter
178718334Speter  return nreverse (result);
178818334Speter}
178918334Speter
179018334Speter/* This is the entry point used by the parser
179118334Speter   for binary operators in the input.
179218334Speter   In addition to constructing the expression,
179318334Speter   we check for operands that were written with other binary operators
179418334Speter   in a way that is likely to confuse the user.  */
179518334Speter
179618334Spetertree
179718334Speterparser_build_binary_op (code, arg1, arg2)
179818334Speter     enum tree_code code;
179918334Speter     tree arg1, arg2;
180018334Speter{
180118334Speter  tree result = build_binary_op (code, arg1, arg2, 1);
180218334Speter
180318334Speter  char class;
180418334Speter  char class1 = TREE_CODE_CLASS (TREE_CODE (arg1));
180518334Speter  char class2 = TREE_CODE_CLASS (TREE_CODE (arg2));
180618334Speter  enum tree_code code1 = ERROR_MARK;
180718334Speter  enum tree_code code2 = ERROR_MARK;
180818334Speter
180990075Sobrien  if (TREE_CODE (result) == ERROR_MARK)
181090075Sobrien    return error_mark_node;
181190075Sobrien
181290075Sobrien  if (IS_EXPR_CODE_CLASS (class1))
181318334Speter    code1 = C_EXP_ORIGINAL_CODE (arg1);
181490075Sobrien  if (IS_EXPR_CODE_CLASS (class2))
181518334Speter    code2 = C_EXP_ORIGINAL_CODE (arg2);
181618334Speter
181718334Speter  /* Check for cases such as x+y<<z which users are likely
181818334Speter     to misinterpret.  If parens are used, C_EXP_ORIGINAL_CODE
181918334Speter     is cleared to prevent these warnings.  */
182018334Speter  if (warn_parentheses)
182118334Speter    {
182218334Speter      if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
182318334Speter	{
182418334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
182518334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
182618334Speter	    warning ("suggest parentheses around + or - inside shift");
182718334Speter	}
182818334Speter
182918334Speter      if (code == TRUTH_ORIF_EXPR)
183018334Speter	{
183118334Speter	  if (code1 == TRUTH_ANDIF_EXPR
183218334Speter	      || code2 == TRUTH_ANDIF_EXPR)
183318334Speter	    warning ("suggest parentheses around && within ||");
183418334Speter	}
183518334Speter
183618334Speter      if (code == BIT_IOR_EXPR)
183718334Speter	{
183818334Speter	  if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
183918334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
184018334Speter	      || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
184118334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
184218334Speter	    warning ("suggest parentheses around arithmetic in operand of |");
184318334Speter	  /* Check cases like x|y==z */
184418334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
184518334Speter	    warning ("suggest parentheses around comparison in operand of |");
184618334Speter	}
184718334Speter
184818334Speter      if (code == BIT_XOR_EXPR)
184918334Speter	{
185018334Speter	  if (code1 == BIT_AND_EXPR
185118334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
185218334Speter	      || code2 == BIT_AND_EXPR
185318334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
185418334Speter	    warning ("suggest parentheses around arithmetic in operand of ^");
185518334Speter	  /* Check cases like x^y==z */
185618334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
185718334Speter	    warning ("suggest parentheses around comparison in operand of ^");
185818334Speter	}
185918334Speter
186018334Speter      if (code == BIT_AND_EXPR)
186118334Speter	{
186218334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
186318334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
186418334Speter	    warning ("suggest parentheses around + or - in operand of &");
186518334Speter	  /* Check cases like x&y==z */
186618334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
186718334Speter	    warning ("suggest parentheses around comparison in operand of &");
186818334Speter	}
186918334Speter    }
187018334Speter
187118334Speter  /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
187218334Speter  if (TREE_CODE_CLASS (code) == '<' && extra_warnings
187318334Speter      && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<'))
187418334Speter    warning ("comparisons like X<=Y<=Z do not have their mathematical meaning");
187518334Speter
187618334Speter  unsigned_conversion_warning (result, arg1);
187718334Speter  unsigned_conversion_warning (result, arg2);
187818334Speter  overflow_warning (result);
187918334Speter
188018334Speter  class = TREE_CODE_CLASS (TREE_CODE (result));
188118334Speter
188218334Speter  /* Record the code that was specified in the source,
188318334Speter     for the sake of warnings about confusing nesting.  */
188490075Sobrien  if (IS_EXPR_CODE_CLASS (class))
188518334Speter    C_SET_EXP_ORIGINAL_CODE (result, code);
188618334Speter  else
188718334Speter    {
188818334Speter      int flag = TREE_CONSTANT (result);
188918334Speter      /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR
189018334Speter	 so that convert_for_assignment wouldn't strip it.
189118334Speter	 That way, we got warnings for things like p = (1 - 1).
189218334Speter	 But it turns out we should not get those warnings.  */
189318334Speter      result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
189418334Speter      C_SET_EXP_ORIGINAL_CODE (result, code);
189518334Speter      TREE_CONSTANT (result) = flag;
189618334Speter    }
189718334Speter
189818334Speter  return result;
189918334Speter}
190018334Speter
190118334Speter/* Build a binary-operation expression without default conversions.
190218334Speter   CODE is the kind of expression to build.
190318334Speter   This function differs from `build' in several ways:
190418334Speter   the data type of the result is computed and recorded in it,
190518334Speter   warnings are generated if arg data types are invalid,
190618334Speter   special handling for addition and subtraction of pointers is known,
190718334Speter   and some optimization is done (operations on narrow ints
190818334Speter   are done in the narrower type when that gives the same result).
190918334Speter   Constant folding is also done before the result is returned.
191018334Speter
191118334Speter   Note that the operands will never have enumeral types, or function
191218334Speter   or array types, because either they will have the default conversions
191318334Speter   performed or they have both just been converted to some other type in which
191418334Speter   the arithmetic is to be done.  */
191518334Speter
191618334Spetertree
191718334Speterbuild_binary_op (code, orig_op0, orig_op1, convert_p)
191818334Speter     enum tree_code code;
191918334Speter     tree orig_op0, orig_op1;
192018334Speter     int convert_p;
192118334Speter{
192218334Speter  tree type0, type1;
192390075Sobrien  enum tree_code code0, code1;
192418334Speter  tree op0, op1;
192518334Speter
192618334Speter  /* Expression code to give to the expression when it is built.
192718334Speter     Normally this is CODE, which is what the caller asked for,
192818334Speter     but in some special cases we change it.  */
192990075Sobrien  enum tree_code resultcode = code;
193018334Speter
193118334Speter  /* Data type in which the computation is to be performed.
193218334Speter     In the simplest cases this is the common type of the arguments.  */
193390075Sobrien  tree result_type = NULL;
193418334Speter
193518334Speter  /* Nonzero means operands have already been type-converted
193618334Speter     in whatever way is necessary.
193718334Speter     Zero means they need to be converted to RESULT_TYPE.  */
193818334Speter  int converted = 0;
193918334Speter
194018334Speter  /* Nonzero means create the expression with this type, rather than
194118334Speter     RESULT_TYPE.  */
194218334Speter  tree build_type = 0;
194318334Speter
194418334Speter  /* Nonzero means after finally constructing the expression
194518334Speter     convert it to this type.  */
194618334Speter  tree final_type = 0;
194718334Speter
194818334Speter  /* Nonzero if this is an operation like MIN or MAX which can
194918334Speter     safely be computed in short if both args are promoted shorts.
195018334Speter     Also implies COMMON.
195118334Speter     -1 indicates a bitwise operation; this makes a difference
195218334Speter     in the exact conditions for when it is safe to do the operation
195318334Speter     in a narrower mode.  */
195418334Speter  int shorten = 0;
195518334Speter
195618334Speter  /* Nonzero if this is a comparison operation;
195718334Speter     if both args are promoted shorts, compare the original shorts.
195818334Speter     Also implies COMMON.  */
195918334Speter  int short_compare = 0;
196018334Speter
196118334Speter  /* Nonzero if this is a right-shift operation, which can be computed on the
196218334Speter     original short and then promoted if the operand is a promoted short.  */
196318334Speter  int short_shift = 0;
196418334Speter
196518334Speter  /* Nonzero means set RESULT_TYPE to the common type of the args.  */
196618334Speter  int common = 0;
196718334Speter
196818334Speter  if (convert_p)
196918334Speter    {
197018334Speter      op0 = default_conversion (orig_op0);
197118334Speter      op1 = default_conversion (orig_op1);
197218334Speter    }
197318334Speter  else
197418334Speter    {
197518334Speter      op0 = orig_op0;
197618334Speter      op1 = orig_op1;
197718334Speter    }
197818334Speter
197918334Speter  type0 = TREE_TYPE (op0);
198018334Speter  type1 = TREE_TYPE (op1);
198118334Speter
198218334Speter  /* The expression codes of the data types of the arguments tell us
198318334Speter     whether the arguments are integers, floating, pointers, etc.  */
198418334Speter  code0 = TREE_CODE (type0);
198518334Speter  code1 = TREE_CODE (type1);
198618334Speter
198718334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
198818334Speter  STRIP_TYPE_NOPS (op0);
198918334Speter  STRIP_TYPE_NOPS (op1);
199018334Speter
199118334Speter  /* If an error was already reported for one of the arguments,
199218334Speter     avoid reporting another error.  */
199318334Speter
199418334Speter  if (code0 == ERROR_MARK || code1 == ERROR_MARK)
199518334Speter    return error_mark_node;
199618334Speter
199718334Speter  switch (code)
199818334Speter    {
199918334Speter    case PLUS_EXPR:
200018334Speter      /* Handle the pointer + int case.  */
200118334Speter      if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
200218334Speter	return pointer_int_sum (PLUS_EXPR, op0, op1);
200318334Speter      else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
200418334Speter	return pointer_int_sum (PLUS_EXPR, op1, op0);
200518334Speter      else
200618334Speter	common = 1;
200718334Speter      break;
200818334Speter
200918334Speter    case MINUS_EXPR:
201018334Speter      /* Subtraction of two similar pointers.
201118334Speter	 We must subtract them as integers, then divide by object size.  */
201218334Speter      if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
201318334Speter	  && comp_target_types (type0, type1))
201418334Speter	return pointer_diff (op0, op1);
201518334Speter      /* Handle pointer minus int.  Just like pointer plus int.  */
201618334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
201718334Speter	return pointer_int_sum (MINUS_EXPR, op0, op1);
201818334Speter      else
201918334Speter	common = 1;
202018334Speter      break;
202118334Speter
202218334Speter    case MULT_EXPR:
202318334Speter      common = 1;
202418334Speter      break;
202518334Speter
202618334Speter    case TRUNC_DIV_EXPR:
202718334Speter    case CEIL_DIV_EXPR:
202818334Speter    case FLOOR_DIV_EXPR:
202918334Speter    case ROUND_DIV_EXPR:
203018334Speter    case EXACT_DIV_EXPR:
203190075Sobrien      /* Floating point division by zero is a legitimate way to obtain
203290075Sobrien	 infinities and NaNs.  */
203390075Sobrien      if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
203490075Sobrien	warning ("division by zero");
203590075Sobrien
203618334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
203718334Speter	   || code0 == COMPLEX_TYPE)
203818334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
203918334Speter	      || code1 == COMPLEX_TYPE))
204018334Speter	{
204118334Speter	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
204218334Speter	    resultcode = RDIV_EXPR;
204318334Speter	  else
204490075Sobrien	    /* Although it would be tempting to shorten always here, that
204590075Sobrien	       loses on some targets, since the modulo instruction is
204690075Sobrien	       undefined if the quotient can't be represented in the
204790075Sobrien	       computation mode.  We shorten only if unsigned or if
204890075Sobrien	       dividing by something we know != -1.  */
204990075Sobrien	    shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
205090075Sobrien		       || (TREE_CODE (op1) == INTEGER_CST
205190075Sobrien			   && ! integer_all_onesp (op1)));
205218334Speter	  common = 1;
205318334Speter	}
205418334Speter      break;
205518334Speter
205618334Speter    case BIT_AND_EXPR:
205718334Speter    case BIT_ANDTC_EXPR:
205818334Speter    case BIT_IOR_EXPR:
205918334Speter    case BIT_XOR_EXPR:
206018334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
206118334Speter	shorten = -1;
206218334Speter      break;
206318334Speter
206418334Speter    case TRUNC_MOD_EXPR:
206518334Speter    case FLOOR_MOD_EXPR:
206690075Sobrien      if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
206790075Sobrien	warning ("division by zero");
206890075Sobrien
206918334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
207018334Speter	{
207118334Speter	  /* Although it would be tempting to shorten always here, that loses
207218334Speter	     on some targets, since the modulo instruction is undefined if the
207318334Speter	     quotient can't be represented in the computation mode.  We shorten
207418334Speter	     only if unsigned or if dividing by something we know != -1.  */
207518334Speter	  shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
207618334Speter		     || (TREE_CODE (op1) == INTEGER_CST
207790075Sobrien			 && ! integer_all_onesp (op1)));
207818334Speter	  common = 1;
207918334Speter	}
208018334Speter      break;
208118334Speter
208218334Speter    case TRUTH_ANDIF_EXPR:
208318334Speter    case TRUTH_ORIF_EXPR:
208418334Speter    case TRUTH_AND_EXPR:
208518334Speter    case TRUTH_OR_EXPR:
208618334Speter    case TRUTH_XOR_EXPR:
208718334Speter      if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
208818334Speter	   || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
208918334Speter	  && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
209018334Speter	      || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
209118334Speter	{
209218334Speter	  /* Result of these operations is always an int,
209318334Speter	     but that does not mean the operands should be
209418334Speter	     converted to ints!  */
209518334Speter	  result_type = integer_type_node;
209618334Speter	  op0 = truthvalue_conversion (op0);
209718334Speter	  op1 = truthvalue_conversion (op1);
209818334Speter	  converted = 1;
209918334Speter	}
210018334Speter      break;
210118334Speter
210218334Speter      /* Shift operations: result has same type as first operand;
210318334Speter	 always convert second operand to int.
210418334Speter	 Also set SHORT_SHIFT if shifting rightward.  */
210518334Speter
210618334Speter    case RSHIFT_EXPR:
210718334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
210818334Speter	{
210950397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
211018334Speter	    {
211118334Speter	      if (tree_int_cst_sgn (op1) < 0)
211218334Speter		warning ("right shift count is negative");
211318334Speter	      else
211418334Speter		{
211590075Sobrien		  if (! integer_zerop (op1))
211618334Speter		    short_shift = 1;
211790075Sobrien
211890075Sobrien		  if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
211918334Speter		    warning ("right shift count >= width of type");
212018334Speter		}
212118334Speter	    }
212290075Sobrien
212318334Speter	  /* Use the type of the value to be shifted.
212418334Speter	     This is what most traditional C compilers do.  */
212518334Speter	  result_type = type0;
212618334Speter	  /* Unless traditional, convert the shift-count to an integer,
212718334Speter	     regardless of size of value being shifted.  */
212818334Speter	  if (! flag_traditional)
212918334Speter	    {
213018334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
213118334Speter		op1 = convert (integer_type_node, op1);
213218334Speter	      /* Avoid converting op1 to result_type later.  */
213318334Speter	      converted = 1;
213418334Speter	    }
213518334Speter	}
213618334Speter      break;
213718334Speter
213818334Speter    case LSHIFT_EXPR:
213918334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
214018334Speter	{
214150397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
214218334Speter	    {
214318334Speter	      if (tree_int_cst_sgn (op1) < 0)
214418334Speter		warning ("left shift count is negative");
214590075Sobrien
214690075Sobrien	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
214718334Speter		warning ("left shift count >= width of type");
214818334Speter	    }
214990075Sobrien
215018334Speter	  /* Use the type of the value to be shifted.
215118334Speter	     This is what most traditional C compilers do.  */
215218334Speter	  result_type = type0;
215318334Speter	  /* Unless traditional, convert the shift-count to an integer,
215418334Speter	     regardless of size of value being shifted.  */
215518334Speter	  if (! flag_traditional)
215618334Speter	    {
215718334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
215818334Speter		op1 = convert (integer_type_node, op1);
215918334Speter	      /* Avoid converting op1 to result_type later.  */
216018334Speter	      converted = 1;
216118334Speter	    }
216218334Speter	}
216318334Speter      break;
216418334Speter
216518334Speter    case RROTATE_EXPR:
216618334Speter    case LROTATE_EXPR:
216718334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
216818334Speter	{
216950397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
217018334Speter	    {
217118334Speter	      if (tree_int_cst_sgn (op1) < 0)
217218334Speter		warning ("shift count is negative");
217390075Sobrien	      else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
217418334Speter		warning ("shift count >= width of type");
217518334Speter	    }
217690075Sobrien
217718334Speter	  /* Use the type of the value to be shifted.
217818334Speter	     This is what most traditional C compilers do.  */
217918334Speter	  result_type = type0;
218018334Speter	  /* Unless traditional, convert the shift-count to an integer,
218118334Speter	     regardless of size of value being shifted.  */
218218334Speter	  if (! flag_traditional)
218318334Speter	    {
218418334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
218518334Speter		op1 = convert (integer_type_node, op1);
218618334Speter	      /* Avoid converting op1 to result_type later.  */
218718334Speter	      converted = 1;
218818334Speter	    }
218918334Speter	}
219018334Speter      break;
219118334Speter
219218334Speter    case EQ_EXPR:
219318334Speter    case NE_EXPR:
219490075Sobrien      if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
219590075Sobrien	warning ("comparing floating point with == or != is unsafe");
219618334Speter      /* Result of comparison is always int,
219718334Speter	 but don't convert the args to int!  */
219818334Speter      build_type = integer_type_node;
219918334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
220018334Speter	   || code0 == COMPLEX_TYPE)
220118334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
220218334Speter	      || code1 == COMPLEX_TYPE))
220318334Speter	short_compare = 1;
220418334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
220518334Speter	{
220690075Sobrien	  tree tt0 = TREE_TYPE (type0);
220790075Sobrien	  tree tt1 = TREE_TYPE (type1);
220818334Speter	  /* Anything compares with void *.  void * compares with anything.
220918334Speter	     Otherwise, the targets must be compatible
221018334Speter	     and both must be object or both incomplete.  */
221118334Speter	  if (comp_target_types (type0, type1))
221218334Speter	    result_type = common_type (type0, type1);
221390075Sobrien	  else if (VOID_TYPE_P (tt0))
221418334Speter	    {
221518334Speter	      /* op0 != orig_op0 detects the case of something
221618334Speter		 whose value is 0 but which isn't a valid null ptr const.  */
221718334Speter	      if (pedantic && (!integer_zerop (op0) || op0 != orig_op0)
221818334Speter		  && TREE_CODE (tt1) == FUNCTION_TYPE)
221990075Sobrien		pedwarn ("ISO C forbids comparison of `void *' with function pointer");
222018334Speter	    }
222190075Sobrien	  else if (VOID_TYPE_P (tt1))
222218334Speter	    {
222318334Speter	      if (pedantic && (!integer_zerop (op1) || op1 != orig_op1)
222418334Speter		  && TREE_CODE (tt0) == FUNCTION_TYPE)
222590075Sobrien		pedwarn ("ISO C forbids comparison of `void *' with function pointer");
222618334Speter	    }
222718334Speter	  else
222818334Speter	    pedwarn ("comparison of distinct pointer types lacks a cast");
222918334Speter
223018334Speter	  if (result_type == NULL_TREE)
223118334Speter	    result_type = ptr_type_node;
223218334Speter	}
223318334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
223418334Speter	       && integer_zerop (op1))
223518334Speter	result_type = type0;
223618334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
223718334Speter	       && integer_zerop (op0))
223818334Speter	result_type = type1;
223918334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
224018334Speter	{
224118334Speter	  result_type = type0;
224218334Speter	  if (! flag_traditional)
224318334Speter	    pedwarn ("comparison between pointer and integer");
224418334Speter	}
224518334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
224618334Speter	{
224718334Speter	  result_type = type1;
224818334Speter	  if (! flag_traditional)
224918334Speter	    pedwarn ("comparison between pointer and integer");
225018334Speter	}
225118334Speter      break;
225218334Speter
225318334Speter    case MAX_EXPR:
225418334Speter    case MIN_EXPR:
225518334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
225618334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
225718334Speter	shorten = 1;
225818334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
225918334Speter	{
226018334Speter	  if (comp_target_types (type0, type1))
226118334Speter	    {
226218334Speter	      result_type = common_type (type0, type1);
226318334Speter	      if (pedantic
226418334Speter		  && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
226590075Sobrien		pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
226618334Speter	    }
226718334Speter	  else
226818334Speter	    {
226918334Speter	      result_type = ptr_type_node;
227018334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
227118334Speter	    }
227218334Speter	}
227318334Speter      break;
227418334Speter
227518334Speter    case LE_EXPR:
227618334Speter    case GE_EXPR:
227718334Speter    case LT_EXPR:
227818334Speter    case GT_EXPR:
227918334Speter      build_type = integer_type_node;
228018334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
228118334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
228218334Speter	short_compare = 1;
228318334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
228418334Speter	{
228518334Speter	  if (comp_target_types (type0, type1))
228618334Speter	    {
228718334Speter	      result_type = common_type (type0, type1);
228890075Sobrien	      if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
228990075Sobrien		  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
229018334Speter		pedwarn ("comparison of complete and incomplete pointers");
229118334Speter	      else if (pedantic
229218334Speter		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
229390075Sobrien		pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
229418334Speter	    }
229518334Speter	  else
229618334Speter	    {
229718334Speter	      result_type = ptr_type_node;
229818334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
229918334Speter	    }
230018334Speter	}
230118334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
230218334Speter	       && integer_zerop (op1))
230318334Speter	{
230418334Speter	  result_type = type0;
230518334Speter	  if (pedantic || extra_warnings)
230618334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
230718334Speter	}
230818334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
230918334Speter	       && integer_zerop (op0))
231018334Speter	{
231118334Speter	  result_type = type1;
231218334Speter	  if (pedantic)
231318334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
231418334Speter	}
231518334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
231618334Speter	{
231718334Speter	  result_type = type0;
231818334Speter	  if (! flag_traditional)
231918334Speter	    pedwarn ("comparison between pointer and integer");
232018334Speter	}
232118334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
232218334Speter	{
232318334Speter	  result_type = type1;
232418334Speter	  if (! flag_traditional)
232518334Speter	    pedwarn ("comparison between pointer and integer");
232618334Speter	}
232718334Speter      break;
232890075Sobrien
232990075Sobrien    case UNORDERED_EXPR:
233090075Sobrien    case ORDERED_EXPR:
233190075Sobrien    case UNLT_EXPR:
233290075Sobrien    case UNLE_EXPR:
233390075Sobrien    case UNGT_EXPR:
233490075Sobrien    case UNGE_EXPR:
233590075Sobrien    case UNEQ_EXPR:
233690075Sobrien      build_type = integer_type_node;
233790075Sobrien      if (code0 != REAL_TYPE || code1 != REAL_TYPE)
233890075Sobrien	{
233990075Sobrien	  error ("unordered comparison on non-floating point argument");
234090075Sobrien	  return error_mark_node;
234190075Sobrien	}
234290075Sobrien      common = 1;
234390075Sobrien      break;
234490075Sobrien
234550397Sobrien    default:
234650397Sobrien      break;
234718334Speter    }
234818334Speter
234918334Speter  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
235018334Speter      &&
235118334Speter      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
235218334Speter    {
235318334Speter      int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
235418334Speter
235518334Speter      if (shorten || common || short_compare)
235618334Speter	result_type = common_type (type0, type1);
235718334Speter
235818334Speter      /* For certain operations (which identify themselves by shorten != 0)
235918334Speter	 if both args were extended from the same smaller type,
236018334Speter	 do the arithmetic in that type and then extend.
236118334Speter
236218334Speter	 shorten !=0 and !=1 indicates a bitwise operation.
236318334Speter	 For them, this optimization is safe only if
236418334Speter	 both args are zero-extended or both are sign-extended.
236518334Speter	 Otherwise, we might change the result.
236618334Speter	 Eg, (short)-1 | (unsigned short)-1 is (int)-1
236718334Speter	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
236818334Speter
236918334Speter      if (shorten && none_complex)
237018334Speter	{
237118334Speter	  int unsigned0, unsigned1;
237218334Speter	  tree arg0 = get_narrower (op0, &unsigned0);
237318334Speter	  tree arg1 = get_narrower (op1, &unsigned1);
237418334Speter	  /* UNS is 1 if the operation to be done is an unsigned one.  */
237518334Speter	  int uns = TREE_UNSIGNED (result_type);
237618334Speter	  tree type;
237718334Speter
237818334Speter	  final_type = result_type;
237918334Speter
238018334Speter	  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
238118334Speter	     but it *requires* conversion to FINAL_TYPE.  */
238218334Speter
238318334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op0))
238418334Speter	       == TYPE_PRECISION (TREE_TYPE (arg0)))
238518334Speter	      && TREE_TYPE (op0) != final_type)
238618334Speter	    unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
238718334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op1))
238818334Speter	       == TYPE_PRECISION (TREE_TYPE (arg1)))
238918334Speter	      && TREE_TYPE (op1) != final_type)
239018334Speter	    unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
239118334Speter
239218334Speter	  /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
239318334Speter
239418334Speter	  /* For bitwise operations, signedness of nominal type
239518334Speter	     does not matter.  Consider only how operands were extended.  */
239618334Speter	  if (shorten == -1)
239718334Speter	    uns = unsigned0;
239818334Speter
239918334Speter	  /* Note that in all three cases below we refrain from optimizing
240018334Speter	     an unsigned operation on sign-extended args.
240118334Speter	     That would not be valid.  */
240218334Speter
240318334Speter	  /* Both args variable: if both extended in same way
240418334Speter	     from same width, do it in that width.
240518334Speter	     Do it unsigned if args were zero-extended.  */
240618334Speter	  if ((TYPE_PRECISION (TREE_TYPE (arg0))
240718334Speter	       < TYPE_PRECISION (result_type))
240818334Speter	      && (TYPE_PRECISION (TREE_TYPE (arg1))
240918334Speter		  == TYPE_PRECISION (TREE_TYPE (arg0)))
241018334Speter	      && unsigned0 == unsigned1
241118334Speter	      && (unsigned0 || !uns))
241218334Speter	    result_type
241318334Speter	      = signed_or_unsigned_type (unsigned0,
241418334Speter					 common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
241518334Speter	  else if (TREE_CODE (arg0) == INTEGER_CST
241618334Speter		   && (unsigned1 || !uns)
241718334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg1))
241818334Speter		       < TYPE_PRECISION (result_type))
241918334Speter		   && (type = signed_or_unsigned_type (unsigned1,
242018334Speter						       TREE_TYPE (arg1)),
242118334Speter		       int_fits_type_p (arg0, type)))
242218334Speter	    result_type = type;
242318334Speter	  else if (TREE_CODE (arg1) == INTEGER_CST
242418334Speter		   && (unsigned0 || !uns)
242518334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg0))
242618334Speter		       < TYPE_PRECISION (result_type))
242718334Speter		   && (type = signed_or_unsigned_type (unsigned0,
242818334Speter						       TREE_TYPE (arg0)),
242918334Speter		       int_fits_type_p (arg1, type)))
243018334Speter	    result_type = type;
243118334Speter	}
243218334Speter
243318334Speter      /* Shifts can be shortened if shifting right.  */
243418334Speter
243518334Speter      if (short_shift)
243618334Speter	{
243718334Speter	  int unsigned_arg;
243818334Speter	  tree arg0 = get_narrower (op0, &unsigned_arg);
243918334Speter
244018334Speter	  final_type = result_type;
244118334Speter
244218334Speter	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
244318334Speter	    unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
244418334Speter
244518334Speter	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
244618334Speter	      /* We can shorten only if the shift count is less than the
244718334Speter		 number of bits in the smaller type size.  */
244890075Sobrien	      && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
244990075Sobrien	      /* We cannot drop an unsigned shift after sign-extension.  */
245090075Sobrien	      && (!TREE_UNSIGNED (final_type) || unsigned_arg))
245118334Speter	    {
245218334Speter	      /* Do an unsigned shift if the operand was zero-extended.  */
245318334Speter	      result_type
245490075Sobrien		= signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0));
245518334Speter	      /* Convert value-to-be-shifted to that type.  */
245618334Speter	      if (TREE_TYPE (op0) != result_type)
245718334Speter		op0 = convert (result_type, op0);
245818334Speter	      converted = 1;
245918334Speter	    }
246018334Speter	}
246118334Speter
246218334Speter      /* Comparison operations are shortened too but differently.
246318334Speter	 They identify themselves by setting short_compare = 1.  */
246418334Speter
246518334Speter      if (short_compare)
246618334Speter	{
246718334Speter	  /* Don't write &op0, etc., because that would prevent op0
246818334Speter	     from being kept in a register.
246918334Speter	     Instead, make copies of the our local variables and
247018334Speter	     pass the copies by reference, then copy them back afterward.  */
247118334Speter	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
247218334Speter	  enum tree_code xresultcode = resultcode;
247318334Speter	  tree val
247418334Speter	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
247590075Sobrien
247618334Speter	  if (val != 0)
247718334Speter	    return val;
247890075Sobrien
247918334Speter	  op0 = xop0, op1 = xop1;
248018334Speter	  converted = 1;
248118334Speter	  resultcode = xresultcode;
248218334Speter
248350397Sobrien	  if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0)
248450397Sobrien	      && skip_evaluation == 0)
248518334Speter	    {
248618334Speter	      int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
248718334Speter	      int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
248818334Speter	      int unsignedp0, unsignedp1;
248918334Speter	      tree primop0 = get_narrower (op0, &unsignedp0);
249018334Speter	      tree primop1 = get_narrower (op1, &unsignedp1);
249118334Speter
249218334Speter	      xop0 = orig_op0;
249318334Speter	      xop1 = orig_op1;
249418334Speter	      STRIP_TYPE_NOPS (xop0);
249518334Speter	      STRIP_TYPE_NOPS (xop1);
249618334Speter
249718334Speter	      /* Give warnings for comparisons between signed and unsigned
249890075Sobrien		 quantities that may fail.
249918334Speter
250090075Sobrien		 Do the checking based on the original operand trees, so that
250190075Sobrien		 casts will be considered, but default promotions won't be.
250290075Sobrien
250390075Sobrien		 Do not warn if the comparison is being done in a signed type,
250418334Speter		 since the signed type will only be chosen if it can represent
250518334Speter		 all the values of the unsigned type.  */
250618334Speter	      if (! TREE_UNSIGNED (result_type))
250718334Speter		/* OK */;
250890075Sobrien              /* Do not warn if both operands are the same signedness.  */
250918334Speter              else if (op0_signed == op1_signed)
251018334Speter                /* OK */;
251118334Speter	      else
251290075Sobrien		{
251390075Sobrien		  tree sop, uop;
251418334Speter
251590075Sobrien		  if (op0_signed)
251690075Sobrien		    sop = xop0, uop = xop1;
251790075Sobrien		  else
251890075Sobrien		    sop = xop1, uop = xop0;
251990075Sobrien
252090075Sobrien		  /* Do not warn if the signed quantity is an
252190075Sobrien		     unsuffixed integer literal (or some static
252290075Sobrien		     constant expression involving such literals or a
252390075Sobrien		     conditional expression involving such literals)
252490075Sobrien		     and it is non-negative.  */
252590075Sobrien		  if (tree_expr_nonnegative_p (sop))
252690075Sobrien		    /* OK */;
252790075Sobrien		  /* Do not warn if the comparison is an equality operation,
252890075Sobrien		     the unsigned quantity is an integral constant, and it
252990075Sobrien		     would fit in the result if the result were signed.  */
253090075Sobrien		  else if (TREE_CODE (uop) == INTEGER_CST
253190075Sobrien			   && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
253290075Sobrien			   && int_fits_type_p (uop, signed_type (result_type)))
253390075Sobrien		    /* OK */;
253490075Sobrien		  /* Do not warn if the unsigned quantity is an enumeration
253590075Sobrien		     constant and its maximum value would fit in the result
253690075Sobrien		     if the result were signed.  */
253790075Sobrien		  else if (TREE_CODE (uop) == INTEGER_CST
253890075Sobrien			   && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
253990075Sobrien			   && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE(uop)),
254090075Sobrien					       signed_type (result_type)))
254190075Sobrien		    /* OK */;
254290075Sobrien		  else
254390075Sobrien		    warning ("comparison between signed and unsigned");
254490075Sobrien		}
254590075Sobrien
254618334Speter	      /* Warn if two unsigned values are being compared in a size
254718334Speter		 larger than their original size, and one (and only one) is the
254818334Speter		 result of a `~' operator.  This comparison will always fail.
254918334Speter
255018334Speter		 Also warn if one operand is a constant, and the constant
255118334Speter		 does not have all bits set that are set in the ~ operand
255218334Speter		 when it is extended.  */
255318334Speter
255418334Speter	      if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
255518334Speter		  != (TREE_CODE (primop1) == BIT_NOT_EXPR))
255618334Speter		{
255718334Speter		  if (TREE_CODE (primop0) == BIT_NOT_EXPR)
255818334Speter		    primop0 = get_narrower (TREE_OPERAND (primop0, 0),
255918334Speter					    &unsignedp0);
256018334Speter		  else
256118334Speter		    primop1 = get_narrower (TREE_OPERAND (primop1, 0),
256218334Speter					    &unsignedp1);
256318334Speter
256490075Sobrien		  if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
256518334Speter		    {
256618334Speter		      tree primop;
256790075Sobrien		      HOST_WIDE_INT constant, mask;
256818334Speter		      int unsignedp, bits;
256918334Speter
257090075Sobrien		      if (host_integerp (primop0, 0))
257118334Speter			{
257218334Speter			  primop = primop1;
257318334Speter			  unsignedp = unsignedp1;
257490075Sobrien			  constant = tree_low_cst (primop0, 0);
257518334Speter			}
257618334Speter		      else
257718334Speter			{
257818334Speter			  primop = primop0;
257918334Speter			  unsignedp = unsignedp0;
258090075Sobrien			  constant = tree_low_cst (primop1, 0);
258118334Speter			}
258218334Speter
258318334Speter		      bits = TYPE_PRECISION (TREE_TYPE (primop));
258418334Speter		      if (bits < TYPE_PRECISION (result_type)
258590075Sobrien			  && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
258618334Speter			{
258790075Sobrien			  mask = (~ (HOST_WIDE_INT) 0) << bits;
258818334Speter			  if ((mask & constant) != mask)
258918334Speter			    warning ("comparison of promoted ~unsigned with constant");
259018334Speter			}
259118334Speter		    }
259218334Speter		  else if (unsignedp0 && unsignedp1
259318334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop0))
259418334Speter			       < TYPE_PRECISION (result_type))
259518334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop1))
259618334Speter			       < TYPE_PRECISION (result_type)))
259718334Speter		    warning ("comparison of promoted ~unsigned with unsigned");
259818334Speter		}
259918334Speter	    }
260018334Speter	}
260118334Speter    }
260218334Speter
260318334Speter  /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
260418334Speter     If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
260518334Speter     Then the expression will be built.
260618334Speter     It will be given type FINAL_TYPE if that is nonzero;
260718334Speter     otherwise, it will be given type RESULT_TYPE.  */
260818334Speter
260918334Speter  if (!result_type)
261018334Speter    {
261118334Speter      binary_op_error (code);
261218334Speter      return error_mark_node;
261318334Speter    }
261418334Speter
261518334Speter  if (! converted)
261618334Speter    {
261718334Speter      if (TREE_TYPE (op0) != result_type)
261818334Speter	op0 = convert (result_type, op0);
261918334Speter      if (TREE_TYPE (op1) != result_type)
262018334Speter	op1 = convert (result_type, op1);
262118334Speter    }
262218334Speter
262318334Speter  if (build_type == NULL_TREE)
262418334Speter    build_type = result_type;
262518334Speter
262618334Speter  {
262790075Sobrien    tree result = build (resultcode, build_type, op0, op1);
262890075Sobrien    tree folded;
262918334Speter
263018334Speter    folded = fold (result);
263118334Speter    if (folded == result)
263218334Speter      TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
263318334Speter    if (final_type != 0)
263418334Speter      return convert (final_type, folded);
263518334Speter    return folded;
263618334Speter  }
263718334Speter}
263818334Speter
263918334Speter/* Return a tree for the difference of pointers OP0 and OP1.
264018334Speter   The resulting tree has type int.  */
264118334Speter
264218334Speterstatic tree
264318334Speterpointer_diff (op0, op1)
264490075Sobrien     tree op0, op1;
264518334Speter{
264690075Sobrien  tree result, folded;
264718334Speter  tree restype = ptrdiff_type_node;
264818334Speter
264918334Speter  tree target_type = TREE_TYPE (TREE_TYPE (op0));
265090075Sobrien  tree con0, con1, lit0, lit1;
265190075Sobrien  tree orig_op1 = op1;
265218334Speter
265318334Speter  if (pedantic || warn_pointer_arith)
265418334Speter    {
265518334Speter      if (TREE_CODE (target_type) == VOID_TYPE)
265618334Speter	pedwarn ("pointer of type `void *' used in subtraction");
265718334Speter      if (TREE_CODE (target_type) == FUNCTION_TYPE)
265818334Speter	pedwarn ("pointer to a function used in subtraction");
265918334Speter    }
266018334Speter
266190075Sobrien  /* If the conversion to ptrdiff_type does anything like widening or
266290075Sobrien     converting a partial to an integral mode, we get a convert_expression
266390075Sobrien     that is in the way to do any simplifications.
266490075Sobrien     (fold-const.c doesn't know that the extra bits won't be needed.
266590075Sobrien     split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
266690075Sobrien     different mode in place.)
266790075Sobrien     So first try to find a common term here 'by hand'; we want to cover
266890075Sobrien     at least the cases that occur in legal static initializers.  */
266990075Sobrien  con0 = TREE_CODE (op0) == NOP_EXPR ? TREE_OPERAND (op0, 0) : op0;
267090075Sobrien  con1 = TREE_CODE (op1) == NOP_EXPR ? TREE_OPERAND (op1, 0) : op1;
267190075Sobrien
267290075Sobrien  if (TREE_CODE (con0) == PLUS_EXPR)
267390075Sobrien    {
267490075Sobrien      lit0 = TREE_OPERAND (con0, 1);
267590075Sobrien      con0 = TREE_OPERAND (con0, 0);
267690075Sobrien    }
267790075Sobrien  else
267890075Sobrien    lit0 = integer_zero_node;
267990075Sobrien
268090075Sobrien  if (TREE_CODE (con1) == PLUS_EXPR)
268190075Sobrien    {
268290075Sobrien      lit1 = TREE_OPERAND (con1, 1);
268390075Sobrien      con1 = TREE_OPERAND (con1, 0);
268490075Sobrien    }
268590075Sobrien  else
268690075Sobrien    lit1 = integer_zero_node;
268790075Sobrien
268890075Sobrien  if (operand_equal_p (con0, con1, 0))
268990075Sobrien    {
269090075Sobrien      op0 = lit0;
269190075Sobrien      op1 = lit1;
269290075Sobrien    }
269390075Sobrien
269490075Sobrien
269518334Speter  /* First do the subtraction as integers;
269650397Sobrien     then drop through to build the divide operator.
269750397Sobrien     Do not do default conversions on the minus operator
269850397Sobrien     in case restype is a short type.  */
269918334Speter
270018334Speter  op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
270150397Sobrien			 convert (restype, op1), 0);
270218334Speter  /* This generates an error if op1 is pointer to incomplete type.  */
270390075Sobrien  if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
270418334Speter    error ("arithmetic on pointer to an incomplete type");
270518334Speter
270618334Speter  /* This generates an error if op0 is pointer to incomplete type.  */
270718334Speter  op1 = c_size_in_bytes (target_type);
270818334Speter
270918334Speter  /* Divide by the size, in easiest possible way.  */
271018334Speter
271118334Speter  result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
271218334Speter
271318334Speter  folded = fold (result);
271418334Speter  if (folded == result)
271518334Speter    TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
271618334Speter  return folded;
271718334Speter}
271818334Speter
271918334Speter/* Construct and perhaps optimize a tree representation
272018334Speter   for a unary operation.  CODE, a tree_code, specifies the operation
272190075Sobrien   and XARG is the operand.
272290075Sobrien   For any CODE other than ADDR_EXPR, FLAG nonzero suppresses
272390075Sobrien   the default promotions (such as from short to int).
272490075Sobrien   For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
272590075Sobrien   allows non-lvalues; this is only used to handle conversion of non-lvalue
272690075Sobrien   arrays to pointers in C99.  */
272718334Speter
272818334Spetertree
272990075Sobrienbuild_unary_op (code, xarg, flag)
273018334Speter     enum tree_code code;
273118334Speter     tree xarg;
273290075Sobrien     int flag;
273318334Speter{
273418334Speter  /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
273590075Sobrien  tree arg = xarg;
273690075Sobrien  tree argtype = 0;
273790075Sobrien  enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
273818334Speter  tree val;
273990075Sobrien  int noconvert = flag;
274018334Speter
274118334Speter  if (typecode == ERROR_MARK)
274218334Speter    return error_mark_node;
274390075Sobrien  if (typecode == ENUMERAL_TYPE || typecode == BOOLEAN_TYPE)
274418334Speter    typecode = INTEGER_TYPE;
274518334Speter
274618334Speter  switch (code)
274718334Speter    {
274818334Speter    case CONVERT_EXPR:
274918334Speter      /* This is used for unary plus, because a CONVERT_EXPR
275018334Speter	 is enough to prevent anybody from looking inside for
275118334Speter	 associativity, but won't generate any code.  */
275218334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
275318334Speter	    || typecode == COMPLEX_TYPE))
275452284Sobrien	{
275552284Sobrien	  error ("wrong type argument to unary plus");
275652284Sobrien	  return error_mark_node;
275752284Sobrien	}
275818334Speter      else if (!noconvert)
275918334Speter	arg = default_conversion (arg);
276018334Speter      break;
276118334Speter
276218334Speter    case NEGATE_EXPR:
276318334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
276418334Speter	    || typecode == COMPLEX_TYPE))
276552284Sobrien	{
276652284Sobrien	  error ("wrong type argument to unary minus");
276752284Sobrien	  return error_mark_node;
276852284Sobrien	}
276918334Speter      else if (!noconvert)
277018334Speter	arg = default_conversion (arg);
277118334Speter      break;
277218334Speter
277318334Speter    case BIT_NOT_EXPR:
277418334Speter      if (typecode == COMPLEX_TYPE)
277518334Speter	{
277618334Speter	  code = CONJ_EXPR;
277790075Sobrien	  if (pedantic)
277890075Sobrien	    pedwarn ("ISO C does not support `~' for complex conjugation");
277918334Speter	  if (!noconvert)
278018334Speter	    arg = default_conversion (arg);
278118334Speter	}
278218334Speter      else if (typecode != INTEGER_TYPE)
278352284Sobrien	{
278452284Sobrien	  error ("wrong type argument to bit-complement");
278552284Sobrien	  return error_mark_node;
278652284Sobrien	}
278718334Speter      else if (!noconvert)
278818334Speter	arg = default_conversion (arg);
278918334Speter      break;
279018334Speter
279118334Speter    case ABS_EXPR:
279218334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
279318334Speter	    || typecode == COMPLEX_TYPE))
279452284Sobrien	{
279552284Sobrien	  error ("wrong type argument to abs");
279652284Sobrien	  return error_mark_node;
279752284Sobrien	}
279818334Speter      else if (!noconvert)
279918334Speter	arg = default_conversion (arg);
280018334Speter      break;
280118334Speter
280218334Speter    case CONJ_EXPR:
280318334Speter      /* Conjugating a real value is a no-op, but allow it anyway.  */
280418334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
280518334Speter	    || typecode == COMPLEX_TYPE))
280652284Sobrien	{
280752284Sobrien	  error ("wrong type argument to conjugation");
280852284Sobrien	  return error_mark_node;
280952284Sobrien	}
281018334Speter      else if (!noconvert)
281118334Speter	arg = default_conversion (arg);
281218334Speter      break;
281318334Speter
281418334Speter    case TRUTH_NOT_EXPR:
281518334Speter      if (typecode != INTEGER_TYPE
281618334Speter	  && typecode != REAL_TYPE && typecode != POINTER_TYPE
281718334Speter	  && typecode != COMPLEX_TYPE
281818334Speter	  /* These will convert to a pointer.  */
281918334Speter	  && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
282018334Speter	{
282152284Sobrien	  error ("wrong type argument to unary exclamation mark");
282252284Sobrien	  return error_mark_node;
282318334Speter	}
282418334Speter      arg = truthvalue_conversion (arg);
282518334Speter      return invert_truthvalue (arg);
282618334Speter
282718334Speter    case NOP_EXPR:
282818334Speter      break;
282918334Speter
283018334Speter    case REALPART_EXPR:
283118334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
283218334Speter	return TREE_REALPART (arg);
283318334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
283418334Speter	return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
283518334Speter      else
283618334Speter	return arg;
283718334Speter
283818334Speter    case IMAGPART_EXPR:
283918334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
284018334Speter	return TREE_IMAGPART (arg);
284118334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
284218334Speter	return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
284318334Speter      else
284418334Speter	return convert (TREE_TYPE (arg), integer_zero_node);
284518334Speter
284618334Speter    case PREINCREMENT_EXPR:
284718334Speter    case POSTINCREMENT_EXPR:
284818334Speter    case PREDECREMENT_EXPR:
284918334Speter    case POSTDECREMENT_EXPR:
285018334Speter      /* Handle complex lvalues (when permitted)
285118334Speter	 by reduction to simpler cases.  */
285218334Speter
285390075Sobrien      val = unary_complex_lvalue (code, arg, 0);
285418334Speter      if (val != 0)
285518334Speter	return val;
285618334Speter
285718334Speter      /* Increment or decrement the real part of the value,
285818334Speter	 and don't change the imaginary part.  */
285918334Speter      if (typecode == COMPLEX_TYPE)
286018334Speter	{
286118334Speter	  tree real, imag;
286218334Speter
286390075Sobrien	  if (pedantic)
286490075Sobrien	    pedwarn ("ISO C does not support `++' and `--' on complex types");
286590075Sobrien
286618334Speter	  arg = stabilize_reference (arg);
286718334Speter	  real = build_unary_op (REALPART_EXPR, arg, 1);
286818334Speter	  imag = build_unary_op (IMAGPART_EXPR, arg, 1);
286918334Speter	  return build (COMPLEX_EXPR, TREE_TYPE (arg),
287018334Speter			build_unary_op (code, real, 1), imag);
287118334Speter	}
287218334Speter
287318334Speter      /* Report invalid types.  */
287418334Speter
287518334Speter      if (typecode != POINTER_TYPE
287618334Speter	  && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
287718334Speter	{
287890075Sobrien	  if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
287990075Sobrien            error ("wrong type argument to increment");
288090075Sobrien          else
288190075Sobrien            error ("wrong type argument to decrement");
288290075Sobrien
288352284Sobrien	  return error_mark_node;
288418334Speter	}
288518334Speter
288618334Speter      {
288790075Sobrien	tree inc;
288818334Speter	tree result_type = TREE_TYPE (arg);
288918334Speter
289018334Speter	arg = get_unwidened (arg, 0);
289118334Speter	argtype = TREE_TYPE (arg);
289218334Speter
289318334Speter	/* Compute the increment.  */
289418334Speter
289518334Speter	if (typecode == POINTER_TYPE)
289618334Speter	  {
289718334Speter	    /* If pointer target is an undefined struct,
289818334Speter	       we just cannot know how to do the arithmetic.  */
289990075Sobrien	    if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
290090075Sobrien	      {
290190075Sobrien		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
290290075Sobrien		  error ("increment of pointer to unknown structure");
290390075Sobrien		else
290490075Sobrien		  error ("decrement of pointer to unknown structure");
290590075Sobrien	      }
290618334Speter	    else if ((pedantic || warn_pointer_arith)
290718334Speter		     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
290818334Speter			 || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
290990075Sobrien              {
291090075Sobrien		if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
291190075Sobrien		  pedwarn ("wrong type argument to increment");
291290075Sobrien		else
291390075Sobrien		  pedwarn ("wrong type argument to decrement");
291490075Sobrien	      }
291590075Sobrien
291618334Speter	    inc = c_size_in_bytes (TREE_TYPE (result_type));
291718334Speter	  }
291818334Speter	else
291918334Speter	  inc = integer_one_node;
292018334Speter
292118334Speter	inc = convert (argtype, inc);
292218334Speter
292318334Speter	/* Handle incrementing a cast-expression.  */
292418334Speter
292518334Speter	while (1)
292618334Speter	  switch (TREE_CODE (arg))
292718334Speter	    {
292818334Speter	    case NOP_EXPR:
292918334Speter	    case CONVERT_EXPR:
293018334Speter	    case FLOAT_EXPR:
293118334Speter	    case FIX_TRUNC_EXPR:
293218334Speter	    case FIX_FLOOR_EXPR:
293318334Speter	    case FIX_ROUND_EXPR:
293418334Speter	    case FIX_CEIL_EXPR:
293518334Speter	      pedantic_lvalue_warning (CONVERT_EXPR);
293618334Speter	      /* If the real type has the same machine representation
293718334Speter		 as the type it is cast to, we can make better output
293818334Speter		 by adding directly to the inside of the cast.  */
293918334Speter	      if ((TREE_CODE (TREE_TYPE (arg))
294018334Speter		   == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
294118334Speter		  && (TYPE_MODE (TREE_TYPE (arg))
294218334Speter		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
294318334Speter		arg = TREE_OPERAND (arg, 0);
294418334Speter	      else
294518334Speter		{
294618334Speter		  tree incremented, modify, value;
294790075Sobrien		  if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
294890075Sobrien		    value = boolean_increment (code, arg);
294918334Speter		  else
295090075Sobrien		    {
295190075Sobrien		      arg = stabilize_reference (arg);
295290075Sobrien		      if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
295390075Sobrien			value = arg;
295490075Sobrien		      else
295590075Sobrien			value = save_expr (arg);
295690075Sobrien		      incremented = build (((code == PREINCREMENT_EXPR
295790075Sobrien					     || code == POSTINCREMENT_EXPR)
295890075Sobrien					    ? PLUS_EXPR : MINUS_EXPR),
295990075Sobrien					   argtype, value, inc);
296090075Sobrien		      TREE_SIDE_EFFECTS (incremented) = 1;
296190075Sobrien		      modify = build_modify_expr (arg, NOP_EXPR, incremented);
296290075Sobrien		      value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
296390075Sobrien		    }
296418334Speter		  TREE_USED (value) = 1;
296518334Speter		  return value;
296618334Speter		}
296718334Speter	      break;
296818334Speter
296918334Speter	    default:
297018334Speter	      goto give_up;
297118334Speter	    }
297218334Speter      give_up:
297318334Speter
297418334Speter	/* Complain about anything else that is not a true lvalue.  */
297518334Speter	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
297618334Speter				    || code == POSTINCREMENT_EXPR)
297752284Sobrien				   ? "invalid lvalue in increment"
297852284Sobrien				   : "invalid lvalue in decrement")))
297918334Speter	  return error_mark_node;
298018334Speter
298118334Speter	/* Report a read-only lvalue.  */
298218334Speter	if (TREE_READONLY (arg))
298318334Speter	  readonly_warning (arg,
298418334Speter			    ((code == PREINCREMENT_EXPR
298518334Speter			      || code == POSTINCREMENT_EXPR)
298618334Speter			     ? "increment" : "decrement"));
298718334Speter
298890075Sobrien	if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
298990075Sobrien	  val = boolean_increment (code, arg);
299090075Sobrien	else
299190075Sobrien	  val = build (code, TREE_TYPE (arg), arg, inc);
299218334Speter	TREE_SIDE_EFFECTS (val) = 1;
299318334Speter	val = convert (result_type, val);
299418334Speter	if (TREE_CODE (val) != code)
299518334Speter	  TREE_NO_UNUSED_WARNING (val) = 1;
299618334Speter	return val;
299718334Speter      }
299818334Speter
299918334Speter    case ADDR_EXPR:
300090075Sobrien      /* Note that this operation never does default_conversion.  */
300118334Speter
300218334Speter      /* Let &* cancel out to simplify resulting code.  */
300318334Speter      if (TREE_CODE (arg) == INDIRECT_REF)
300418334Speter	{
300518334Speter	  /* Don't let this be an lvalue.  */
300618334Speter	  if (lvalue_p (TREE_OPERAND (arg, 0)))
300718334Speter	    return non_lvalue (TREE_OPERAND (arg, 0));
300818334Speter	  return TREE_OPERAND (arg, 0);
300918334Speter	}
301018334Speter
301118334Speter      /* For &x[y], return x+y */
301218334Speter      if (TREE_CODE (arg) == ARRAY_REF)
301318334Speter	{
301418334Speter	  if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
301518334Speter	    return error_mark_node;
301618334Speter	  return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
301718334Speter				  TREE_OPERAND (arg, 1), 1);
301818334Speter	}
301918334Speter
302018334Speter      /* Handle complex lvalues (when permitted)
302118334Speter	 by reduction to simpler cases.  */
302290075Sobrien      val = unary_complex_lvalue (code, arg, flag);
302318334Speter      if (val != 0)
302418334Speter	return val;
302518334Speter
302618334Speter#if 0 /* Turned off because inconsistent;
302718334Speter	 float f; *&(int)f = 3.4 stores in int format
302818334Speter	 whereas (int)f = 3.4 stores in float format.  */
302918334Speter      /* Address of a cast is just a cast of the address
303018334Speter	 of the operand of the cast.  */
303118334Speter      switch (TREE_CODE (arg))
303218334Speter	{
303318334Speter	case NOP_EXPR:
303418334Speter	case CONVERT_EXPR:
303518334Speter	case FLOAT_EXPR:
303618334Speter	case FIX_TRUNC_EXPR:
303718334Speter	case FIX_FLOOR_EXPR:
303818334Speter	case FIX_ROUND_EXPR:
303918334Speter	case FIX_CEIL_EXPR:
304018334Speter	  if (pedantic)
304190075Sobrien	    pedwarn ("ISO C forbids the address of a cast expression");
304218334Speter	  return convert (build_pointer_type (TREE_TYPE (arg)),
304318334Speter			  build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0),
304418334Speter					  0));
304518334Speter	}
304618334Speter#endif
304718334Speter
304818334Speter      /* Anything not already handled and not a true memory reference
304990075Sobrien	 or a non-lvalue array is an error.  */
305090075Sobrien      else if (typecode != FUNCTION_TYPE && !flag
305152284Sobrien	       && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
305218334Speter	return error_mark_node;
305318334Speter
305418334Speter      /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
305518334Speter      argtype = TREE_TYPE (arg);
305690075Sobrien
305752284Sobrien      /* If the lvalue is const or volatile, merge that into the type
305852284Sobrien         to which the address will point.  Note that you can't get a
305952284Sobrien	 restricted pointer by taking the address of something, so we
306052284Sobrien	 only have to deal with `const' and `volatile' here.  */
306190075Sobrien      if ((DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
306290075Sobrien	  && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)))
306390075Sobrien	  argtype = c_build_type_variant (argtype,
306490075Sobrien					  TREE_READONLY (arg),
306590075Sobrien					  TREE_THIS_VOLATILE (arg));
306618334Speter
306718334Speter      argtype = build_pointer_type (argtype);
306818334Speter
306918334Speter      if (mark_addressable (arg) == 0)
307018334Speter	return error_mark_node;
307118334Speter
307218334Speter      {
307318334Speter	tree addr;
307418334Speter
307518334Speter	if (TREE_CODE (arg) == COMPONENT_REF)
307618334Speter	  {
307718334Speter	    tree field = TREE_OPERAND (arg, 1);
307818334Speter
307990075Sobrien	    addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), flag);
308018334Speter
308150397Sobrien	    if (DECL_C_BIT_FIELD (field))
308218334Speter	      {
308318334Speter		error ("attempt to take address of bit-field structure member `%s'",
308418334Speter		       IDENTIFIER_POINTER (DECL_NAME (field)));
308518334Speter		return error_mark_node;
308618334Speter	      }
308718334Speter
308890075Sobrien	    addr = fold (build (PLUS_EXPR, argtype,
308990075Sobrien				convert (argtype, addr),
309090075Sobrien				convert (argtype, byte_position (field))));
309118334Speter	  }
309218334Speter	else
309318334Speter	  addr = build1 (code, argtype, arg);
309418334Speter
309518334Speter	/* Address of a static or external variable or
309618334Speter	   file-scope function counts as a constant.  */
309718334Speter	if (staticp (arg)
309818334Speter	    && ! (TREE_CODE (arg) == FUNCTION_DECL
309918334Speter		  && DECL_CONTEXT (arg) != 0))
310018334Speter	  TREE_CONSTANT (addr) = 1;
310118334Speter	return addr;
310218334Speter      }
310350397Sobrien
310450397Sobrien    default:
310550397Sobrien      break;
310618334Speter    }
310718334Speter
310852284Sobrien  if (argtype == 0)
310952284Sobrien    argtype = TREE_TYPE (arg);
311052284Sobrien  return fold (build1 (code, argtype, arg));
311118334Speter}
311218334Speter
311318334Speter#if 0
311418334Speter/* If CONVERSIONS is a conversion expression or a nested sequence of such,
311518334Speter   convert ARG with the same conversions in the same order
311618334Speter   and return the result.  */
311718334Speter
311818334Speterstatic tree
311918334Speterconvert_sequence (conversions, arg)
312018334Speter     tree conversions;
312118334Speter     tree arg;
312218334Speter{
312318334Speter  switch (TREE_CODE (conversions))
312418334Speter    {
312518334Speter    case NOP_EXPR:
312618334Speter    case CONVERT_EXPR:
312718334Speter    case FLOAT_EXPR:
312818334Speter    case FIX_TRUNC_EXPR:
312918334Speter    case FIX_FLOOR_EXPR:
313018334Speter    case FIX_ROUND_EXPR:
313118334Speter    case FIX_CEIL_EXPR:
313218334Speter      return convert (TREE_TYPE (conversions),
313318334Speter		      convert_sequence (TREE_OPERAND (conversions, 0),
313418334Speter					arg));
313518334Speter
313618334Speter    default:
313718334Speter      return arg;
313818334Speter    }
313918334Speter}
314018334Speter#endif /* 0 */
314118334Speter
314218334Speter/* Return nonzero if REF is an lvalue valid for this language.
314318334Speter   Lvalues can be assigned, unless their type has TYPE_READONLY.
314418334Speter   Lvalues can have their address taken, unless they have DECL_REGISTER.  */
314518334Speter
314618334Speterint
314718334Speterlvalue_p (ref)
314818334Speter     tree ref;
314918334Speter{
315090075Sobrien  enum tree_code code = TREE_CODE (ref);
315118334Speter
315218334Speter  switch (code)
315318334Speter    {
315418334Speter    case REALPART_EXPR:
315518334Speter    case IMAGPART_EXPR:
315618334Speter    case COMPONENT_REF:
315718334Speter      return lvalue_p (TREE_OPERAND (ref, 0));
315818334Speter
315990075Sobrien    case COMPOUND_LITERAL_EXPR:
316018334Speter    case STRING_CST:
316118334Speter      return 1;
316218334Speter
316318334Speter    case INDIRECT_REF:
316418334Speter    case ARRAY_REF:
316518334Speter    case VAR_DECL:
316618334Speter    case PARM_DECL:
316718334Speter    case RESULT_DECL:
316818334Speter    case ERROR_MARK:
316950397Sobrien      return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
317050397Sobrien	      && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
317150397Sobrien
317250397Sobrien    case BIND_EXPR:
317350397Sobrien    case RTL_EXPR:
317450397Sobrien      return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
317550397Sobrien
317650397Sobrien    default:
317750397Sobrien      return 0;
317818334Speter    }
317918334Speter}
318018334Speter
318118334Speter/* Return nonzero if REF is an lvalue valid for this language;
318218334Speter   otherwise, print an error message and return zero.  */
318318334Speter
318418334Speterint
318552284Sobrienlvalue_or_else (ref, msgid)
318618334Speter     tree ref;
318752284Sobrien     const char *msgid;
318818334Speter{
318918334Speter  int win = lvalue_p (ref);
319090075Sobrien
319118334Speter  if (! win)
319290075Sobrien    error ("%s", msgid);
319390075Sobrien
319418334Speter  return win;
319518334Speter}
319618334Speter
319718334Speter/* Apply unary lvalue-demanding operator CODE to the expression ARG
319818334Speter   for certain kinds of expressions which are not really lvalues
319990075Sobrien   but which we can accept as lvalues.  If FLAG is nonzero, then
320090075Sobrien   non-lvalues are OK since we may be converting a non-lvalue array to
320190075Sobrien   a pointer in C99.
320218334Speter
320318334Speter   If ARG is not a kind of expression we can handle, return zero.  */
320418334Speter
320518334Speterstatic tree
320690075Sobrienunary_complex_lvalue (code, arg, flag)
320718334Speter     enum tree_code code;
320818334Speter     tree arg;
320990075Sobrien     int flag;
321018334Speter{
321118334Speter  /* Handle (a, b) used as an "lvalue".  */
321218334Speter  if (TREE_CODE (arg) == COMPOUND_EXPR)
321318334Speter    {
321418334Speter      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
321550397Sobrien
321650397Sobrien      /* If this returns a function type, it isn't really being used as
321750397Sobrien	 an lvalue, so don't issue a warning about it.  */
321890075Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
321950397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
322050397Sobrien
322118334Speter      return build (COMPOUND_EXPR, TREE_TYPE (real_result),
322218334Speter		    TREE_OPERAND (arg, 0), real_result);
322318334Speter    }
322418334Speter
322518334Speter  /* Handle (a ? b : c) used as an "lvalue".  */
322618334Speter  if (TREE_CODE (arg) == COND_EXPR)
322718334Speter    {
322890075Sobrien      if (!flag)
322990075Sobrien	pedantic_lvalue_warning (COND_EXPR);
323090075Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag)
323150397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
323250397Sobrien
323318334Speter      return (build_conditional_expr
323418334Speter	      (TREE_OPERAND (arg, 0),
323590075Sobrien	       build_unary_op (code, TREE_OPERAND (arg, 1), flag),
323690075Sobrien	       build_unary_op (code, TREE_OPERAND (arg, 2), flag)));
323718334Speter    }
323818334Speter
323918334Speter  return 0;
324018334Speter}
324118334Speter
324218334Speter/* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
324318334Speter   COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
324418334Speter
324518334Speterstatic void
324618334Speterpedantic_lvalue_warning (code)
324718334Speter     enum tree_code code;
324818334Speter{
324918334Speter  if (pedantic)
325090075Sobrien    switch (code)
325190075Sobrien      {
325290075Sobrien      case COND_EXPR:
325390075Sobrien	pedwarn ("ISO C forbids use of conditional expressions as lvalues");
325490075Sobrien	break;
325590075Sobrien      case COMPOUND_EXPR:
325690075Sobrien	pedwarn ("ISO C forbids use of compound expressions as lvalues");
325790075Sobrien	break;
325890075Sobrien      default:
325990075Sobrien	pedwarn ("ISO C forbids use of cast expressions as lvalues");
326090075Sobrien	break;
326190075Sobrien      }
326218334Speter}
326318334Speter
326418334Speter/* Warn about storing in something that is `const'.  */
326518334Speter
326618334Spetervoid
326752284Sobrienreadonly_warning (arg, msgid)
326818334Speter     tree arg;
326952284Sobrien     const char *msgid;
327018334Speter{
327118334Speter  if (TREE_CODE (arg) == COMPONENT_REF)
327218334Speter    {
327318334Speter      if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
327452284Sobrien	readonly_warning (TREE_OPERAND (arg, 0), msgid);
327518334Speter      else
327652284Sobrien	pedwarn ("%s of read-only member `%s'", _(msgid),
327752284Sobrien		 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
327818334Speter    }
327918334Speter  else if (TREE_CODE (arg) == VAR_DECL)
328052284Sobrien    pedwarn ("%s of read-only variable `%s'", _(msgid),
328152284Sobrien	     IDENTIFIER_POINTER (DECL_NAME (arg)));
328218334Speter  else
328352284Sobrien    pedwarn ("%s of read-only location", _(msgid));
328418334Speter}
328518334Speter
328618334Speter/* Mark EXP saying that we need to be able to take the
328718334Speter   address of it; it should not be allocated in a register.
328818334Speter   Value is 1 if successful.  */
328918334Speter
329018334Speterint
329118334Spetermark_addressable (exp)
329218334Speter     tree exp;
329318334Speter{
329490075Sobrien  tree x = exp;
329518334Speter  while (1)
329618334Speter    switch (TREE_CODE (x))
329718334Speter      {
329850397Sobrien      case COMPONENT_REF:
329950397Sobrien	if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
330050397Sobrien	  {
330190075Sobrien	    error ("cannot take address of bit-field `%s'",
330250397Sobrien		   IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
330350397Sobrien	    return 0;
330450397Sobrien	  }
330550397Sobrien
330650397Sobrien	/* ... fall through ...  */
330750397Sobrien
330818334Speter      case ADDR_EXPR:
330918334Speter      case ARRAY_REF:
331018334Speter      case REALPART_EXPR:
331118334Speter      case IMAGPART_EXPR:
331218334Speter	x = TREE_OPERAND (x, 0);
331318334Speter	break;
331418334Speter
331590075Sobrien      case COMPOUND_LITERAL_EXPR:
331618334Speter      case CONSTRUCTOR:
331718334Speter	TREE_ADDRESSABLE (x) = 1;
331818334Speter	return 1;
331918334Speter
332018334Speter      case VAR_DECL:
332118334Speter      case CONST_DECL:
332218334Speter      case PARM_DECL:
332318334Speter      case RESULT_DECL:
332418334Speter	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
332518334Speter	    && DECL_NONLOCAL (x))
332618334Speter	  {
332718334Speter	    if (TREE_PUBLIC (x))
332818334Speter	      {
332918334Speter		error ("global register variable `%s' used in nested function",
333018334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
333118334Speter		return 0;
333218334Speter	      }
333318334Speter	    pedwarn ("register variable `%s' used in nested function",
333418334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
333518334Speter	  }
333618334Speter	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
333718334Speter	  {
333818334Speter	    if (TREE_PUBLIC (x))
333918334Speter	      {
334018334Speter		error ("address of global register variable `%s' requested",
334118334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
334218334Speter		return 0;
334318334Speter	      }
334418334Speter
334518334Speter	    /* If we are making this addressable due to its having
334618334Speter	       volatile components, give a different error message.  Also
334718334Speter	       handle the case of an unnamed parameter by not trying
334818334Speter	       to give the name.  */
334918334Speter
335018334Speter	    else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
335118334Speter	      {
335218334Speter		error ("cannot put object with volatile field into register");
335318334Speter		return 0;
335418334Speter	      }
335518334Speter
335618334Speter	    pedwarn ("address of register variable `%s' requested",
335718334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
335818334Speter	  }
335918334Speter	put_var_into_stack (x);
336018334Speter
336118334Speter	/* drops in */
336218334Speter      case FUNCTION_DECL:
336318334Speter	TREE_ADDRESSABLE (x) = 1;
336418334Speter#if 0  /* poplevel deals with this now.  */
336518334Speter	if (DECL_CONTEXT (x) == 0)
336618334Speter	  TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
336718334Speter#endif
336818334Speter
336918334Speter      default:
337018334Speter	return 1;
337118334Speter    }
337218334Speter}
337318334Speter
337418334Speter/* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
337518334Speter
337618334Spetertree
337718334Speterbuild_conditional_expr (ifexp, op1, op2)
337818334Speter     tree ifexp, op1, op2;
337918334Speter{
338090075Sobrien  tree type1;
338190075Sobrien  tree type2;
338290075Sobrien  enum tree_code code1;
338390075Sobrien  enum tree_code code2;
338490075Sobrien  tree result_type = NULL;
338518334Speter  tree orig_op1 = op1, orig_op2 = op2;
338618334Speter
338718334Speter  ifexp = truthvalue_conversion (default_conversion (ifexp));
338818334Speter
338918334Speter#if 0 /* Produces wrong result if within sizeof.  */
339018334Speter  /* Don't promote the operands separately if they promote
339118334Speter     the same way.  Return the unpromoted type and let the combined
339218334Speter     value get promoted if necessary.  */
339318334Speter
339418334Speter  if (TREE_TYPE (op1) == TREE_TYPE (op2)
339518334Speter      && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE
339618334Speter      && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE
339718334Speter      && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE)
339818334Speter    {
339918334Speter      if (TREE_CODE (ifexp) == INTEGER_CST)
340018334Speter	return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
340118334Speter
340218334Speter      return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2));
340318334Speter    }
340418334Speter#endif
340518334Speter
340618334Speter  /* Promote both alternatives.  */
340718334Speter
340818334Speter  if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
340918334Speter    op1 = default_conversion (op1);
341018334Speter  if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
341118334Speter    op2 = default_conversion (op2);
341218334Speter
341318334Speter  if (TREE_CODE (ifexp) == ERROR_MARK
341418334Speter      || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
341518334Speter      || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
341618334Speter    return error_mark_node;
341718334Speter
341818334Speter  type1 = TREE_TYPE (op1);
341918334Speter  code1 = TREE_CODE (type1);
342018334Speter  type2 = TREE_TYPE (op2);
342118334Speter  code2 = TREE_CODE (type2);
342218334Speter
342318334Speter  /* Quickly detect the usual case where op1 and op2 have the same type
342418334Speter     after promotion.  */
342518334Speter  if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
342618334Speter    {
342718334Speter      if (type1 == type2)
342818334Speter	result_type = type1;
342918334Speter      else
343018334Speter	result_type = TYPE_MAIN_VARIANT (type1);
343118334Speter    }
343290075Sobrien  else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE
343390075Sobrien            || code1 == COMPLEX_TYPE)
343490075Sobrien           && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
343590075Sobrien               || code2 == COMPLEX_TYPE))
343618334Speter    {
343718334Speter      result_type = common_type (type1, type2);
343890075Sobrien
343990075Sobrien      /* If -Wsign-compare, warn here if type1 and type2 have
344090075Sobrien	 different signedness.  We'll promote the signed to unsigned
344190075Sobrien	 and later code won't know it used to be different.
344290075Sobrien	 Do this check on the original types, so that explicit casts
344390075Sobrien	 will be considered, but default promotions won't.  */
344490075Sobrien      if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare)
344590075Sobrien	  && !skip_evaluation)
344690075Sobrien	{
344790075Sobrien	  int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1));
344890075Sobrien	  int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2));
344990075Sobrien
345090075Sobrien	  if (unsigned_op1 ^ unsigned_op2)
345190075Sobrien	    {
345290075Sobrien	      /* Do not warn if the result type is signed, since the
345390075Sobrien		 signed type will only be chosen if it can represent
345490075Sobrien		 all the values of the unsigned type.  */
345590075Sobrien	      if (! TREE_UNSIGNED (result_type))
345690075Sobrien		/* OK */;
345790075Sobrien	      /* Do not warn if the signed quantity is an unsuffixed
345890075Sobrien		 integer literal (or some static constant expression
345990075Sobrien		 involving such literals) and it is non-negative.  */
346090075Sobrien	      else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
346190075Sobrien		       || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
346290075Sobrien		/* OK */;
346390075Sobrien	      else
346490075Sobrien		warning ("signed and unsigned type in conditional expression");
346590075Sobrien	    }
346690075Sobrien	}
346718334Speter    }
346818334Speter  else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
346918334Speter    {
347018334Speter      if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
347190075Sobrien	pedwarn ("ISO C forbids conditional expr with only one void side");
347218334Speter      result_type = void_type_node;
347318334Speter    }
347418334Speter  else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
347518334Speter    {
347618334Speter      if (comp_target_types (type1, type2))
347718334Speter	result_type = common_type (type1, type2);
347818334Speter      else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
347918334Speter	       && TREE_CODE (orig_op1) != NOP_EXPR)
348018334Speter	result_type = qualify_type (type2, type1);
348118334Speter      else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node
348218334Speter	       && TREE_CODE (orig_op2) != NOP_EXPR)
348318334Speter	result_type = qualify_type (type1, type2);
348490075Sobrien      else if (VOID_TYPE_P (TREE_TYPE (type1)))
348518334Speter	{
348618334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
348790075Sobrien	    pedwarn ("ISO C forbids conditional expr between `void *' and function pointer");
348890075Sobrien	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
348990075Sobrien							  TREE_TYPE (type2)));
349018334Speter	}
349190075Sobrien      else if (VOID_TYPE_P (TREE_TYPE (type2)))
349218334Speter	{
349318334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
349490075Sobrien	    pedwarn ("ISO C forbids conditional expr between `void *' and function pointer");
349590075Sobrien	  result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
349690075Sobrien							  TREE_TYPE (type1)));
349718334Speter	}
349818334Speter      else
349918334Speter	{
350018334Speter	  pedwarn ("pointer type mismatch in conditional expression");
350118334Speter	  result_type = build_pointer_type (void_type_node);
350218334Speter	}
350318334Speter    }
350418334Speter  else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
350518334Speter    {
350618334Speter      if (! integer_zerop (op2))
350718334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
350818334Speter      else
350918334Speter	{
351018334Speter	  op2 = null_pointer_node;
351118334Speter	}
351218334Speter      result_type = type1;
351318334Speter    }
351418334Speter  else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
351518334Speter    {
351618334Speter      if (!integer_zerop (op1))
351718334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
351818334Speter      else
351918334Speter	{
352018334Speter	  op1 = null_pointer_node;
352118334Speter	}
352218334Speter      result_type = type2;
352318334Speter    }
352418334Speter
352518334Speter  if (!result_type)
352618334Speter    {
352718334Speter      if (flag_cond_mismatch)
352818334Speter	result_type = void_type_node;
352918334Speter      else
353018334Speter	{
353118334Speter	  error ("type mismatch in conditional expression");
353218334Speter	  return error_mark_node;
353318334Speter	}
353418334Speter    }
353518334Speter
353618334Speter  /* Merge const and volatile flags of the incoming types.  */
353718334Speter  result_type
353818334Speter    = build_type_variant (result_type,
353918334Speter			  TREE_READONLY (op1) || TREE_READONLY (op2),
354018334Speter			  TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
354118334Speter
354218334Speter  if (result_type != TREE_TYPE (op1))
354318334Speter    op1 = convert_and_check (result_type, op1);
354418334Speter  if (result_type != TREE_TYPE (op2))
354518334Speter    op2 = convert_and_check (result_type, op2);
354618334Speter
354718334Speter  if (TREE_CODE (ifexp) == INTEGER_CST)
354818334Speter    return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
354918334Speter
355018334Speter  return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
355118334Speter}
355218334Speter
355318334Speter/* Given a list of expressions, return a compound expression
355418334Speter   that performs them all and returns the value of the last of them.  */
355518334Speter
355618334Spetertree
355718334Speterbuild_compound_expr (list)
355818334Speter     tree list;
355918334Speter{
356018334Speter  return internal_build_compound_expr (list, TRUE);
356118334Speter}
356218334Speter
356318334Speterstatic tree
356418334Speterinternal_build_compound_expr (list, first_p)
356518334Speter     tree list;
356618334Speter     int first_p;
356718334Speter{
356890075Sobrien  tree rest;
356918334Speter
357018334Speter  if (TREE_CHAIN (list) == 0)
357118334Speter    {
357290075Sobrien      /* Convert arrays and functions to pointers when there
357390075Sobrien	 really is a comma operator.  */
357490075Sobrien      if (!first_p)
357590075Sobrien	TREE_VALUE (list)
357690075Sobrien	  = default_function_array_conversion (TREE_VALUE (list));
357790075Sobrien
357818334Speter#if 0 /* If something inside inhibited lvalueness, we should not override.  */
357918334Speter      /* Consider (x, y+0), which is not an lvalue since y+0 is not.  */
358018334Speter
358118334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
358218334Speter      if (TREE_CODE (list) == NON_LVALUE_EXPR)
358318334Speter	list = TREE_OPERAND (list, 0);
358418334Speter#endif
358518334Speter
358618334Speter      /* Don't let (0, 0) be null pointer constant.  */
358718334Speter      if (!first_p && integer_zerop (TREE_VALUE (list)))
358818334Speter	return non_lvalue (TREE_VALUE (list));
358918334Speter      return TREE_VALUE (list);
359018334Speter    }
359118334Speter
359218334Speter  rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
359318334Speter
359418334Speter  if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
359518334Speter    {
359618334Speter      /* The left-hand operand of a comma expression is like an expression
359718334Speter         statement: with -W or -Wunused, we should warn if it doesn't have
359818334Speter	 any side-effects, unless it was explicitly cast to (void).  */
359990075Sobrien      if ((extra_warnings || warn_unused_value)
360018334Speter           && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
360190075Sobrien                && VOID_TYPE_P (TREE_TYPE (TREE_VALUE (list)))))
360218334Speter        warning ("left-hand operand of comma expression has no effect");
360318334Speter
360418334Speter      /* When pedantic, a compound expression can be neither an lvalue
360518334Speter         nor an integer constant expression.  */
360618334Speter      if (! pedantic)
360718334Speter        return rest;
360818334Speter    }
360918334Speter
361018334Speter  /* With -Wunused, we should also warn if the left-hand operand does have
361118334Speter     side-effects, but computes a value which is not used.  For example, in
361218334Speter     `foo() + bar(), baz()' the result of the `+' operator is not used,
361318334Speter     so we should issue a warning.  */
361490075Sobrien  else if (warn_unused_value)
361518334Speter    warn_if_unused_value (TREE_VALUE (list));
361618334Speter
361718334Speter  return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
361818334Speter}
361918334Speter
362018334Speter/* Build an expression representing a cast to type TYPE of expression EXPR.  */
362118334Speter
362218334Spetertree
362318334Speterbuild_c_cast (type, expr)
362490075Sobrien     tree type;
362518334Speter     tree expr;
362618334Speter{
362790075Sobrien  tree value = expr;
362818334Speter
362918334Speter  if (type == error_mark_node || expr == error_mark_node)
363018334Speter    return error_mark_node;
363118334Speter  type = TYPE_MAIN_VARIANT (type);
363218334Speter
363318334Speter#if 0
363418334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
363518334Speter  if (TREE_CODE (value) == NON_LVALUE_EXPR)
363618334Speter    value = TREE_OPERAND (value, 0);
363718334Speter#endif
363818334Speter
363918334Speter  if (TREE_CODE (type) == ARRAY_TYPE)
364018334Speter    {
364118334Speter      error ("cast specifies array type");
364218334Speter      return error_mark_node;
364318334Speter    }
364418334Speter
364518334Speter  if (TREE_CODE (type) == FUNCTION_TYPE)
364618334Speter    {
364718334Speter      error ("cast specifies function type");
364818334Speter      return error_mark_node;
364918334Speter    }
365018334Speter
365190075Sobrien  if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
365218334Speter    {
365318334Speter      if (pedantic)
365418334Speter	{
365518334Speter	  if (TREE_CODE (type) == RECORD_TYPE
365618334Speter	      || TREE_CODE (type) == UNION_TYPE)
365790075Sobrien	    pedwarn ("ISO C forbids casting nonscalar to the same type");
365818334Speter	}
365918334Speter    }
366018334Speter  else if (TREE_CODE (type) == UNION_TYPE)
366118334Speter    {
366218334Speter      tree field;
366390075Sobrien      value = default_function_array_conversion (value);
366418334Speter
366518334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
366618334Speter	if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
366718334Speter		       TYPE_MAIN_VARIANT (TREE_TYPE (value))))
366818334Speter	  break;
366918334Speter
367018334Speter      if (field)
367118334Speter	{
367252284Sobrien	  const char *name;
367318334Speter	  tree t;
367418334Speter
367518334Speter	  if (pedantic)
367690075Sobrien	    pedwarn ("ISO C forbids casts to union type");
367718334Speter	  if (TYPE_NAME (type) != 0)
367818334Speter	    {
367918334Speter	      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
368018334Speter		name = IDENTIFIER_POINTER (TYPE_NAME (type));
368118334Speter	      else
368218334Speter		name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
368318334Speter	    }
368418334Speter	  else
368518334Speter	    name = "";
368618334Speter	  t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
368718334Speter					build_tree_list (field, value)),
368818334Speter			   0, 0);
368918334Speter	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
369018334Speter	  return t;
369118334Speter	}
369218334Speter      error ("cast to union type from type not present in union");
369318334Speter      return error_mark_node;
369418334Speter    }
369518334Speter  else
369618334Speter    {
369718334Speter      tree otype, ovalue;
369818334Speter
369918334Speter      /* If casting to void, avoid the error that would come
370018334Speter	 from default_conversion in the case of a non-lvalue array.  */
370118334Speter      if (type == void_type_node)
370218334Speter	return build1 (CONVERT_EXPR, type, value);
370318334Speter
370418334Speter      /* Convert functions and arrays to pointers,
370518334Speter	 but don't convert any other types.  */
370690075Sobrien      value = default_function_array_conversion (value);
370718334Speter      otype = TREE_TYPE (value);
370818334Speter
370918334Speter      /* Optionally warn about potentially worrisome casts.  */
371018334Speter
371118334Speter      if (warn_cast_qual
371218334Speter	  && TREE_CODE (type) == POINTER_TYPE
371318334Speter	  && TREE_CODE (otype) == POINTER_TYPE)
371418334Speter	{
371550397Sobrien	  tree in_type = type;
371650397Sobrien	  tree in_otype = otype;
371796263Sobrien	  int added = 0;
371896263Sobrien	  int discarded = 0;
371950397Sobrien
372090075Sobrien	  /* Check that the qualifiers on IN_TYPE are a superset of
372190075Sobrien	     the qualifiers of IN_OTYPE.  The outermost level of
372290075Sobrien	     POINTER_TYPE nodes is uninteresting and we stop as soon
372390075Sobrien	     as we hit a non-POINTER_TYPE node on either type.  */
372490075Sobrien	  do
372590075Sobrien	    {
372690075Sobrien	      in_otype = TREE_TYPE (in_otype);
372790075Sobrien	      in_type = TREE_TYPE (in_type);
372896263Sobrien
372996263Sobrien	      /* GNU C allows cv-qualified function types.  'const'
373096263Sobrien		 means the function is very pure, 'volatile' means it
373196263Sobrien		 can't return.  We need to warn when such qualifiers
373296263Sobrien		 are added, not when they're taken away.  */
373396263Sobrien	      if (TREE_CODE (in_otype) == FUNCTION_TYPE
373496263Sobrien		  && TREE_CODE (in_type) == FUNCTION_TYPE)
373596263Sobrien		added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
373696263Sobrien	      else
373796263Sobrien		discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
373890075Sobrien	    }
373990075Sobrien	  while (TREE_CODE (in_type) == POINTER_TYPE
374090075Sobrien		 && TREE_CODE (in_otype) == POINTER_TYPE);
374190075Sobrien
374296263Sobrien	  if (added)
374396263Sobrien	    warning ("cast adds new qualifiers to function type");
374496263Sobrien
374596263Sobrien	  if (discarded)
374652284Sobrien	    /* There are qualifiers present in IN_OTYPE that are not
374752284Sobrien	       present in IN_TYPE.  */
374890075Sobrien	    warning ("cast discards qualifiers from pointer target type");
374918334Speter	}
375018334Speter
375118334Speter      /* Warn about possible alignment problems.  */
375218334Speter      if (STRICT_ALIGNMENT && warn_cast_align
375318334Speter	  && TREE_CODE (type) == POINTER_TYPE
375418334Speter	  && TREE_CODE (otype) == POINTER_TYPE
375518334Speter	  && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
375618334Speter	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
375750397Sobrien	  /* Don't warn about opaque types, where the actual alignment
375850397Sobrien	     restriction is unknown.  */
375950397Sobrien	  && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
376050397Sobrien		|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
376150397Sobrien	       && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
376218334Speter	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
376318334Speter	warning ("cast increases required alignment of target type");
376418334Speter
376518334Speter      if (TREE_CODE (type) == INTEGER_TYPE
376618334Speter	  && TREE_CODE (otype) == POINTER_TYPE
376718334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
376818334Speter	  && !TREE_CONSTANT (value))
376918334Speter	warning ("cast from pointer to integer of different size");
377018334Speter
377118334Speter      if (warn_bad_function_cast
377218334Speter	  && TREE_CODE (value) == CALL_EXPR
377318334Speter	  && TREE_CODE (type) != TREE_CODE (otype))
377418334Speter	warning ("cast does not match function type");
377518334Speter
377618334Speter      if (TREE_CODE (type) == POINTER_TYPE
377718334Speter	  && TREE_CODE (otype) == INTEGER_TYPE
377818334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
377918334Speter	  /* Don't warn about converting any constant.  */
378018334Speter	  && !TREE_CONSTANT (value))
378118334Speter	warning ("cast to pointer from integer of different size");
378218334Speter
378318334Speter      ovalue = value;
378418334Speter      value = convert (type, value);
378518334Speter
378618334Speter      /* Ignore any integer overflow caused by the cast.  */
378718334Speter      if (TREE_CODE (value) == INTEGER_CST)
378818334Speter	{
378918334Speter	  TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
379018334Speter	  TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
379118334Speter	}
379218334Speter    }
379318334Speter
379490075Sobrien  /* Pedantically, don't let (void *) (FOO *) 0 be a null pointer constant.  */
379518334Speter  if (pedantic && TREE_CODE (value) == INTEGER_CST
379618334Speter      && TREE_CODE (expr) == INTEGER_CST
379718334Speter      && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
379818334Speter    value = non_lvalue (value);
379918334Speter
380018334Speter  /* If pedantic, don't let a cast be an lvalue.  */
380118334Speter  if (value == expr && pedantic)
380218334Speter    value = non_lvalue (value);
380318334Speter
380418334Speter  return value;
380518334Speter}
380690075Sobrien
380790075Sobrien/* Interpret a cast of expression EXPR to type TYPE.  */
380890075Sobrientree
380990075Sobrienc_cast_expr (type, expr)
381090075Sobrien     tree type, expr;
381190075Sobrien{
381290075Sobrien  int saved_wsp = warn_strict_prototypes;
381390075Sobrien
381490075Sobrien  /* This avoids warnings about unprototyped casts on
381590075Sobrien     integers.  E.g. "#define SIG_DFL (void(*)())0".  */
381690075Sobrien  if (TREE_CODE (expr) == INTEGER_CST)
381790075Sobrien    warn_strict_prototypes = 0;
381890075Sobrien  type = groktypename (type);
381990075Sobrien  warn_strict_prototypes = saved_wsp;
382090075Sobrien
382190075Sobrien  return build_c_cast (type, expr);
382290075Sobrien}
382390075Sobrien
382418334Speter
382518334Speter/* Build an assignment expression of lvalue LHS from value RHS.
382618334Speter   MODIFYCODE is the code for a binary operator that we use
382718334Speter   to combine the old value of LHS with RHS to get the new value.
382818334Speter   Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.  */
382918334Speter
383018334Spetertree
383118334Speterbuild_modify_expr (lhs, modifycode, rhs)
383218334Speter     tree lhs, rhs;
383318334Speter     enum tree_code modifycode;
383418334Speter{
383590075Sobrien  tree result;
383618334Speter  tree newrhs;
383718334Speter  tree lhstype = TREE_TYPE (lhs);
383818334Speter  tree olhstype = lhstype;
383918334Speter
384018334Speter  /* Types that aren't fully specified cannot be used in assignments.  */
384118334Speter  lhs = require_complete_type (lhs);
384218334Speter
384318334Speter  /* Avoid duplicate error messages from operands that had errors.  */
384418334Speter  if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
384518334Speter    return error_mark_node;
384618334Speter
384718334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
384818334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
384918334Speter     whose value is 0 to count as a null pointer constant.  */
385018334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
385118334Speter    rhs = TREE_OPERAND (rhs, 0);
385218334Speter
385318334Speter  newrhs = rhs;
385418334Speter
385518334Speter  /* Handle control structure constructs used as "lvalues".  */
385618334Speter
385718334Speter  switch (TREE_CODE (lhs))
385818334Speter    {
385918334Speter      /* Handle (a, b) used as an "lvalue".  */
386018334Speter    case COMPOUND_EXPR:
386118334Speter      pedantic_lvalue_warning (COMPOUND_EXPR);
386290075Sobrien      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs);
386318334Speter      if (TREE_CODE (newrhs) == ERROR_MARK)
386418334Speter	return error_mark_node;
386518334Speter      return build (COMPOUND_EXPR, lhstype,
386618334Speter		    TREE_OPERAND (lhs, 0), newrhs);
386718334Speter
386818334Speter      /* Handle (a ? b : c) used as an "lvalue".  */
386918334Speter    case COND_EXPR:
387018334Speter      pedantic_lvalue_warning (COND_EXPR);
387118334Speter      rhs = save_expr (rhs);
387218334Speter      {
387318334Speter	/* Produce (a ? (b = rhs) : (c = rhs))
387418334Speter	   except that the RHS goes through a save-expr
387518334Speter	   so the code to compute it is only emitted once.  */
387618334Speter	tree cond
387718334Speter	  = build_conditional_expr (TREE_OPERAND (lhs, 0),
387818334Speter				    build_modify_expr (TREE_OPERAND (lhs, 1),
387918334Speter						       modifycode, rhs),
388018334Speter				    build_modify_expr (TREE_OPERAND (lhs, 2),
388118334Speter						       modifycode, rhs));
388218334Speter	if (TREE_CODE (cond) == ERROR_MARK)
388318334Speter	  return cond;
388418334Speter	/* Make sure the code to compute the rhs comes out
388518334Speter	   before the split.  */
388618334Speter	return build (COMPOUND_EXPR, TREE_TYPE (lhs),
388718334Speter		      /* But cast it to void to avoid an "unused" error.  */
388818334Speter		      convert (void_type_node, rhs), cond);
388918334Speter      }
389050397Sobrien    default:
389150397Sobrien      break;
389218334Speter    }
389318334Speter
389418334Speter  /* If a binary op has been requested, combine the old LHS value with the RHS
389518334Speter     producing the value we should actually store into the LHS.  */
389618334Speter
389718334Speter  if (modifycode != NOP_EXPR)
389818334Speter    {
389918334Speter      lhs = stabilize_reference (lhs);
390018334Speter      newrhs = build_binary_op (modifycode, lhs, rhs, 1);
390118334Speter    }
390218334Speter
390318334Speter  /* Handle a cast used as an "lvalue".
390418334Speter     We have already performed any binary operator using the value as cast.
390518334Speter     Now convert the result to the cast type of the lhs,
390618334Speter     and then true type of the lhs and store it there;
390718334Speter     then convert result back to the cast type to be the value
390818334Speter     of the assignment.  */
390918334Speter
391018334Speter  switch (TREE_CODE (lhs))
391118334Speter    {
391218334Speter    case NOP_EXPR:
391318334Speter    case CONVERT_EXPR:
391418334Speter    case FLOAT_EXPR:
391518334Speter    case FIX_TRUNC_EXPR:
391618334Speter    case FIX_FLOOR_EXPR:
391718334Speter    case FIX_ROUND_EXPR:
391818334Speter    case FIX_CEIL_EXPR:
391990075Sobrien      newrhs = default_function_array_conversion (newrhs);
392018334Speter      {
392118334Speter	tree inner_lhs = TREE_OPERAND (lhs, 0);
392218334Speter	tree result;
392318334Speter	result = build_modify_expr (inner_lhs, NOP_EXPR,
392418334Speter				    convert (TREE_TYPE (inner_lhs),
392518334Speter					     convert (lhstype, newrhs)));
392618334Speter	if (TREE_CODE (result) == ERROR_MARK)
392718334Speter	  return result;
392818334Speter	pedantic_lvalue_warning (CONVERT_EXPR);
392918334Speter	return convert (TREE_TYPE (lhs), result);
393018334Speter      }
393150397Sobrien
393250397Sobrien    default:
393350397Sobrien      break;
393418334Speter    }
393518334Speter
393618334Speter  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
393718334Speter     Reject anything strange now.  */
393818334Speter
393952284Sobrien  if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
394018334Speter    return error_mark_node;
394118334Speter
394218334Speter  /* Warn about storing in something that is `const'.  */
394318334Speter
394418334Speter  if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
394518334Speter      || ((TREE_CODE (lhstype) == RECORD_TYPE
394618334Speter	   || TREE_CODE (lhstype) == UNION_TYPE)
394718334Speter	  && C_TYPE_FIELDS_READONLY (lhstype)))
394818334Speter    readonly_warning (lhs, "assignment");
394918334Speter
395018334Speter  /* If storing into a structure or union member,
395118334Speter     it has probably been given type `int'.
395218334Speter     Compute the type that would go with
395318334Speter     the actual amount of storage the member occupies.  */
395418334Speter
395518334Speter  if (TREE_CODE (lhs) == COMPONENT_REF
395618334Speter      && (TREE_CODE (lhstype) == INTEGER_TYPE
395790075Sobrien	  || TREE_CODE (lhstype) == BOOLEAN_TYPE
395818334Speter	  || TREE_CODE (lhstype) == REAL_TYPE
395918334Speter	  || TREE_CODE (lhstype) == ENUMERAL_TYPE))
396018334Speter    lhstype = TREE_TYPE (get_unwidened (lhs, 0));
396118334Speter
396218334Speter  /* If storing in a field that is in actuality a short or narrower than one,
396318334Speter     we must store in the field in its actual type.  */
396418334Speter
396518334Speter  if (lhstype != TREE_TYPE (lhs))
396618334Speter    {
396718334Speter      lhs = copy_node (lhs);
396818334Speter      TREE_TYPE (lhs) = lhstype;
396918334Speter    }
397018334Speter
397118334Speter  /* Convert new value to destination type.  */
397218334Speter
397352284Sobrien  newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
397418334Speter				   NULL_TREE, NULL_TREE, 0);
397518334Speter  if (TREE_CODE (newrhs) == ERROR_MARK)
397618334Speter    return error_mark_node;
397718334Speter
397890075Sobrien  /* Scan operands */
397990075Sobrien
398018334Speter  result = build (MODIFY_EXPR, lhstype, lhs, newrhs);
398118334Speter  TREE_SIDE_EFFECTS (result) = 1;
398218334Speter
398318334Speter  /* If we got the LHS in a different type for storing in,
398418334Speter     convert the result back to the nominal type of LHS
398518334Speter     so that the value we return always has the same type
398618334Speter     as the LHS argument.  */
398718334Speter
398818334Speter  if (olhstype == TREE_TYPE (result))
398918334Speter    return result;
399052284Sobrien  return convert_for_assignment (olhstype, result, _("assignment"),
399118334Speter				 NULL_TREE, NULL_TREE, 0);
399218334Speter}
399318334Speter
399418334Speter/* Convert value RHS to type TYPE as preparation for an assignment
399518334Speter   to an lvalue of type TYPE.
399618334Speter   The real work of conversion is done by `convert'.
399718334Speter   The purpose of this function is to generate error messages
399818334Speter   for assignments that are not allowed in C.
399918334Speter   ERRTYPE is a string to use in error messages:
400018334Speter   "assignment", "return", etc.  If it is null, this is parameter passing
400152284Sobrien   for a function call (and different error messages are output).
400218334Speter
400318334Speter   FUNNAME is the name of the function being called,
400418334Speter   as an IDENTIFIER_NODE, or null.
400518334Speter   PARMNUM is the number of the argument, for printing in error messages.  */
400618334Speter
400718334Speterstatic tree
400818334Speterconvert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
400918334Speter     tree type, rhs;
401052284Sobrien     const char *errtype;
401118334Speter     tree fundecl, funname;
401218334Speter     int parmnum;
401318334Speter{
401490075Sobrien  enum tree_code codel = TREE_CODE (type);
401590075Sobrien  tree rhstype;
401690075Sobrien  enum tree_code coder;
401718334Speter
401818334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
401918334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
402018334Speter     whose value is 0 to count as a null pointer constant.  */
402118334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
402218334Speter    rhs = TREE_OPERAND (rhs, 0);
402318334Speter
402418334Speter  if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
402518334Speter      || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE)
402618334Speter    rhs = default_conversion (rhs);
402718334Speter  else if (optimize && TREE_CODE (rhs) == VAR_DECL)
402890075Sobrien    rhs = decl_constant_value_for_broken_optimization (rhs);
402918334Speter
403018334Speter  rhstype = TREE_TYPE (rhs);
403118334Speter  coder = TREE_CODE (rhstype);
403218334Speter
403318334Speter  if (coder == ERROR_MARK)
403418334Speter    return error_mark_node;
403518334Speter
403618334Speter  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
403718334Speter    {
403818334Speter      overflow_warning (rhs);
403918334Speter      /* Check for Objective-C protocols.  This will issue a warning if
404018334Speter	 there are protocol violations.  No need to use the return value.  */
404118334Speter      maybe_objc_comptypes (type, rhstype, 0);
404218334Speter      return rhs;
404318334Speter    }
404418334Speter
404518334Speter  if (coder == VOID_TYPE)
404618334Speter    {
404718334Speter      error ("void value not ignored as it ought to be");
404818334Speter      return error_mark_node;
404918334Speter    }
405090075Sobrien  /* A type converts to a reference to it.
405190075Sobrien     This code doesn't fully support references, it's just for the
405290075Sobrien     special case of va_start and va_copy.  */
405390075Sobrien  if (codel == REFERENCE_TYPE
405490075Sobrien      && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
405590075Sobrien    {
405690075Sobrien      if (mark_addressable (rhs) == 0)
405790075Sobrien	return error_mark_node;
405890075Sobrien      rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
405990075Sobrien
406090075Sobrien      /* We already know that these two types are compatible, but they
406190075Sobrien	 may not be exactly identical.  In fact, `TREE_TYPE (type)' is
406290075Sobrien	 likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
406390075Sobrien	 likely to be va_list, a typedef to __builtin_va_list, which
406490075Sobrien	 is different enough that it will cause problems later.  */
406590075Sobrien      if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
406690075Sobrien	rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
406790075Sobrien
406890075Sobrien      rhs = build1 (NOP_EXPR, type, rhs);
406990075Sobrien      return rhs;
407090075Sobrien    }
407118334Speter  /* Arithmetic types all interconvert, and enum is treated like int.  */
407290075Sobrien  else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
407390075Sobrien	    || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
407490075Sobrien	    || codel == BOOLEAN_TYPE)
407590075Sobrien	   && (coder == INTEGER_TYPE || coder == REAL_TYPE
407690075Sobrien	       || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
407790075Sobrien	       || coder == BOOLEAN_TYPE))
407818334Speter    return convert_and_check (type, rhs);
407918334Speter
408050397Sobrien  /* Conversion to a transparent union from its member types.
408150397Sobrien     This applies only to function arguments.  */
408250397Sobrien  else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype)
408318334Speter    {
408418334Speter      tree memb_types;
408550397Sobrien      tree marginal_memb_type = 0;
408618334Speter
408718334Speter      for (memb_types = TYPE_FIELDS (type); memb_types;
408818334Speter	   memb_types = TREE_CHAIN (memb_types))
408918334Speter	{
409050397Sobrien	  tree memb_type = TREE_TYPE (memb_types);
409118334Speter
409250397Sobrien	  if (comptypes (TYPE_MAIN_VARIANT (memb_type),
409350397Sobrien			 TYPE_MAIN_VARIANT (rhstype)))
409450397Sobrien	    break;
409550397Sobrien
409650397Sobrien	  if (TREE_CODE (memb_type) != POINTER_TYPE)
409750397Sobrien	    continue;
409850397Sobrien
409950397Sobrien	  if (coder == POINTER_TYPE)
410018334Speter	    {
410190075Sobrien	      tree ttl = TREE_TYPE (memb_type);
410290075Sobrien	      tree ttr = TREE_TYPE (rhstype);
410318334Speter
410418334Speter	      /* Any non-function converts to a [const][volatile] void *
410518334Speter		 and vice versa; otherwise, targets must be the same.
410618334Speter		 Meanwhile, the lhs target must have all the qualifiers of
410718334Speter		 the rhs.  */
410890075Sobrien	      if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
410918334Speter		  || comp_target_types (memb_type, rhstype))
411018334Speter		{
411150397Sobrien		  /* If this type won't generate any warnings, use it.  */
411252284Sobrien		  if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
411352284Sobrien		      || ((TREE_CODE (ttr) == FUNCTION_TYPE
411452284Sobrien			   && TREE_CODE (ttl) == FUNCTION_TYPE)
411552284Sobrien			  ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
411652284Sobrien			     == TYPE_QUALS (ttr))
411752284Sobrien			  : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
411852284Sobrien			     == TYPE_QUALS (ttl))))
411950397Sobrien		    break;
412018334Speter
412150397Sobrien		  /* Keep looking for a better type, but remember this one.  */
412250397Sobrien		  if (! marginal_memb_type)
412350397Sobrien		    marginal_memb_type = memb_type;
412418334Speter		}
412518334Speter	    }
412618334Speter
412718334Speter	  /* Can convert integer zero to any pointer type.  */
412850397Sobrien	  if (integer_zerop (rhs)
412950397Sobrien	      || (TREE_CODE (rhs) == NOP_EXPR
413050397Sobrien		  && integer_zerop (TREE_OPERAND (rhs, 0))))
413150397Sobrien	    {
413250397Sobrien	      rhs = null_pointer_node;
413350397Sobrien	      break;
413450397Sobrien	    }
413518334Speter	}
413650397Sobrien
413750397Sobrien      if (memb_types || marginal_memb_type)
413850397Sobrien	{
413950397Sobrien	  if (! memb_types)
414050397Sobrien	    {
414150397Sobrien	      /* We have only a marginally acceptable member type;
414250397Sobrien		 it needs a warning.  */
414390075Sobrien	      tree ttl = TREE_TYPE (marginal_memb_type);
414490075Sobrien	      tree ttr = TREE_TYPE (rhstype);
414550397Sobrien
414650397Sobrien	      /* Const and volatile mean something different for function
414750397Sobrien		 types, so the usual warnings are not appropriate.  */
414850397Sobrien	      if (TREE_CODE (ttr) == FUNCTION_TYPE
414950397Sobrien		  && TREE_CODE (ttl) == FUNCTION_TYPE)
415050397Sobrien		{
415150397Sobrien		  /* Because const and volatile on functions are
415250397Sobrien		     restrictions that say the function will not do
415350397Sobrien		     certain things, it is okay to use a const or volatile
415450397Sobrien		     function where an ordinary one is wanted, but not
415550397Sobrien		     vice-versa.  */
415652284Sobrien		  if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
415752284Sobrien		    warn_for_assignment ("%s makes qualified function pointer from unqualified",
415852284Sobrien					 errtype, funname, parmnum);
415950397Sobrien		}
416052284Sobrien	      else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
416152284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
416252284Sobrien				     errtype, funname,
416352284Sobrien				     parmnum);
416450397Sobrien	    }
416550397Sobrien
416650397Sobrien	  if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
416790075Sobrien	    pedwarn ("ISO C prohibits argument conversion to union type");
416850397Sobrien
416950397Sobrien	  return build1 (NOP_EXPR, type, rhs);
417050397Sobrien	}
417118334Speter    }
417218334Speter
417318334Speter  /* Conversions among pointers */
417490075Sobrien  else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
417590075Sobrien	   && (coder == POINTER_TYPE || coder == REFERENCE_TYPE))
417618334Speter    {
417790075Sobrien      tree ttl = TREE_TYPE (type);
417890075Sobrien      tree ttr = TREE_TYPE (rhstype);
417918334Speter
418018334Speter      /* Any non-function converts to a [const][volatile] void *
418118334Speter	 and vice versa; otherwise, targets must be the same.
418218334Speter	 Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
418390075Sobrien      if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
418418334Speter	  || comp_target_types (type, rhstype)
418518334Speter	  || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
418618334Speter	      == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
418718334Speter	{
418818334Speter	  if (pedantic
418990075Sobrien	      && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
419018334Speter		  ||
419190075Sobrien		  (VOID_TYPE_P (ttr)
419218334Speter		   /* Check TREE_CODE to catch cases like (void *) (char *) 0
419318334Speter		      which are not ANSI null ptr constants.  */
419418334Speter		   && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
419518334Speter		   && TREE_CODE (ttl) == FUNCTION_TYPE)))
419690075Sobrien	    warn_for_assignment ("ISO C forbids %s between function pointer and `void *'",
419752284Sobrien				 errtype, funname, parmnum);
419818334Speter	  /* Const and volatile mean something different for function types,
419918334Speter	     so the usual warnings are not appropriate.  */
420018334Speter	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
420118334Speter		   && TREE_CODE (ttl) != FUNCTION_TYPE)
420218334Speter	    {
420352284Sobrien	      if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
420452284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
420552284Sobrien				     errtype, funname, parmnum);
420618334Speter	      /* If this is not a case of ignoring a mismatch in signedness,
420718334Speter		 no warning.  */
420890075Sobrien	      else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
420918334Speter		       || comp_target_types (type, rhstype))
421018334Speter		;
421118334Speter	      /* If there is a mismatch, do warn.  */
421218334Speter	      else if (pedantic)
421318334Speter		warn_for_assignment ("pointer targets in %s differ in signedness",
421452284Sobrien				     errtype, funname, parmnum);
421518334Speter	    }
421618334Speter	  else if (TREE_CODE (ttl) == FUNCTION_TYPE
421718334Speter		   && TREE_CODE (ttr) == FUNCTION_TYPE)
421818334Speter	    {
421918334Speter	      /* Because const and volatile on functions are restrictions
422018334Speter		 that say the function will not do certain things,
422118334Speter		 it is okay to use a const or volatile function
422218334Speter		 where an ordinary one is wanted, but not vice-versa.  */
422352284Sobrien	      if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
422452284Sobrien		warn_for_assignment ("%s makes qualified function pointer from unqualified",
422552284Sobrien				     errtype, funname, parmnum);
422618334Speter	    }
422718334Speter	}
422818334Speter      else
422918334Speter	warn_for_assignment ("%s from incompatible pointer type",
423052284Sobrien			     errtype, funname, parmnum);
423118334Speter      return convert (type, rhs);
423218334Speter    }
423318334Speter  else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
423418334Speter    {
423518334Speter      /* An explicit constant 0 can convert to a pointer,
423618334Speter	 or one that results from arithmetic, even including
423718334Speter	 a cast to integer type.  */
423818334Speter      if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))
423918334Speter	  &&
424018334Speter	  ! (TREE_CODE (rhs) == NOP_EXPR
424118334Speter	     && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
424218334Speter	     && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
424318334Speter	     && integer_zerop (TREE_OPERAND (rhs, 0))))
424418334Speter	{
424518334Speter	  warn_for_assignment ("%s makes pointer from integer without a cast",
424652284Sobrien			       errtype, funname, parmnum);
424718334Speter	  return convert (type, rhs);
424818334Speter	}
424918334Speter      return null_pointer_node;
425018334Speter    }
425118334Speter  else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
425218334Speter    {
425318334Speter      warn_for_assignment ("%s makes integer from pointer without a cast",
425452284Sobrien			   errtype, funname, parmnum);
425518334Speter      return convert (type, rhs);
425618334Speter    }
425790075Sobrien  else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE)
425890075Sobrien    return convert (type, rhs);
425918334Speter
426018334Speter  if (!errtype)
426118334Speter    {
426218334Speter      if (funname)
426318334Speter 	{
426418334Speter 	  tree selector = maybe_building_objc_message_expr ();
426518334Speter
426618334Speter 	  if (selector && parmnum > 2)
426718334Speter 	    error ("incompatible type for argument %d of `%s'",
426818334Speter		   parmnum - 2, IDENTIFIER_POINTER (selector));
426918334Speter 	  else
427018334Speter	    error ("incompatible type for argument %d of `%s'",
427118334Speter		   parmnum, IDENTIFIER_POINTER (funname));
427218334Speter	}
427318334Speter      else
427418334Speter	error ("incompatible type for argument %d of indirect function call",
427518334Speter	       parmnum);
427618334Speter    }
427718334Speter  else
427852284Sobrien    error ("incompatible types in %s", errtype);
427918334Speter
428018334Speter  return error_mark_node;
428118334Speter}
428218334Speter
428396263Sobrien/* Convert VALUE for assignment into inlined parameter PARM.  */
428496263Sobrien
428596263Sobrientree
428696263Sobrienc_convert_parm_for_inlining (parm, value, fn)
428796263Sobrien     tree parm, value, fn;
428896263Sobrien{
428996263Sobrien  tree ret, type;
429096263Sobrien
429196263Sobrien  /* If FN was prototyped, the value has been converted already
429296263Sobrien     in convert_arguments.  */
429396263Sobrien  if (! value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
429496263Sobrien    return value;
429596263Sobrien
429696263Sobrien  type = TREE_TYPE (parm);
429796263Sobrien  ret = convert_for_assignment (type, value,
429896263Sobrien				(char *) 0 /* arg passing  */, fn,
429996263Sobrien				DECL_NAME (fn), 0);
430096263Sobrien  if (PROMOTE_PROTOTYPES
430196263Sobrien      && INTEGRAL_TYPE_P (type)
430296263Sobrien      && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
430396263Sobrien    ret = default_conversion (ret);
430496263Sobrien  return ret;
430596263Sobrien}
430696263Sobrien
430752284Sobrien/* Print a warning using MSGID.
430818334Speter   It gets OPNAME as its one parameter.
430918334Speter   If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
431018334Speter   FUNCTION and ARGNUM are handled specially if we are building an
431118334Speter   Objective-C selector.  */
431218334Speter
431318334Speterstatic void
431452284Sobrienwarn_for_assignment (msgid, opname, function, argnum)
431552284Sobrien     const char *msgid;
431652284Sobrien     const char *opname;
431718334Speter     tree function;
431818334Speter     int argnum;
431918334Speter{
432018334Speter  if (opname == 0)
432118334Speter    {
432218334Speter      tree selector = maybe_building_objc_message_expr ();
432352284Sobrien      char * new_opname;
432418334Speter
432518334Speter      if (selector && argnum > 2)
432618334Speter	{
432718334Speter	  function = selector;
432818334Speter	  argnum -= 2;
432918334Speter	}
433018334Speter      if (function)
433118334Speter	{
433218334Speter	  /* Function name is known; supply it.  */
433390075Sobrien	  const char *const argstring = _("passing arg %d of `%s'");
433452284Sobrien	  new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
433552284Sobrien					+ strlen (argstring) + 1 + 25
433652284Sobrien					/*%d*/ + 1);
433752284Sobrien	  sprintf (new_opname, argstring, argnum,
433852284Sobrien		   IDENTIFIER_POINTER (function));
433918334Speter	}
434018334Speter      else
434118334Speter	{
434290075Sobrien	  /* Function name unknown (call through ptr); just give arg number.  */
434390075Sobrien	  const char *const argnofun = _("passing arg %d of pointer to function");
434452284Sobrien	  new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
434552284Sobrien	  sprintf (new_opname, argnofun, argnum);
434618334Speter	}
434752284Sobrien      opname = new_opname;
434818334Speter    }
434952284Sobrien  pedwarn (msgid, opname);
435018334Speter}
435118334Speter
435218334Speter/* If VALUE is a compound expr all of whose expressions are constant, then
435318334Speter   return its value.  Otherwise, return error_mark_node.
435418334Speter
435518334Speter   This is for handling COMPOUND_EXPRs as initializer elements
435618334Speter   which is allowed with a warning when -pedantic is specified.  */
435718334Speter
435818334Speterstatic tree
435918334Spetervalid_compound_expr_initializer (value, endtype)
436018334Speter     tree value;
436118334Speter     tree endtype;
436218334Speter{
436318334Speter  if (TREE_CODE (value) == COMPOUND_EXPR)
436418334Speter    {
436518334Speter      if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype)
436618334Speter	  == error_mark_node)
436718334Speter	return error_mark_node;
436818334Speter      return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
436918334Speter					      endtype);
437018334Speter    }
437118334Speter  else if (! TREE_CONSTANT (value)
437218334Speter	   && ! initializer_constant_valid_p (value, endtype))
437318334Speter    return error_mark_node;
437418334Speter  else
437518334Speter    return value;
437618334Speter}
437718334Speter
437818334Speter/* Perform appropriate conversions on the initial value of a variable,
437918334Speter   store it in the declaration DECL,
438018334Speter   and print any error messages that are appropriate.
438118334Speter   If the init is invalid, store an ERROR_MARK.  */
438218334Speter
438318334Spetervoid
438418334Speterstore_init_value (decl, init)
438518334Speter     tree decl, init;
438618334Speter{
438790075Sobrien  tree value, type;
438818334Speter
438918334Speter  /* If variable's type was invalidly declared, just ignore it.  */
439018334Speter
439118334Speter  type = TREE_TYPE (decl);
439218334Speter  if (TREE_CODE (type) == ERROR_MARK)
439318334Speter    return;
439418334Speter
439518334Speter  /* Digest the specified initializer into an expression.  */
439618334Speter
439718334Speter  value = digest_init (type, init, TREE_STATIC (decl),
439890075Sobrien		       TREE_STATIC (decl) || (pedantic && !flag_isoc99));
439918334Speter
440018334Speter  /* Store the expression if valid; else report error.  */
440118334Speter
440218334Speter#if 0
440318334Speter  /* Note that this is the only place we can detect the error
440418334Speter     in a case such as   struct foo bar = (struct foo) { x, y };
440518334Speter     where there is one initial value which is a constructor expression.  */
440618334Speter  if (value == error_mark_node)
440718334Speter    ;
440818334Speter  else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value))
440918334Speter    {
441018334Speter      error ("initializer for static variable is not constant");
441118334Speter      value = error_mark_node;
441218334Speter    }
441318334Speter  else if (TREE_STATIC (decl)
441418334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
441518334Speter    {
441618334Speter      error ("initializer for static variable uses complicated arithmetic");
441718334Speter      value = error_mark_node;
441818334Speter    }
441918334Speter  else
442018334Speter    {
442118334Speter      if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
442218334Speter	{
442318334Speter	  if (! TREE_CONSTANT (value))
442418334Speter	    pedwarn ("aggregate initializer is not constant");
442518334Speter	  else if (! TREE_STATIC (value))
442618334Speter	    pedwarn ("aggregate initializer uses complicated arithmetic");
442718334Speter	}
442818334Speter    }
442918334Speter#endif
443018334Speter
443190075Sobrien  if (warn_traditional && !in_system_header
443290075Sobrien      && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && ! TREE_STATIC (decl))
443390075Sobrien    warning ("traditional C rejects automatic aggregate initialization");
443490075Sobrien
443518334Speter  DECL_INITIAL (decl) = value;
443618334Speter
443718334Speter  /* ANSI wants warnings about out-of-range constant initializers.  */
443818334Speter  STRIP_TYPE_NOPS (value);
443918334Speter  constant_expression_warning (value);
444090075Sobrien
444190075Sobrien  /* Check if we need to set array size from compound literal size.  */
444290075Sobrien  if (TREE_CODE (type) == ARRAY_TYPE
444390075Sobrien      && TYPE_DOMAIN (type) == 0
444490075Sobrien      && value != error_mark_node)
444590075Sobrien    {
444690075Sobrien      tree inside_init = init;
444790075Sobrien
444890075Sobrien      if (TREE_CODE (init) == NON_LVALUE_EXPR)
444990075Sobrien	inside_init = TREE_OPERAND (init, 0);
445090075Sobrien      inside_init = fold (inside_init);
445190075Sobrien
445290075Sobrien      if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
445390075Sobrien	{
445490075Sobrien	  tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
445590075Sobrien
445690075Sobrien	  if (TYPE_DOMAIN (TREE_TYPE (decl)))
445790075Sobrien	    {
445890075Sobrien	      /* For int foo[] = (int [3]){1}; we need to set array size
445990075Sobrien		 now since later on array initializer will be just the
446090075Sobrien		 brace enclosed list of the compound literal.  */
446190075Sobrien	      TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl));
446290075Sobrien	      layout_type (type);
446390075Sobrien	      layout_decl (decl, 0);
446490075Sobrien	    }
446590075Sobrien	}
446690075Sobrien    }
446718334Speter}
446818334Speter
446918334Speter/* Methods for storing and printing names for error messages.  */
447018334Speter
447118334Speter/* Implement a spelling stack that allows components of a name to be pushed
447218334Speter   and popped.  Each element on the stack is this structure.  */
447318334Speter
447418334Speterstruct spelling
447518334Speter{
447618334Speter  int kind;
447718334Speter  union
447818334Speter    {
447918334Speter      int i;
448052284Sobrien      const char *s;
448118334Speter    } u;
448218334Speter};
448318334Speter
448418334Speter#define SPELLING_STRING 1
448518334Speter#define SPELLING_MEMBER 2
448618334Speter#define SPELLING_BOUNDS 3
448718334Speter
448818334Speterstatic struct spelling *spelling;	/* Next stack element (unused).  */
448918334Speterstatic struct spelling *spelling_base;	/* Spelling stack base.  */
449018334Speterstatic int spelling_size;		/* Size of the spelling stack.  */
449118334Speter
449218334Speter/* Macros to save and restore the spelling stack around push_... functions.
449318334Speter   Alternative to SAVE_SPELLING_STACK.  */
449418334Speter
449518334Speter#define SPELLING_DEPTH() (spelling - spelling_base)
449690075Sobrien#define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH))
449718334Speter
449818334Speter/* Save and restore the spelling stack around arbitrary C code.  */
449918334Speter
450018334Speter#define SAVE_SPELLING_DEPTH(code)		\
450118334Speter{						\
450218334Speter  int __depth = SPELLING_DEPTH ();		\
450318334Speter  code;						\
450418334Speter  RESTORE_SPELLING_DEPTH (__depth);		\
450518334Speter}
450618334Speter
450718334Speter/* Push an element on the spelling stack with type KIND and assign VALUE
450818334Speter   to MEMBER.  */
450918334Speter
451018334Speter#define PUSH_SPELLING(KIND, VALUE, MEMBER)				\
451118334Speter{									\
451218334Speter  int depth = SPELLING_DEPTH ();					\
451318334Speter									\
451418334Speter  if (depth >= spelling_size)						\
451518334Speter    {									\
451618334Speter      spelling_size += 10;						\
451718334Speter      if (spelling_base == 0)						\
451818334Speter	spelling_base							\
451918334Speter	  = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling));	\
452018334Speter      else								\
452118334Speter        spelling_base							\
452218334Speter	  = (struct spelling *) xrealloc (spelling_base,		\
452318334Speter					  spelling_size * sizeof (struct spelling));	\
452418334Speter      RESTORE_SPELLING_DEPTH (depth);					\
452518334Speter    }									\
452618334Speter									\
452718334Speter  spelling->kind = (KIND);						\
452818334Speter  spelling->MEMBER = (VALUE);						\
452918334Speter  spelling++;								\
453018334Speter}
453118334Speter
453218334Speter/* Push STRING on the stack.  Printed literally.  */
453318334Speter
453418334Speterstatic void
453518334Speterpush_string (string)
453652284Sobrien     const char *string;
453718334Speter{
453818334Speter  PUSH_SPELLING (SPELLING_STRING, string, u.s);
453918334Speter}
454018334Speter
454118334Speter/* Push a member name on the stack.  Printed as '.' STRING.  */
454218334Speter
454318334Speterstatic void
454418334Speterpush_member_name (decl)
454518334Speter     tree decl;
454618334Speter
454718334Speter{
454890075Sobrien  const char *const string
454918334Speter    = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
455018334Speter  PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
455118334Speter}
455218334Speter
455318334Speter/* Push an array bounds on the stack.  Printed as [BOUNDS].  */
455418334Speter
455518334Speterstatic void
455618334Speterpush_array_bounds (bounds)
455718334Speter     int bounds;
455818334Speter{
455918334Speter  PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
456018334Speter}
456118334Speter
456218334Speter/* Compute the maximum size in bytes of the printed spelling.  */
456318334Speter
456418334Speterstatic int
456518334Speterspelling_length ()
456618334Speter{
456790075Sobrien  int size = 0;
456890075Sobrien  struct spelling *p;
456918334Speter
457018334Speter  for (p = spelling_base; p < spelling; p++)
457118334Speter    {
457218334Speter      if (p->kind == SPELLING_BOUNDS)
457318334Speter	size += 25;
457418334Speter      else
457518334Speter	size += strlen (p->u.s) + 1;
457618334Speter    }
457718334Speter
457818334Speter  return size;
457918334Speter}
458018334Speter
458118334Speter/* Print the spelling to BUFFER and return it.  */
458218334Speter
458318334Speterstatic char *
458418334Speterprint_spelling (buffer)
458590075Sobrien     char *buffer;
458618334Speter{
458790075Sobrien  char *d = buffer;
458890075Sobrien  struct spelling *p;
458918334Speter
459018334Speter  for (p = spelling_base; p < spelling; p++)
459118334Speter    if (p->kind == SPELLING_BOUNDS)
459218334Speter      {
459318334Speter	sprintf (d, "[%d]", p->u.i);
459418334Speter	d += strlen (d);
459518334Speter      }
459618334Speter    else
459718334Speter      {
459890075Sobrien	const char *s;
459918334Speter	if (p->kind == SPELLING_MEMBER)
460018334Speter	  *d++ = '.';
460150397Sobrien	for (s = p->u.s; (*d = *s++); d++)
460218334Speter	  ;
460318334Speter      }
460418334Speter  *d++ = '\0';
460518334Speter  return buffer;
460618334Speter}
460718334Speter
460818334Speter/* Issue an error message for a bad initializer component.
460952284Sobrien   MSGID identifies the message.
461052284Sobrien   The component name is taken from the spelling stack.  */
461118334Speter
461218334Spetervoid
461352284Sobrienerror_init (msgid)
461452284Sobrien     const char *msgid;
461518334Speter{
461652284Sobrien  char *ofwhat;
461718334Speter
461890075Sobrien  error ("%s", _(msgid));
461952284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
462018334Speter  if (*ofwhat)
462152284Sobrien    error ("(near initialization for `%s')", ofwhat);
462218334Speter}
462318334Speter
462418334Speter/* Issue a pedantic warning for a bad initializer component.
462552284Sobrien   MSGID identifies the message.
462652284Sobrien   The component name is taken from the spelling stack.  */
462718334Speter
462818334Spetervoid
462952284Sobrienpedwarn_init (msgid)
463052284Sobrien     const char *msgid;
463118334Speter{
463252284Sobrien  char *ofwhat;
463318334Speter
463490075Sobrien  pedwarn ("%s", _(msgid));
463552284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
463618334Speter  if (*ofwhat)
463752284Sobrien    pedwarn ("(near initialization for `%s')", ofwhat);
463818334Speter}
463918334Speter
464018334Speter/* Issue a warning for a bad initializer component.
464152284Sobrien   MSGID identifies the message.
464252284Sobrien   The component name is taken from the spelling stack.  */
464318334Speter
464418334Speterstatic void
464552284Sobrienwarning_init (msgid)
464652284Sobrien     const char *msgid;
464718334Speter{
464852284Sobrien  char *ofwhat;
464918334Speter
465090075Sobrien  warning ("%s", _(msgid));
465152284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
465218334Speter  if (*ofwhat)
465352284Sobrien    warning ("(near initialization for `%s')", ofwhat);
465418334Speter}
465518334Speter
465618334Speter/* Digest the parser output INIT as an initializer for type TYPE.
465718334Speter   Return a C expression of type TYPE to represent the initial value.
465818334Speter
465918334Speter   The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors
466018334Speter   if non-constant initializers or elements are seen.  CONSTRUCTOR_CONSTANT
466118334Speter   applies only to elements of constructors.  */
466218334Speter
466318334Speterstatic tree
466418334Speterdigest_init (type, init, require_constant, constructor_constant)
466518334Speter     tree type, init;
466618334Speter     int require_constant, constructor_constant;
466718334Speter{
466818334Speter  enum tree_code code = TREE_CODE (type);
466918334Speter  tree inside_init = init;
467018334Speter
467190075Sobrien  if (type == error_mark_node
467290075Sobrien      || init == error_mark_node
467390075Sobrien      || TREE_TYPE (init) == error_mark_node)
467490075Sobrien    return error_mark_node;
467518334Speter
467618334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
467718334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
467818334Speter     whose value is 0 to count as a null pointer constant.  */
467918334Speter  if (TREE_CODE (init) == NON_LVALUE_EXPR)
468018334Speter    inside_init = TREE_OPERAND (init, 0);
468118334Speter
468290075Sobrien  inside_init = fold (inside_init);
468390075Sobrien
468418334Speter  /* Initialization of an array of chars from a string constant
468518334Speter     optionally enclosed in braces.  */
468618334Speter
468718334Speter  if (code == ARRAY_TYPE)
468818334Speter    {
468918334Speter      tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
469018334Speter      if ((typ1 == char_type_node
469118334Speter	   || typ1 == signed_char_type_node
469218334Speter	   || typ1 == unsigned_char_type_node
469318334Speter	   || typ1 == unsigned_wchar_type_node
469418334Speter	   || typ1 == signed_wchar_type_node)
469518334Speter	  && ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
469618334Speter	{
469718334Speter	  if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
469818334Speter			 TYPE_MAIN_VARIANT (type)))
469918334Speter	    return inside_init;
470018334Speter
470118334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
470218334Speter	       != char_type_node)
470318334Speter	      && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
470418334Speter	    {
470552284Sobrien	      error_init ("char-array initialized from wide string");
470618334Speter	      return error_mark_node;
470718334Speter	    }
470818334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
470918334Speter	       == char_type_node)
471018334Speter	      && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
471118334Speter	    {
471252284Sobrien	      error_init ("int-array initialized from non-wide string");
471318334Speter	      return error_mark_node;
471418334Speter	    }
471518334Speter
471618334Speter	  TREE_TYPE (inside_init) = type;
471718334Speter	  if (TYPE_DOMAIN (type) != 0
471890075Sobrien	      && TYPE_SIZE (type) != 0
471990075Sobrien	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
472018334Speter	      /* Subtract 1 (or sizeof (wchar_t))
472118334Speter		 because it's ok to ignore the terminating null char
472218334Speter		 that is counted in the length of the constant.  */
472390075Sobrien	      && 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
472490075Sobrien				       TREE_STRING_LENGTH (inside_init)
472590075Sobrien				       - ((TYPE_PRECISION (typ1)
472690075Sobrien					   != TYPE_PRECISION (char_type_node))
472790075Sobrien					  ? (TYPE_PRECISION (wchar_type_node)
472890075Sobrien					     / BITS_PER_UNIT)
472990075Sobrien					  : 1)))
473090075Sobrien	    pedwarn_init ("initializer-string for array of chars is too long");
473190075Sobrien
473218334Speter	  return inside_init;
473318334Speter	}
473418334Speter    }
473518334Speter
473618334Speter  /* Any type can be initialized
473718334Speter     from an expression of the same type, optionally with braces.  */
473818334Speter
473918334Speter  if (inside_init && TREE_TYPE (inside_init) != 0
474018334Speter      && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
474118334Speter		     TYPE_MAIN_VARIANT (type))
474218334Speter	  || (code == ARRAY_TYPE
474318334Speter	      && comptypes (TREE_TYPE (inside_init), type))
474496263Sobrien	  || (code == VECTOR_TYPE
474596263Sobrien	      && comptypes (TREE_TYPE (inside_init), type))
474618334Speter	  || (code == POINTER_TYPE
474718334Speter	      && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
474818334Speter		  || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
474918334Speter	      && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
475018334Speter			    TREE_TYPE (type)))))
475118334Speter    {
475290075Sobrien      if (code == POINTER_TYPE)
475390075Sobrien	inside_init = default_function_array_conversion (inside_init);
475490075Sobrien
475590075Sobrien      if (require_constant && !flag_isoc99
475690075Sobrien	  && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
475718334Speter	{
475890075Sobrien	  /* As an extension, allow initializing objects with static storage
475990075Sobrien	     duration with compound literals (which are then treated just as
476090075Sobrien	     the brace enclosed list they contain).  */
476190075Sobrien	  tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
476290075Sobrien	  inside_init = DECL_INITIAL (decl);
476390075Sobrien	}
476490075Sobrien
476590075Sobrien      if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
476690075Sobrien	  && TREE_CODE (inside_init) != CONSTRUCTOR)
476790075Sobrien	{
476852284Sobrien	  error_init ("array initialized from non-constant array expression");
476918334Speter	  return error_mark_node;
477018334Speter	}
477118334Speter
477218334Speter      if (optimize && TREE_CODE (inside_init) == VAR_DECL)
477390075Sobrien	inside_init = decl_constant_value_for_broken_optimization (inside_init);
477418334Speter
477518334Speter      /* Compound expressions can only occur here if -pedantic or
477618334Speter	 -pedantic-errors is specified.  In the later case, we always want
477718334Speter	 an error.  In the former case, we simply want a warning.  */
477818334Speter      if (require_constant && pedantic
477918334Speter	  && TREE_CODE (inside_init) == COMPOUND_EXPR)
478018334Speter	{
478118334Speter	  inside_init
478218334Speter	    = valid_compound_expr_initializer (inside_init,
478318334Speter					       TREE_TYPE (inside_init));
478418334Speter	  if (inside_init == error_mark_node)
478552284Sobrien	    error_init ("initializer element is not constant");
478618334Speter	  else
478752284Sobrien	    pedwarn_init ("initializer element is not constant");
478818334Speter	  if (flag_pedantic_errors)
478918334Speter	    inside_init = error_mark_node;
479018334Speter	}
479190075Sobrien      else if (require_constant
479290075Sobrien	       && (!TREE_CONSTANT (inside_init)
479390075Sobrien		   /* This test catches things like `7 / 0' which
479490075Sobrien		      result in an expression for which TREE_CONSTANT
479590075Sobrien		      is true, but which is not actually something
479690075Sobrien		      that is a legal constant.  We really should not
479790075Sobrien		      be using this function, because it is a part of
479890075Sobrien		      the back-end.  Instead, the expression should
479990075Sobrien		      already have been turned into ERROR_MARK_NODE.  */
480090075Sobrien		   || !initializer_constant_valid_p (inside_init,
480190075Sobrien						     TREE_TYPE (inside_init))))
480218334Speter	{
480352284Sobrien	  error_init ("initializer element is not constant");
480418334Speter	  inside_init = error_mark_node;
480518334Speter	}
480618334Speter
480718334Speter      return inside_init;
480818334Speter    }
480918334Speter
481018334Speter  /* Handle scalar types, including conversions.  */
481118334Speter
481218334Speter  if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
481390075Sobrien      || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE)
481418334Speter    {
481518334Speter      /* Note that convert_for_assignment calls default_conversion
481618334Speter	 for arrays and functions.  We must not call it in the
481718334Speter	 case where inside_init is a null pointer constant.  */
481818334Speter      inside_init
481952284Sobrien	= convert_for_assignment (type, init, _("initialization"),
482018334Speter				  NULL_TREE, NULL_TREE, 0);
482118334Speter
482218334Speter      if (require_constant && ! TREE_CONSTANT (inside_init))
482318334Speter	{
482452284Sobrien	  error_init ("initializer element is not constant");
482518334Speter	  inside_init = error_mark_node;
482618334Speter	}
482718334Speter      else if (require_constant
482818334Speter	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
482918334Speter	{
483052284Sobrien	  error_init ("initializer element is not computable at load time");
483118334Speter	  inside_init = error_mark_node;
483218334Speter	}
483318334Speter
483418334Speter      return inside_init;
483518334Speter    }
483618334Speter
483718334Speter  /* Come here only for records and arrays.  */
483818334Speter
483990075Sobrien  if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
484018334Speter    {
484152284Sobrien      error_init ("variable-sized object may not be initialized");
484218334Speter      return error_mark_node;
484318334Speter    }
484418334Speter
484518334Speter  /* Traditionally, you can write  struct foo x = 0;
484618334Speter     and it initializes the first element of x to 0.  */
484718334Speter  if (flag_traditional)
484818334Speter    {
484918334Speter      tree top = 0, prev = 0, otype = type;
485018334Speter      while (TREE_CODE (type) == RECORD_TYPE
485118334Speter	     || TREE_CODE (type) == ARRAY_TYPE
485218334Speter	     || TREE_CODE (type) == QUAL_UNION_TYPE
485318334Speter	     || TREE_CODE (type) == UNION_TYPE)
485418334Speter	{
485518334Speter	  tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
485618334Speter	  if (prev == 0)
485718334Speter	    top = temp;
485818334Speter	  else
485918334Speter	    TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp);
486018334Speter	  prev = temp;
486118334Speter	  if (TREE_CODE (type) == ARRAY_TYPE)
486218334Speter	    type = TREE_TYPE (type);
486318334Speter	  else if (TYPE_FIELDS (type))
486418334Speter	    type = TREE_TYPE (TYPE_FIELDS (type));
486518334Speter	  else
486618334Speter	    {
486752284Sobrien	      error_init ("invalid initializer");
486818334Speter	      return error_mark_node;
486918334Speter	    }
487018334Speter	}
487118334Speter
487218334Speter      if (otype != type)
487318334Speter	{
487418334Speter	  TREE_OPERAND (prev, 1)
487518334Speter	    = build_tree_list (NULL_TREE,
487618334Speter			       digest_init (type, init, require_constant,
487718334Speter					    constructor_constant));
487818334Speter	  return top;
487918334Speter	}
488018334Speter      else
488118334Speter	return error_mark_node;
488218334Speter    }
488352284Sobrien  error_init ("invalid initializer");
488418334Speter  return error_mark_node;
488518334Speter}
488618334Speter
488718334Speter/* Handle initializers that use braces.  */
488818334Speter
488918334Speter/* Type of object we are accumulating a constructor for.
489018334Speter   This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE.  */
489118334Speterstatic tree constructor_type;
489218334Speter
489318334Speter/* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields
489418334Speter   left to fill.  */
489518334Speterstatic tree constructor_fields;
489618334Speter
489718334Speter/* For an ARRAY_TYPE, this is the specified index
489890075Sobrien   at which to store the next element we get.  */
489918334Speterstatic tree constructor_index;
490018334Speter
490118334Speter/* For an ARRAY_TYPE, this is the maximum index.  */
490218334Speterstatic tree constructor_max_index;
490318334Speter
490418334Speter/* For a RECORD_TYPE, this is the first field not yet written out.  */
490518334Speterstatic tree constructor_unfilled_fields;
490618334Speter
490718334Speter/* For an ARRAY_TYPE, this is the index of the first element
490890075Sobrien   not yet written out.  */
490918334Speterstatic tree constructor_unfilled_index;
491018334Speter
491118334Speter/* In a RECORD_TYPE, the byte index of the next consecutive field.
491290075Sobrien   This is so we can generate gaps between fields, when appropriate.  */
491318334Speterstatic tree constructor_bit_index;
491418334Speter
491518334Speter/* If we are saving up the elements rather than allocating them,
491618334Speter   this is the list of elements so far (in reverse order,
491718334Speter   most recent first).  */
491818334Speterstatic tree constructor_elements;
491918334Speter
492090075Sobrien/* 1 if constructor should be incrementally stored into a constructor chain,
492190075Sobrien   0 if all the elements should be kept in AVL tree.  */
492290075Sobrienstatic int constructor_incremental;
492390075Sobrien
492418334Speter/* 1 if so far this constructor's elements are all compile-time constants.  */
492518334Speterstatic int constructor_constant;
492618334Speter
492718334Speter/* 1 if so far this constructor's elements are all valid address constants.  */
492818334Speterstatic int constructor_simple;
492918334Speter
493018334Speter/* 1 if this constructor is erroneous so far.  */
493118334Speterstatic int constructor_erroneous;
493218334Speter
493318334Speter/* 1 if have called defer_addressed_constants.  */
493418334Speterstatic int constructor_subconstants_deferred;
493518334Speter
493650397Sobrien/* Structure for managing pending initializer elements, organized as an
493750397Sobrien   AVL tree.  */
493850397Sobrien
493950397Sobrienstruct init_node
494050397Sobrien{
494150397Sobrien  struct init_node *left, *right;
494250397Sobrien  struct init_node *parent;
494350397Sobrien  int balance;
494450397Sobrien  tree purpose;
494550397Sobrien  tree value;
494650397Sobrien};
494750397Sobrien
494850397Sobrien/* Tree of pending elements at this constructor level.
494918334Speter   These are elements encountered out of order
495018334Speter   which belong at places we haven't reached yet in actually
495190075Sobrien   writing the output.
495290075Sobrien   Will never hold tree nodes across GC runs.  */
495350397Sobrienstatic struct init_node *constructor_pending_elts;
495418334Speter
495518334Speter/* The SPELLING_DEPTH of this constructor.  */
495618334Speterstatic int constructor_depth;
495718334Speter
495818334Speter/* 0 if implicitly pushing constructor levels is allowed.  */
495950397Sobrienint constructor_no_implicit = 0; /* 0 for C; 1 for some other languages.  */
496018334Speter
496118334Speterstatic int require_constant_value;
496218334Speterstatic int require_constant_elements;
496318334Speter
496418334Speter/* DECL node for which an initializer is being read.
496518334Speter   0 means we are reading a constructor expression
496618334Speter   such as (struct foo) {...}.  */
496718334Speterstatic tree constructor_decl;
496818334Speter
496918334Speter/* start_init saves the ASMSPEC arg here for really_start_incremental_init.  */
497090075Sobrienstatic const char *constructor_asmspec;
497118334Speter
497218334Speter/* Nonzero if this is an initializer for a top-level decl.  */
497318334Speterstatic int constructor_top_level;
497418334Speter
497590075Sobrien/* Nonzero if there were any member designators in this initializer.  */
497690075Sobrienstatic int constructor_designated;
497790075Sobrien
497890075Sobrien/* Nesting depth of designator list.  */
497990075Sobrienstatic int designator_depth;
498090075Sobrien
498190075Sobrien/* Nonzero if there were diagnosed errors in this designator list.  */
498290075Sobrienstatic int designator_errorneous;
498390075Sobrien
498418334Speter
498518334Speter/* This stack has a level for each implicit or explicit level of
498618334Speter   structuring in the initializer, including the outermost one.  It
498718334Speter   saves the values of most of the variables above.  */
498818334Speter
498990075Sobrienstruct constructor_range_stack;
499090075Sobrien
499118334Speterstruct constructor_stack
499218334Speter{
499318334Speter  struct constructor_stack *next;
499418334Speter  tree type;
499518334Speter  tree fields;
499618334Speter  tree index;
499718334Speter  tree max_index;
499818334Speter  tree unfilled_index;
499918334Speter  tree unfilled_fields;
500018334Speter  tree bit_index;
500118334Speter  tree elements;
500290075Sobrien  struct init_node *pending_elts;
500318334Speter  int offset;
500418334Speter  int depth;
500518334Speter  /* If nonzero, this value should replace the entire
500618334Speter     constructor at this level.  */
500718334Speter  tree replacement_value;
500890075Sobrien  struct constructor_range_stack *range_stack;
500918334Speter  char constant;
501018334Speter  char simple;
501118334Speter  char implicit;
501218334Speter  char erroneous;
501318334Speter  char outer;
501490075Sobrien  char incremental;
501590075Sobrien  char designated;
501618334Speter};
501718334Speter
501818334Speterstruct constructor_stack *constructor_stack;
501918334Speter
502090075Sobrien/* This stack represents designators from some range designator up to
502190075Sobrien   the last designator in the list.  */
502290075Sobrien
502390075Sobrienstruct constructor_range_stack
502490075Sobrien{
502590075Sobrien  struct constructor_range_stack *next, *prev;
502690075Sobrien  struct constructor_stack *stack;
502790075Sobrien  tree range_start;
502890075Sobrien  tree index;
502990075Sobrien  tree range_end;
503090075Sobrien  tree fields;
503190075Sobrien};
503290075Sobrien
503390075Sobrienstruct constructor_range_stack *constructor_range_stack;
503490075Sobrien
503518334Speter/* This stack records separate initializers that are nested.
503618334Speter   Nested initializers can't happen in ANSI C, but GNU C allows them
503718334Speter   in cases like { ... (struct foo) { ... } ... }.  */
503818334Speter
503918334Speterstruct initializer_stack
504018334Speter{
504118334Speter  struct initializer_stack *next;
504218334Speter  tree decl;
504390075Sobrien  const char *asmspec;
504418334Speter  struct constructor_stack *constructor_stack;
504590075Sobrien  struct constructor_range_stack *constructor_range_stack;
504618334Speter  tree elements;
504718334Speter  struct spelling *spelling;
504818334Speter  struct spelling *spelling_base;
504918334Speter  int spelling_size;
505018334Speter  char top_level;
505118334Speter  char require_constant_value;
505218334Speter  char require_constant_elements;
505318334Speter  char deferred;
505418334Speter};
505518334Speter
505618334Speterstruct initializer_stack *initializer_stack;
505718334Speter
505818334Speter/* Prepare to parse and output the initializer for variable DECL.  */
505918334Speter
506018334Spetervoid
506118334Speterstart_init (decl, asmspec_tree, top_level)
506218334Speter     tree decl;
506318334Speter     tree asmspec_tree;
506418334Speter     int top_level;
506518334Speter{
506652284Sobrien  const char *locus;
506718334Speter  struct initializer_stack *p
506818334Speter    = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
506990075Sobrien  const char *asmspec = 0;
507018334Speter
507118334Speter  if (asmspec_tree)
507218334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
507318334Speter
507418334Speter  p->decl = constructor_decl;
507518334Speter  p->asmspec = constructor_asmspec;
507618334Speter  p->require_constant_value = require_constant_value;
507718334Speter  p->require_constant_elements = require_constant_elements;
507818334Speter  p->constructor_stack = constructor_stack;
507990075Sobrien  p->constructor_range_stack = constructor_range_stack;
508018334Speter  p->elements = constructor_elements;
508118334Speter  p->spelling = spelling;
508218334Speter  p->spelling_base = spelling_base;
508318334Speter  p->spelling_size = spelling_size;
508418334Speter  p->deferred = constructor_subconstants_deferred;
508518334Speter  p->top_level = constructor_top_level;
508618334Speter  p->next = initializer_stack;
508718334Speter  initializer_stack = p;
508818334Speter
508918334Speter  constructor_decl = decl;
509018334Speter  constructor_asmspec = asmspec;
509118334Speter  constructor_subconstants_deferred = 0;
509290075Sobrien  constructor_designated = 0;
509318334Speter  constructor_top_level = top_level;
509418334Speter
509518334Speter  if (decl != 0)
509618334Speter    {
509718334Speter      require_constant_value = TREE_STATIC (decl);
509818334Speter      require_constant_elements
509990075Sobrien	= ((TREE_STATIC (decl) || (pedantic && !flag_isoc99))
510018334Speter	   /* For a scalar, you can always use any value to initialize,
510118334Speter	      even within braces.  */
510218334Speter	   && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
510318334Speter	       || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
510418334Speter	       || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
510518334Speter	       || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
510618334Speter      locus = IDENTIFIER_POINTER (DECL_NAME (decl));
510718334Speter    }
510818334Speter  else
510918334Speter    {
511018334Speter      require_constant_value = 0;
511118334Speter      require_constant_elements = 0;
511218334Speter      locus = "(anonymous)";
511318334Speter    }
511418334Speter
511518334Speter  constructor_stack = 0;
511690075Sobrien  constructor_range_stack = 0;
511718334Speter
511818334Speter  missing_braces_mentioned = 0;
511918334Speter
512018334Speter  spelling_base = 0;
512118334Speter  spelling_size = 0;
512218334Speter  RESTORE_SPELLING_DEPTH (0);
512318334Speter
512418334Speter  if (locus)
512518334Speter    push_string (locus);
512618334Speter}
512718334Speter
512818334Spetervoid
512918334Speterfinish_init ()
513018334Speter{
513118334Speter  struct initializer_stack *p = initializer_stack;
513218334Speter
513318334Speter  /* Output subconstants (string constants, usually)
513418334Speter     that were referenced within this initializer and saved up.
513518334Speter     Must do this if and only if we called defer_addressed_constants.  */
513618334Speter  if (constructor_subconstants_deferred)
513718334Speter    output_deferred_addressed_constants ();
513818334Speter
513918334Speter  /* Free the whole constructor stack of this initializer.  */
514018334Speter  while (constructor_stack)
514118334Speter    {
514218334Speter      struct constructor_stack *q = constructor_stack;
514318334Speter      constructor_stack = q->next;
514418334Speter      free (q);
514518334Speter    }
514618334Speter
514790075Sobrien  if (constructor_range_stack)
514890075Sobrien    abort ();
514990075Sobrien
515018334Speter  /* Pop back to the data of the outer initializer (if any).  */
515118334Speter  constructor_decl = p->decl;
515218334Speter  constructor_asmspec = p->asmspec;
515318334Speter  require_constant_value = p->require_constant_value;
515418334Speter  require_constant_elements = p->require_constant_elements;
515518334Speter  constructor_stack = p->constructor_stack;
515690075Sobrien  constructor_range_stack = p->constructor_range_stack;
515718334Speter  constructor_elements = p->elements;
515818334Speter  spelling = p->spelling;
515918334Speter  spelling_base = p->spelling_base;
516018334Speter  spelling_size = p->spelling_size;
516118334Speter  constructor_subconstants_deferred = p->deferred;
516218334Speter  constructor_top_level = p->top_level;
516318334Speter  initializer_stack = p->next;
516418334Speter  free (p);
516518334Speter}
516618334Speter
516718334Speter/* Call here when we see the initializer is surrounded by braces.
516818334Speter   This is instead of a call to push_init_level;
516918334Speter   it is matched by a call to pop_init_level.
517018334Speter
517118334Speter   TYPE is the type to initialize, for a constructor expression.
517218334Speter   For an initializer for a decl, TYPE is zero.  */
517318334Speter
517418334Spetervoid
517518334Speterreally_start_incremental_init (type)
517618334Speter     tree type;
517718334Speter{
517818334Speter  struct constructor_stack *p
517918334Speter    = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
518018334Speter
518118334Speter  if (type == 0)
518218334Speter    type = TREE_TYPE (constructor_decl);
518318334Speter
518418334Speter  p->type = constructor_type;
518518334Speter  p->fields = constructor_fields;
518618334Speter  p->index = constructor_index;
518718334Speter  p->max_index = constructor_max_index;
518818334Speter  p->unfilled_index = constructor_unfilled_index;
518918334Speter  p->unfilled_fields = constructor_unfilled_fields;
519018334Speter  p->bit_index = constructor_bit_index;
519118334Speter  p->elements = constructor_elements;
519218334Speter  p->constant = constructor_constant;
519318334Speter  p->simple = constructor_simple;
519418334Speter  p->erroneous = constructor_erroneous;
519518334Speter  p->pending_elts = constructor_pending_elts;
519618334Speter  p->depth = constructor_depth;
519718334Speter  p->replacement_value = 0;
519818334Speter  p->implicit = 0;
519990075Sobrien  p->range_stack = 0;
520090075Sobrien  p->outer = 0;
520118334Speter  p->incremental = constructor_incremental;
520290075Sobrien  p->designated = constructor_designated;
520318334Speter  p->next = 0;
520418334Speter  constructor_stack = p;
520518334Speter
520618334Speter  constructor_constant = 1;
520718334Speter  constructor_simple = 1;
520818334Speter  constructor_depth = SPELLING_DEPTH ();
520918334Speter  constructor_elements = 0;
521018334Speter  constructor_pending_elts = 0;
521118334Speter  constructor_type = type;
521290075Sobrien  constructor_incremental = 1;
521390075Sobrien  constructor_designated = 0;
521490075Sobrien  designator_depth = 0;
521590075Sobrien  designator_errorneous = 0;
521618334Speter
521718334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
521818334Speter      || TREE_CODE (constructor_type) == UNION_TYPE)
521918334Speter    {
522018334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
522118334Speter      /* Skip any nameless bit fields at the beginning.  */
522250397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
522318334Speter	     && DECL_NAME (constructor_fields) == 0)
522418334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
522590075Sobrien
522618334Speter      constructor_unfilled_fields = constructor_fields;
522790075Sobrien      constructor_bit_index = bitsize_zero_node;
522818334Speter    }
522918334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
523018334Speter    {
523118334Speter      if (TYPE_DOMAIN (constructor_type))
523218334Speter	{
523318334Speter	  constructor_max_index
523418334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
523590075Sobrien
523690075Sobrien	  /* Detect non-empty initializations of zero-length arrays.  */
523790075Sobrien	  if (constructor_max_index == NULL_TREE
523890075Sobrien	      && TYPE_SIZE (constructor_type))
523990075Sobrien	    constructor_max_index = build_int_2 (-1, -1);
524090075Sobrien
524190075Sobrien	  /* constructor_max_index needs to be an INTEGER_CST.  Attempts
524290075Sobrien	     to initialize VLAs will cause an proper error; avoid tree
524390075Sobrien	     checking errors as well by setting a safe value.  */
524490075Sobrien	  if (constructor_max_index
524590075Sobrien	      && TREE_CODE (constructor_max_index) != INTEGER_CST)
524690075Sobrien	    constructor_max_index = build_int_2 (-1, -1);
524790075Sobrien
524818334Speter	  constructor_index
524990075Sobrien	    = convert (bitsizetype,
525090075Sobrien		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
525118334Speter	}
525218334Speter      else
525390075Sobrien	constructor_index = bitsize_zero_node;
525490075Sobrien
525590075Sobrien      constructor_unfilled_index = constructor_index;
525618334Speter    }
525796263Sobrien  else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
525896263Sobrien    {
525996263Sobrien      /* Vectors are like simple fixed-size arrays.  */
526096263Sobrien      constructor_max_index =
526196263Sobrien	build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
526296263Sobrien      constructor_index = convert (bitsizetype, integer_zero_node);
526396263Sobrien      constructor_unfilled_index = constructor_index;
526496263Sobrien    }
526518334Speter  else
526618334Speter    {
526718334Speter      /* Handle the case of int x = {5}; */
526818334Speter      constructor_fields = constructor_type;
526918334Speter      constructor_unfilled_fields = constructor_type;
527018334Speter    }
527118334Speter}
527218334Speter
527318334Speter/* Push down into a subobject, for initialization.
527418334Speter   If this is for an explicit set of braces, IMPLICIT is 0.
527518334Speter   If it is because the next element belongs at a lower level,
527690075Sobrien   IMPLICIT is 1 (or 2 if the push is because of designator list).  */
527718334Speter
527818334Spetervoid
527918334Speterpush_init_level (implicit)
528018334Speter     int implicit;
528118334Speter{
528218334Speter  struct constructor_stack *p;
528390075Sobrien  tree value = NULL_TREE;
528418334Speter
528518334Speter  /* If we've exhausted any levels that didn't have braces,
528618334Speter     pop them now.  */
528718334Speter  while (constructor_stack->implicit)
528818334Speter    {
528918334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
529018334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
529118334Speter	  && constructor_fields == 0)
529218334Speter	process_init_element (pop_init_level (1));
529318334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
529418334Speter	       && tree_int_cst_lt (constructor_max_index, constructor_index))
529518334Speter	process_init_element (pop_init_level (1));
529618334Speter      else
529718334Speter	break;
529818334Speter    }
529918334Speter
530090075Sobrien  /* Unless this is an explicit brace, we need to preserve previous
530190075Sobrien     content if any.  */
530290075Sobrien  if (implicit)
530318334Speter    {
530490075Sobrien      if ((TREE_CODE (constructor_type) == RECORD_TYPE
530590075Sobrien	   || TREE_CODE (constructor_type) == UNION_TYPE)
530690075Sobrien	  && constructor_fields)
530790075Sobrien	value = find_init_member (constructor_fields);
530890075Sobrien      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
530990075Sobrien	value = find_init_member (constructor_index);
531018334Speter    }
531118334Speter
531218334Speter  p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
531318334Speter  p->type = constructor_type;
531418334Speter  p->fields = constructor_fields;
531518334Speter  p->index = constructor_index;
531618334Speter  p->max_index = constructor_max_index;
531718334Speter  p->unfilled_index = constructor_unfilled_index;
531818334Speter  p->unfilled_fields = constructor_unfilled_fields;
531918334Speter  p->bit_index = constructor_bit_index;
532018334Speter  p->elements = constructor_elements;
532118334Speter  p->constant = constructor_constant;
532218334Speter  p->simple = constructor_simple;
532318334Speter  p->erroneous = constructor_erroneous;
532418334Speter  p->pending_elts = constructor_pending_elts;
532518334Speter  p->depth = constructor_depth;
532618334Speter  p->replacement_value = 0;
532718334Speter  p->implicit = implicit;
532890075Sobrien  p->outer = 0;
532918334Speter  p->incremental = constructor_incremental;
533090075Sobrien  p->designated = constructor_designated;
533118334Speter  p->next = constructor_stack;
533290075Sobrien  p->range_stack = 0;
533318334Speter  constructor_stack = p;
533418334Speter
533518334Speter  constructor_constant = 1;
533618334Speter  constructor_simple = 1;
533718334Speter  constructor_depth = SPELLING_DEPTH ();
533818334Speter  constructor_elements = 0;
533990075Sobrien  constructor_incremental = 1;
534090075Sobrien  constructor_designated = 0;
534118334Speter  constructor_pending_elts = 0;
534290075Sobrien  if (!implicit)
534390075Sobrien    {
534490075Sobrien      p->range_stack = constructor_range_stack;
534590075Sobrien      constructor_range_stack = 0;
534690075Sobrien      designator_depth = 0;
534790075Sobrien      designator_errorneous = 0;
534890075Sobrien    }
534918334Speter
535018334Speter  /* Don't die if an entire brace-pair level is superfluous
535118334Speter     in the containing level.  */
535218334Speter  if (constructor_type == 0)
535318334Speter    ;
535418334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
535518334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
535618334Speter    {
535718334Speter      /* Don't die if there are extra init elts at the end.  */
535818334Speter      if (constructor_fields == 0)
535918334Speter	constructor_type = 0;
536018334Speter      else
536118334Speter	{
536218334Speter	  constructor_type = TREE_TYPE (constructor_fields);
536318334Speter	  push_member_name (constructor_fields);
536418334Speter	  constructor_depth++;
536518334Speter	}
536618334Speter    }
536718334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
536818334Speter    {
536918334Speter      constructor_type = TREE_TYPE (constructor_type);
537090075Sobrien      push_array_bounds (tree_low_cst (constructor_index, 0));
537118334Speter      constructor_depth++;
537218334Speter    }
537318334Speter
537418334Speter  if (constructor_type == 0)
537518334Speter    {
537652284Sobrien      error_init ("extra brace group at end of initializer");
537718334Speter      constructor_fields = 0;
537818334Speter      constructor_unfilled_fields = 0;
537918334Speter      return;
538018334Speter    }
538118334Speter
538290075Sobrien  if (value && TREE_CODE (value) == CONSTRUCTOR)
538390075Sobrien    {
538490075Sobrien      constructor_constant = TREE_CONSTANT (value);
538590075Sobrien      constructor_simple = TREE_STATIC (value);
538690075Sobrien      constructor_elements = TREE_OPERAND (value, 1);
538790075Sobrien      if (constructor_elements
538890075Sobrien	  && (TREE_CODE (constructor_type) == RECORD_TYPE
538990075Sobrien	      || TREE_CODE (constructor_type) == ARRAY_TYPE))
539090075Sobrien	set_nonincremental_init ();
539190075Sobrien    }
539218334Speter
539390075Sobrien  if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
539418334Speter    {
539518334Speter      missing_braces_mentioned = 1;
539652284Sobrien      warning_init ("missing braces around initializer");
539718334Speter    }
539818334Speter
539918334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
540018334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
540118334Speter    {
540218334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
540318334Speter      /* Skip any nameless bit fields at the beginning.  */
540450397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
540518334Speter	     && DECL_NAME (constructor_fields) == 0)
540618334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
540790075Sobrien
540818334Speter      constructor_unfilled_fields = constructor_fields;
540990075Sobrien      constructor_bit_index = bitsize_zero_node;
541018334Speter    }
541196263Sobrien  else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
541296263Sobrien    {
541396263Sobrien      /* Vectors are like simple fixed-size arrays.  */
541496263Sobrien      constructor_max_index =
541596263Sobrien	build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
541696263Sobrien      constructor_index = convert (bitsizetype, integer_zero_node);
541796263Sobrien      constructor_unfilled_index = constructor_index;
541896263Sobrien    }
541918334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
542018334Speter    {
542118334Speter      if (TYPE_DOMAIN (constructor_type))
542218334Speter	{
542318334Speter	  constructor_max_index
542418334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
542590075Sobrien
542690075Sobrien	  /* Detect non-empty initializations of zero-length arrays.  */
542790075Sobrien	  if (constructor_max_index == NULL_TREE
542890075Sobrien	      && TYPE_SIZE (constructor_type))
542990075Sobrien	    constructor_max_index = build_int_2 (-1, -1);
543090075Sobrien
543190075Sobrien	  /* constructor_max_index needs to be an INTEGER_CST.  Attempts
543290075Sobrien	     to initialize VLAs will cause an proper error; avoid tree
543390075Sobrien	     checking errors as well by setting a safe value.  */
543490075Sobrien	  if (constructor_max_index
543590075Sobrien	      && TREE_CODE (constructor_max_index) != INTEGER_CST)
543690075Sobrien	    constructor_max_index = build_int_2 (-1, -1);
543790075Sobrien
543818334Speter	  constructor_index
543990075Sobrien	    = convert (bitsizetype,
544090075Sobrien		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
544118334Speter	}
544218334Speter      else
544390075Sobrien	constructor_index = bitsize_zero_node;
544490075Sobrien
544590075Sobrien      constructor_unfilled_index = constructor_index;
544690075Sobrien      if (value && TREE_CODE (value) == STRING_CST)
544790075Sobrien	{
544890075Sobrien	  /* We need to split the char/wchar array into individual
544990075Sobrien	     characters, so that we don't have to special case it
545090075Sobrien	     everywhere.  */
545190075Sobrien	  set_nonincremental_init_from_string (value);
545290075Sobrien	}
545318334Speter    }
545418334Speter  else
545518334Speter    {
545652284Sobrien      warning_init ("braces around scalar initializer");
545718334Speter      constructor_fields = constructor_type;
545818334Speter      constructor_unfilled_fields = constructor_type;
545918334Speter    }
546018334Speter}
546118334Speter
546218334Speter/* At the end of an implicit or explicit brace level,
546318334Speter   finish up that level of constructor.
546418334Speter   If we were outputting the elements as they are read, return 0
546518334Speter   from inner levels (process_init_element ignores that),
546618334Speter   but return error_mark_node from the outermost level
546718334Speter   (that's what we want to put in DECL_INITIAL).
546818334Speter   Otherwise, return a CONSTRUCTOR expression.  */
546918334Speter
547018334Spetertree
547118334Speterpop_init_level (implicit)
547218334Speter     int implicit;
547318334Speter{
547418334Speter  struct constructor_stack *p;
547518334Speter  tree constructor = 0;
547618334Speter
547718334Speter  if (implicit == 0)
547818334Speter    {
547918334Speter      /* When we come to an explicit close brace,
548018334Speter	 pop any inner levels that didn't have explicit braces.  */
548118334Speter      while (constructor_stack->implicit)
548218334Speter	process_init_element (pop_init_level (1));
548390075Sobrien
548490075Sobrien      if (constructor_range_stack)
548590075Sobrien	abort ();
548618334Speter    }
548718334Speter
548818334Speter  p = constructor_stack;
548918334Speter
549090075Sobrien  /* Error for initializing a flexible array member, or a zero-length
549190075Sobrien     array member in an inappropriate context.  */
549290075Sobrien  if (constructor_type && constructor_fields
549390075Sobrien      && TREE_CODE (constructor_type) == ARRAY_TYPE
549490075Sobrien      && TYPE_DOMAIN (constructor_type)
549590075Sobrien      && ! TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
549690075Sobrien    {
549790075Sobrien      /* Silently discard empty initializations.  The parser will
549890075Sobrien	 already have pedwarned for empty brackets.  */
549990075Sobrien      if (integer_zerop (constructor_unfilled_index))
550090075Sobrien	constructor_type = NULL_TREE;
550190075Sobrien      else if (! TYPE_SIZE (constructor_type))
550290075Sobrien	{
550390075Sobrien	  if (constructor_depth > 2)
550490075Sobrien	    error_init ("initialization of flexible array member in a nested context");
550590075Sobrien	  else if (pedantic)
550690075Sobrien	    pedwarn_init ("initialization of a flexible array member");
550718334Speter
550890075Sobrien	  /* We have already issued an error message for the existence
550990075Sobrien	     of a flexible array member not at the end of the structure.
551090075Sobrien	     Discard the initializer so that we do not abort later.  */
551190075Sobrien	  if (TREE_CHAIN (constructor_fields) != NULL_TREE)
551290075Sobrien	    constructor_type = NULL_TREE;
551390075Sobrien	}
551490075Sobrien      else
551590075Sobrien	/* Zero-length arrays are no longer special, so we should no longer
551690075Sobrien	   get here.  */
551790075Sobrien	abort ();
551890075Sobrien    }
551990075Sobrien
552050397Sobrien  /* Warn when some struct elements are implicitly initialized to zero.  */
552150397Sobrien  if (extra_warnings
552250397Sobrien      && constructor_type
552350397Sobrien      && TREE_CODE (constructor_type) == RECORD_TYPE
552450397Sobrien      && constructor_unfilled_fields)
552550397Sobrien    {
552690075Sobrien	/* Do not warn for flexible array members or zero-length arrays.  */
552790075Sobrien	while (constructor_unfilled_fields
552890075Sobrien	       && (! DECL_SIZE (constructor_unfilled_fields)
552990075Sobrien		   || integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
553090075Sobrien	  constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
553190075Sobrien
553290075Sobrien	/* Do not warn if this level of the initializer uses member
553390075Sobrien	   designators; it is likely to be deliberate.  */
553490075Sobrien	if (constructor_unfilled_fields && !constructor_designated)
553590075Sobrien	  {
553690075Sobrien	    push_member_name (constructor_unfilled_fields);
553790075Sobrien	    warning_init ("missing initializer");
553890075Sobrien	    RESTORE_SPELLING_DEPTH (constructor_depth);
553990075Sobrien	  }
554050397Sobrien    }
554150397Sobrien
554218334Speter  /* Now output all pending elements.  */
554390075Sobrien  constructor_incremental = 1;
554418334Speter  output_pending_init_elements (1);
554518334Speter
554618334Speter  /* Pad out the end of the structure.  */
554718334Speter  if (p->replacement_value)
554890075Sobrien    /* If this closes a superfluous brace pair,
554990075Sobrien       just pass out the element between them.  */
555090075Sobrien    constructor = p->replacement_value;
555118334Speter  else if (constructor_type == 0)
555218334Speter    ;
555318334Speter  else if (TREE_CODE (constructor_type) != RECORD_TYPE
555418334Speter	   && TREE_CODE (constructor_type) != UNION_TYPE
555596263Sobrien	   && TREE_CODE (constructor_type) != ARRAY_TYPE
555696263Sobrien	   && TREE_CODE (constructor_type) != VECTOR_TYPE)
555718334Speter    {
555818334Speter      /* A nonincremental scalar initializer--just return
555918334Speter	 the element, after verifying there is just one.  */
556018334Speter      if (constructor_elements == 0)
556118334Speter	{
556290075Sobrien	  if (!constructor_erroneous)
556390075Sobrien	    error_init ("empty scalar initializer");
556418334Speter	  constructor = error_mark_node;
556518334Speter	}
556618334Speter      else if (TREE_CHAIN (constructor_elements) != 0)
556718334Speter	{
556852284Sobrien	  error_init ("extra elements in scalar initializer");
556918334Speter	  constructor = TREE_VALUE (constructor_elements);
557018334Speter	}
557118334Speter      else
557218334Speter	constructor = TREE_VALUE (constructor_elements);
557318334Speter    }
557490075Sobrien  else
557518334Speter    {
557618334Speter      if (constructor_erroneous)
557718334Speter	constructor = error_mark_node;
557818334Speter      else
557918334Speter	{
558018334Speter	  constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
558118334Speter			       nreverse (constructor_elements));
558218334Speter	  if (constructor_constant)
558318334Speter	    TREE_CONSTANT (constructor) = 1;
558418334Speter	  if (constructor_constant && constructor_simple)
558518334Speter	    TREE_STATIC (constructor) = 1;
558618334Speter	}
558718334Speter    }
558818334Speter
558918334Speter  constructor_type = p->type;
559018334Speter  constructor_fields = p->fields;
559118334Speter  constructor_index = p->index;
559218334Speter  constructor_max_index = p->max_index;
559318334Speter  constructor_unfilled_index = p->unfilled_index;
559418334Speter  constructor_unfilled_fields = p->unfilled_fields;
559518334Speter  constructor_bit_index = p->bit_index;
559618334Speter  constructor_elements = p->elements;
559718334Speter  constructor_constant = p->constant;
559818334Speter  constructor_simple = p->simple;
559918334Speter  constructor_erroneous = p->erroneous;
560090075Sobrien  constructor_incremental = p->incremental;
560190075Sobrien  constructor_designated = p->designated;
560218334Speter  constructor_pending_elts = p->pending_elts;
560318334Speter  constructor_depth = p->depth;
560490075Sobrien  if (!p->implicit)
560590075Sobrien    constructor_range_stack = p->range_stack;
560618334Speter  RESTORE_SPELLING_DEPTH (constructor_depth);
560718334Speter
560818334Speter  constructor_stack = p->next;
560918334Speter  free (p);
561018334Speter
561118334Speter  if (constructor == 0)
561218334Speter    {
561318334Speter      if (constructor_stack == 0)
561418334Speter	return error_mark_node;
561518334Speter      return NULL_TREE;
561618334Speter    }
561718334Speter  return constructor;
561818334Speter}
561918334Speter
562090075Sobrien/* Common handling for both array range and field name designators.
562190075Sobrien   ARRAY argument is non-zero for array ranges.  Returns zero for success.  */
562290075Sobrien
562390075Sobrienstatic int
562490075Sobrienset_designator (array)
562590075Sobrien     int array;
562690075Sobrien{
562790075Sobrien  tree subtype;
562890075Sobrien  enum tree_code subcode;
562990075Sobrien
563090075Sobrien  /* Don't die if an entire brace-pair level is superfluous
563190075Sobrien     in the containing level.  */
563290075Sobrien  if (constructor_type == 0)
563390075Sobrien    return 1;
563490075Sobrien
563590075Sobrien  /* If there were errors in this designator list already, bail out silently.  */
563690075Sobrien  if (designator_errorneous)
563790075Sobrien    return 1;
563890075Sobrien
563990075Sobrien  if (!designator_depth)
564090075Sobrien    {
564190075Sobrien      if (constructor_range_stack)
564290075Sobrien	abort ();
564390075Sobrien
564490075Sobrien      /* Designator list starts at the level of closest explicit
564590075Sobrien	 braces.  */
564690075Sobrien      while (constructor_stack->implicit)
564790075Sobrien	process_init_element (pop_init_level (1));
564890075Sobrien      constructor_designated = 1;
564990075Sobrien      return 0;
565090075Sobrien    }
565190075Sobrien
565290075Sobrien  if (constructor_no_implicit)
565390075Sobrien    {
565490075Sobrien      error_init ("initialization designators may not nest");
565590075Sobrien      return 1;
565690075Sobrien    }
565790075Sobrien
565890075Sobrien  if (TREE_CODE (constructor_type) == RECORD_TYPE
565990075Sobrien      || TREE_CODE (constructor_type) == UNION_TYPE)
566090075Sobrien    {
566190075Sobrien      subtype = TREE_TYPE (constructor_fields);
566290075Sobrien      if (subtype != error_mark_node)
566390075Sobrien	subtype = TYPE_MAIN_VARIANT (subtype);
566490075Sobrien    }
566590075Sobrien  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
566690075Sobrien    {
566790075Sobrien      subtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
566890075Sobrien    }
566990075Sobrien  else
567090075Sobrien    abort ();
567190075Sobrien
567290075Sobrien  subcode = TREE_CODE (subtype);
567390075Sobrien  if (array && subcode != ARRAY_TYPE)
567490075Sobrien    {
567590075Sobrien      error_init ("array index in non-array initializer");
567690075Sobrien      return 1;
567790075Sobrien    }
567890075Sobrien  else if (!array && subcode != RECORD_TYPE && subcode != UNION_TYPE)
567990075Sobrien    {
568090075Sobrien      error_init ("field name not in record or union initializer");
568190075Sobrien      return 1;
568290075Sobrien    }
568390075Sobrien
568490075Sobrien  constructor_designated = 1;
568590075Sobrien  push_init_level (2);
568690075Sobrien  return 0;
568790075Sobrien}
568890075Sobrien
568990075Sobrien/* If there are range designators in designator list, push a new designator
569090075Sobrien   to constructor_range_stack.  RANGE_END is end of such stack range or
569190075Sobrien   NULL_TREE if there is no range designator at this level.  */
569290075Sobrien
569390075Sobrienstatic void
569490075Sobrienpush_range_stack (range_end)
569590075Sobrien     tree range_end;
569690075Sobrien{
569790075Sobrien  struct constructor_range_stack *p;
569890075Sobrien
569990075Sobrien  p = (struct constructor_range_stack *)
570090075Sobrien      ggc_alloc (sizeof (struct constructor_range_stack));
570190075Sobrien  p->prev = constructor_range_stack;
570290075Sobrien  p->next = 0;
570390075Sobrien  p->fields = constructor_fields;
570490075Sobrien  p->range_start = constructor_index;
570590075Sobrien  p->index = constructor_index;
570690075Sobrien  p->stack = constructor_stack;
570790075Sobrien  p->range_end = range_end;
570890075Sobrien  if (constructor_range_stack)
570990075Sobrien    constructor_range_stack->next = p;
571090075Sobrien  constructor_range_stack = p;
571190075Sobrien}
571290075Sobrien
571318334Speter/* Within an array initializer, specify the next index to be initialized.
571418334Speter   FIRST is that index.  If LAST is nonzero, then initialize a range
571518334Speter   of indices, running from FIRST through LAST.  */
571618334Speter
571718334Spetervoid
571818334Speterset_init_index (first, last)
571918334Speter     tree first, last;
572018334Speter{
572190075Sobrien  if (set_designator (1))
572290075Sobrien    return;
572390075Sobrien
572490075Sobrien  designator_errorneous = 1;
572590075Sobrien
572618334Speter  while ((TREE_CODE (first) == NOP_EXPR
572718334Speter	  || TREE_CODE (first) == CONVERT_EXPR
572818334Speter	  || TREE_CODE (first) == NON_LVALUE_EXPR)
572918334Speter	 && (TYPE_MODE (TREE_TYPE (first))
573018334Speter	     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0)))))
573190075Sobrien    first = TREE_OPERAND (first, 0);
573290075Sobrien
573318334Speter  if (last)
573418334Speter    while ((TREE_CODE (last) == NOP_EXPR
573518334Speter	    || TREE_CODE (last) == CONVERT_EXPR
573618334Speter	    || TREE_CODE (last) == NON_LVALUE_EXPR)
573718334Speter	   && (TYPE_MODE (TREE_TYPE (last))
573818334Speter	       == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0)))))
573990075Sobrien      last = TREE_OPERAND (last, 0);
574018334Speter
574118334Speter  if (TREE_CODE (first) != INTEGER_CST)
574252284Sobrien    error_init ("nonconstant array index in initializer");
574318334Speter  else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
574452284Sobrien    error_init ("nonconstant array index in initializer");
574590075Sobrien  else if (TREE_CODE (constructor_type) != ARRAY_TYPE)
574652284Sobrien    error_init ("array index in non-array initializer");
574790075Sobrien  else if (constructor_max_index
574890075Sobrien	   && tree_int_cst_lt (constructor_max_index, first))
574990075Sobrien    error_init ("array index in initializer exceeds array bounds");
575018334Speter  else
575118334Speter    {
575290075Sobrien      constructor_index = convert (bitsizetype, first);
575318334Speter
575490075Sobrien      if (last)
575518334Speter	{
575690075Sobrien	  if (tree_int_cst_equal (first, last))
575790075Sobrien	    last = 0;
575890075Sobrien	  else if (tree_int_cst_lt (last, first))
575990075Sobrien	    {
576090075Sobrien	      error_init ("empty index range in initializer");
576190075Sobrien	      last = 0;
576290075Sobrien	    }
576390075Sobrien	  else
576490075Sobrien	    {
576590075Sobrien	      last = convert (bitsizetype, last);
576690075Sobrien	      if (constructor_max_index != 0
576790075Sobrien		  && tree_int_cst_lt (constructor_max_index, last))
576890075Sobrien		{
576990075Sobrien		  error_init ("array index range in initializer exceeds array bounds");
577090075Sobrien		  last = 0;
577190075Sobrien		}
577290075Sobrien	    }
577318334Speter	}
577490075Sobrien
577590075Sobrien      designator_depth++;
577690075Sobrien      designator_errorneous = 0;
577790075Sobrien      if (constructor_range_stack || last)
577890075Sobrien	push_range_stack (last);
577918334Speter    }
578018334Speter}
578118334Speter
578218334Speter/* Within a struct initializer, specify the next field to be initialized.  */
578318334Speter
578418334Spetervoid
578518334Speterset_init_label (fieldname)
578618334Speter     tree fieldname;
578718334Speter{
578818334Speter  tree tail;
578918334Speter
579090075Sobrien  if (set_designator (0))
579118334Speter    return;
579218334Speter
579390075Sobrien  designator_errorneous = 1;
579490075Sobrien
579590075Sobrien  if (TREE_CODE (constructor_type) != RECORD_TYPE
579690075Sobrien      && TREE_CODE (constructor_type) != UNION_TYPE)
579790075Sobrien    {
579890075Sobrien      error_init ("field name not in record or union initializer");
579990075Sobrien      return;
580090075Sobrien    }
580190075Sobrien
580218334Speter  for (tail = TYPE_FIELDS (constructor_type); tail;
580318334Speter       tail = TREE_CHAIN (tail))
580418334Speter    {
580518334Speter      if (DECL_NAME (tail) == fieldname)
580618334Speter	break;
580718334Speter    }
580818334Speter
580918334Speter  if (tail == 0)
581018334Speter    error ("unknown field `%s' specified in initializer",
581118334Speter	   IDENTIFIER_POINTER (fieldname));
581218334Speter  else
581318334Speter    {
581418334Speter      constructor_fields = tail;
581590075Sobrien      designator_depth++;
581690075Sobrien      designator_errorneous = 0;
581790075Sobrien      if (constructor_range_stack)
581890075Sobrien	push_range_stack (NULL_TREE);
581918334Speter    }
582018334Speter}
582118334Speter
582250397Sobrien/* Add a new initializer to the tree of pending initializers.  PURPOSE
582390075Sobrien   identifies the initializer, either array index or field in a structure.
582450397Sobrien   VALUE is the value of that index or field.  */
582550397Sobrien
582650397Sobrienstatic void
582750397Sobrienadd_pending_init (purpose, value)
582850397Sobrien     tree purpose, value;
582950397Sobrien{
583050397Sobrien  struct init_node *p, **q, *r;
583150397Sobrien
583250397Sobrien  q = &constructor_pending_elts;
583350397Sobrien  p = 0;
583450397Sobrien
583550397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
583650397Sobrien    {
583750397Sobrien      while (*q != 0)
583850397Sobrien	{
583950397Sobrien	  p = *q;
584050397Sobrien	  if (tree_int_cst_lt (purpose, p->purpose))
584150397Sobrien	    q = &p->left;
584290075Sobrien	  else if (tree_int_cst_lt (p->purpose, purpose))
584350397Sobrien	    q = &p->right;
584450397Sobrien	  else
584590075Sobrien	    {
584690075Sobrien	      if (TREE_SIDE_EFFECTS (p->value))
584790075Sobrien		warning_init ("initialized field with side-effects overwritten");
584890075Sobrien	      p->value = value;
584990075Sobrien	      return;
585090075Sobrien	    }
585150397Sobrien	}
585250397Sobrien    }
585350397Sobrien  else
585450397Sobrien    {
585590075Sobrien      tree bitpos;
585690075Sobrien
585790075Sobrien      bitpos = bit_position (purpose);
585850397Sobrien      while (*q != NULL)
585950397Sobrien	{
586050397Sobrien	  p = *q;
586190075Sobrien	  if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
586250397Sobrien	    q = &p->left;
586360967Sobrien	  else if (p->purpose != purpose)
586450397Sobrien	    q = &p->right;
586550397Sobrien	  else
586690075Sobrien	    {
586790075Sobrien	      if (TREE_SIDE_EFFECTS (p->value))
586890075Sobrien		warning_init ("initialized field with side-effects overwritten");
586990075Sobrien	      p->value = value;
587090075Sobrien	      return;
587190075Sobrien	    }
587250397Sobrien	}
587350397Sobrien    }
587450397Sobrien
587590075Sobrien  r = (struct init_node *) ggc_alloc (sizeof (struct init_node));
587650397Sobrien  r->purpose = purpose;
587750397Sobrien  r->value = value;
587850397Sobrien
587950397Sobrien  *q = r;
588050397Sobrien  r->parent = p;
588150397Sobrien  r->left = 0;
588250397Sobrien  r->right = 0;
588350397Sobrien  r->balance = 0;
588450397Sobrien
588550397Sobrien  while (p)
588650397Sobrien    {
588750397Sobrien      struct init_node *s;
588850397Sobrien
588950397Sobrien      if (r == p->left)
589050397Sobrien	{
589150397Sobrien	  if (p->balance == 0)
589250397Sobrien	    p->balance = -1;
589350397Sobrien	  else if (p->balance < 0)
589450397Sobrien	    {
589550397Sobrien	      if (r->balance < 0)
589650397Sobrien		{
589790075Sobrien		  /* L rotation.  */
589850397Sobrien		  p->left = r->right;
589950397Sobrien		  if (p->left)
590050397Sobrien		    p->left->parent = p;
590150397Sobrien		  r->right = p;
590250397Sobrien
590350397Sobrien		  p->balance = 0;
590450397Sobrien		  r->balance = 0;
590550397Sobrien
590650397Sobrien		  s = p->parent;
590750397Sobrien		  p->parent = r;
590850397Sobrien		  r->parent = s;
590950397Sobrien		  if (s)
591050397Sobrien		    {
591150397Sobrien		      if (s->left == p)
591250397Sobrien			s->left = r;
591350397Sobrien		      else
591450397Sobrien			s->right = r;
591550397Sobrien		    }
591650397Sobrien		  else
591750397Sobrien		    constructor_pending_elts = r;
591850397Sobrien		}
591950397Sobrien	      else
592050397Sobrien		{
592190075Sobrien		  /* LR rotation.  */
592250397Sobrien		  struct init_node *t = r->right;
592350397Sobrien
592450397Sobrien		  r->right = t->left;
592550397Sobrien		  if (r->right)
592650397Sobrien		    r->right->parent = r;
592750397Sobrien		  t->left = r;
592850397Sobrien
592950397Sobrien		  p->left = t->right;
593050397Sobrien		  if (p->left)
593150397Sobrien		    p->left->parent = p;
593250397Sobrien		  t->right = p;
593350397Sobrien
593450397Sobrien		  p->balance = t->balance < 0;
593550397Sobrien		  r->balance = -(t->balance > 0);
593650397Sobrien		  t->balance = 0;
593750397Sobrien
593850397Sobrien		  s = p->parent;
593950397Sobrien		  p->parent = t;
594050397Sobrien		  r->parent = t;
594150397Sobrien		  t->parent = s;
594250397Sobrien		  if (s)
594350397Sobrien		    {
594450397Sobrien		      if (s->left == p)
594550397Sobrien			s->left = t;
594650397Sobrien		      else
594750397Sobrien			s->right = t;
594850397Sobrien		    }
594950397Sobrien		  else
595050397Sobrien		    constructor_pending_elts = t;
595150397Sobrien		}
595250397Sobrien	      break;
595350397Sobrien	    }
595450397Sobrien	  else
595550397Sobrien	    {
595650397Sobrien	      /* p->balance == +1; growth of left side balances the node.  */
595750397Sobrien	      p->balance = 0;
595850397Sobrien	      break;
595950397Sobrien	    }
596050397Sobrien	}
596150397Sobrien      else /* r == p->right */
596250397Sobrien	{
596350397Sobrien	  if (p->balance == 0)
596450397Sobrien	    /* Growth propagation from right side.  */
596550397Sobrien	    p->balance++;
596650397Sobrien	  else if (p->balance > 0)
596750397Sobrien	    {
596850397Sobrien	      if (r->balance > 0)
596950397Sobrien		{
597090075Sobrien		  /* R rotation.  */
597150397Sobrien		  p->right = r->left;
597250397Sobrien		  if (p->right)
597350397Sobrien		    p->right->parent = p;
597450397Sobrien		  r->left = p;
597550397Sobrien
597650397Sobrien		  p->balance = 0;
597750397Sobrien		  r->balance = 0;
597850397Sobrien
597950397Sobrien		  s = p->parent;
598050397Sobrien		  p->parent = r;
598150397Sobrien		  r->parent = s;
598250397Sobrien		  if (s)
598350397Sobrien		    {
598450397Sobrien		      if (s->left == p)
598550397Sobrien			s->left = r;
598650397Sobrien		      else
598750397Sobrien			s->right = r;
598850397Sobrien		    }
598950397Sobrien		  else
599050397Sobrien		    constructor_pending_elts = r;
599150397Sobrien		}
599250397Sobrien	      else /* r->balance == -1 */
599350397Sobrien		{
599450397Sobrien		  /* RL rotation */
599550397Sobrien		  struct init_node *t = r->left;
599650397Sobrien
599750397Sobrien		  r->left = t->right;
599850397Sobrien		  if (r->left)
599950397Sobrien		    r->left->parent = r;
600050397Sobrien		  t->right = r;
600150397Sobrien
600250397Sobrien		  p->right = t->left;
600350397Sobrien		  if (p->right)
600450397Sobrien		    p->right->parent = p;
600550397Sobrien		  t->left = p;
600650397Sobrien
600750397Sobrien		  r->balance = (t->balance < 0);
600850397Sobrien		  p->balance = -(t->balance > 0);
600950397Sobrien		  t->balance = 0;
601050397Sobrien
601150397Sobrien		  s = p->parent;
601250397Sobrien		  p->parent = t;
601350397Sobrien		  r->parent = t;
601450397Sobrien		  t->parent = s;
601550397Sobrien		  if (s)
601650397Sobrien		    {
601750397Sobrien		      if (s->left == p)
601850397Sobrien			s->left = t;
601950397Sobrien		      else
602050397Sobrien			s->right = t;
602150397Sobrien		    }
602250397Sobrien		  else
602350397Sobrien		    constructor_pending_elts = t;
602450397Sobrien		}
602550397Sobrien	      break;
602650397Sobrien	    }
602750397Sobrien	  else
602850397Sobrien	    {
602990075Sobrien	      /* p->balance == -1; growth of right side balances the node.  */
603050397Sobrien	      p->balance = 0;
603150397Sobrien	      break;
603250397Sobrien	    }
603350397Sobrien	}
603450397Sobrien
603550397Sobrien      r = p;
603650397Sobrien      p = p->parent;
603750397Sobrien    }
603850397Sobrien}
603950397Sobrien
604090075Sobrien/* Build AVL tree from a sorted chain.  */
604150397Sobrien
604290075Sobrienstatic void
604390075Sobrienset_nonincremental_init ()
604490075Sobrien{
604590075Sobrien  tree chain;
604690075Sobrien
604790075Sobrien  if (TREE_CODE (constructor_type) != RECORD_TYPE
604890075Sobrien      && TREE_CODE (constructor_type) != ARRAY_TYPE)
604990075Sobrien    return;
605090075Sobrien
605190075Sobrien  for (chain = constructor_elements; chain; chain = TREE_CHAIN (chain))
605290075Sobrien    add_pending_init (TREE_PURPOSE (chain), TREE_VALUE (chain));
605390075Sobrien  constructor_elements = 0;
605490075Sobrien  if (TREE_CODE (constructor_type) == RECORD_TYPE)
605590075Sobrien    {
605690075Sobrien      constructor_unfilled_fields = TYPE_FIELDS (constructor_type);
605790075Sobrien      /* Skip any nameless bit fields at the beginning.  */
605890075Sobrien      while (constructor_unfilled_fields != 0
605990075Sobrien	     && DECL_C_BIT_FIELD (constructor_unfilled_fields)
606090075Sobrien	     && DECL_NAME (constructor_unfilled_fields) == 0)
606190075Sobrien	constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
606290075Sobrien
606390075Sobrien    }
606490075Sobrien  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
606590075Sobrien    {
606690075Sobrien      if (TYPE_DOMAIN (constructor_type))
606790075Sobrien	constructor_unfilled_index
606890075Sobrien	    = convert (bitsizetype,
606990075Sobrien		       TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
607090075Sobrien      else
607190075Sobrien	constructor_unfilled_index = bitsize_zero_node;
607290075Sobrien    }
607390075Sobrien  constructor_incremental = 0;
607490075Sobrien}
607590075Sobrien
607690075Sobrien/* Build AVL tree from a string constant.  */
607790075Sobrien
607890075Sobrienstatic void
607990075Sobrienset_nonincremental_init_from_string (str)
608090075Sobrien     tree str;
608190075Sobrien{
608290075Sobrien  tree value, purpose, type;
608390075Sobrien  HOST_WIDE_INT val[2];
608490075Sobrien  const char *p, *end;
608590075Sobrien  int byte, wchar_bytes, charwidth, bitpos;
608690075Sobrien
608790075Sobrien  if (TREE_CODE (constructor_type) != ARRAY_TYPE)
608890075Sobrien    abort ();
608990075Sobrien
609090075Sobrien  if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
609190075Sobrien      == TYPE_PRECISION (char_type_node))
609290075Sobrien    wchar_bytes = 1;
609390075Sobrien  else if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
609490075Sobrien	   == TYPE_PRECISION (wchar_type_node))
609590075Sobrien    wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
609690075Sobrien  else
609790075Sobrien    abort ();
609890075Sobrien
609990075Sobrien  charwidth = TYPE_PRECISION (char_type_node);
610090075Sobrien  type = TREE_TYPE (constructor_type);
610190075Sobrien  p = TREE_STRING_POINTER (str);
610290075Sobrien  end = p + TREE_STRING_LENGTH (str);
610390075Sobrien
610490075Sobrien  for (purpose = bitsize_zero_node;
610590075Sobrien       p < end && !tree_int_cst_lt (constructor_max_index, purpose);
610690075Sobrien       purpose = size_binop (PLUS_EXPR, purpose, bitsize_one_node))
610790075Sobrien    {
610890075Sobrien      if (wchar_bytes == 1)
610990075Sobrien	{
611090075Sobrien	  val[1] = (unsigned char) *p++;
611190075Sobrien	  val[0] = 0;
611290075Sobrien	}
611390075Sobrien      else
611490075Sobrien	{
611590075Sobrien	  val[0] = 0;
611690075Sobrien	  val[1] = 0;
611790075Sobrien	  for (byte = 0; byte < wchar_bytes; byte++)
611890075Sobrien	    {
611990075Sobrien	      if (BYTES_BIG_ENDIAN)
612090075Sobrien		bitpos = (wchar_bytes - byte - 1) * charwidth;
612190075Sobrien	      else
612290075Sobrien		bitpos = byte * charwidth;
612390075Sobrien	      val[bitpos < HOST_BITS_PER_WIDE_INT]
612490075Sobrien		|= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++))
612590075Sobrien		   << (bitpos % HOST_BITS_PER_WIDE_INT);
612690075Sobrien	    }
612790075Sobrien	}
612890075Sobrien
612990075Sobrien      if (!TREE_UNSIGNED (type))
613090075Sobrien	{
613190075Sobrien	  bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR;
613290075Sobrien	  if (bitpos < HOST_BITS_PER_WIDE_INT)
613390075Sobrien	    {
613490075Sobrien	      if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
613590075Sobrien		{
613690075Sobrien		  val[1] |= ((HOST_WIDE_INT) -1) << bitpos;
613790075Sobrien		  val[0] = -1;
613890075Sobrien		}
613990075Sobrien	    }
614090075Sobrien	  else if (bitpos == HOST_BITS_PER_WIDE_INT)
614190075Sobrien	    {
614290075Sobrien	      if (val[1] < 0)
614390075Sobrien	        val[0] = -1;
614490075Sobrien	    }
614590075Sobrien	  else if (val[0] & (((HOST_WIDE_INT) 1)
614690075Sobrien			     << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
614790075Sobrien	    val[0] |= ((HOST_WIDE_INT) -1)
614890075Sobrien		      << (bitpos - HOST_BITS_PER_WIDE_INT);
614990075Sobrien	}
615090075Sobrien
615190075Sobrien      value = build_int_2 (val[1], val[0]);
615290075Sobrien      TREE_TYPE (value) = type;
615390075Sobrien      add_pending_init (purpose, value);
615490075Sobrien    }
615590075Sobrien
615690075Sobrien  constructor_incremental = 0;
615790075Sobrien}
615890075Sobrien
615990075Sobrien/* Return value of FIELD in pending initializer or zero if the field was
616090075Sobrien   not initialized yet.  */
616190075Sobrien
616290075Sobrienstatic tree
616390075Sobrienfind_init_member (field)
616450397Sobrien     tree field;
616550397Sobrien{
616650397Sobrien  struct init_node *p;
616750397Sobrien
616850397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
616950397Sobrien    {
617090075Sobrien      if (constructor_incremental
617190075Sobrien	  && tree_int_cst_lt (field, constructor_unfilled_index))
617290075Sobrien	set_nonincremental_init ();
617390075Sobrien
617490075Sobrien      p = constructor_pending_elts;
617550397Sobrien      while (p)
617650397Sobrien	{
617790075Sobrien	  if (tree_int_cst_lt (field, p->purpose))
617850397Sobrien	    p = p->left;
617990075Sobrien	  else if (tree_int_cst_lt (p->purpose, field))
618090075Sobrien	    p = p->right;
618150397Sobrien	  else
618290075Sobrien	    return p->value;
618350397Sobrien	}
618450397Sobrien    }
618590075Sobrien  else if (TREE_CODE (constructor_type) == RECORD_TYPE)
618650397Sobrien    {
618790075Sobrien      tree bitpos = bit_position (field);
618890075Sobrien
618990075Sobrien      if (constructor_incremental
619090075Sobrien	  && (!constructor_unfilled_fields
619190075Sobrien	      || tree_int_cst_lt (bitpos,
619290075Sobrien				  bit_position (constructor_unfilled_fields))))
619390075Sobrien	set_nonincremental_init ();
619490075Sobrien
619590075Sobrien      p = constructor_pending_elts;
619650397Sobrien      while (p)
619750397Sobrien	{
619850397Sobrien	  if (field == p->purpose)
619990075Sobrien	    return p->value;
620090075Sobrien	  else if (tree_int_cst_lt (bitpos, bit_position (p->purpose)))
620150397Sobrien	    p = p->left;
620250397Sobrien	  else
620350397Sobrien	    p = p->right;
620450397Sobrien	}
620550397Sobrien    }
620690075Sobrien  else if (TREE_CODE (constructor_type) == UNION_TYPE)
620790075Sobrien    {
620890075Sobrien      if (constructor_elements
620990075Sobrien	  && TREE_PURPOSE (constructor_elements) == field)
621090075Sobrien	return TREE_VALUE (constructor_elements);
621190075Sobrien    }
621250397Sobrien  return 0;
621350397Sobrien}
621450397Sobrien
621518334Speter/* "Output" the next constructor element.
621618334Speter   At top level, really output it to assembler code now.
621718334Speter   Otherwise, collect it in a list from which we will make a CONSTRUCTOR.
621818334Speter   TYPE is the data type that the containing data type wants here.
621918334Speter   FIELD is the field (a FIELD_DECL) or the index that this element fills.
622018334Speter
622118334Speter   PENDING if non-nil means output pending elements that belong
622218334Speter   right after this element.  (PENDING is normally 1;
622318334Speter   it is 0 while outputting pending elements, to avoid recursion.)  */
622418334Speter
622518334Speterstatic void
622618334Speteroutput_init_element (value, type, field, pending)
622718334Speter     tree value, type, field;
622818334Speter     int pending;
622918334Speter{
623018334Speter  if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
623118334Speter      || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
623218334Speter	  && !(TREE_CODE (value) == STRING_CST
623318334Speter	       && TREE_CODE (type) == ARRAY_TYPE
623418334Speter	       && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
623518334Speter	  && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
623618334Speter			 TYPE_MAIN_VARIANT (type))))
623718334Speter    value = default_conversion (value);
623818334Speter
623990075Sobrien  if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
624090075Sobrien      && require_constant_value && !flag_isoc99 && pending)
624190075Sobrien    {
624290075Sobrien      /* As an extension, allow initializing objects with static storage
624390075Sobrien	 duration with compound literals (which are then treated just as
624490075Sobrien	 the brace enclosed list they contain).  */
624590075Sobrien      tree decl = COMPOUND_LITERAL_EXPR_DECL (value);
624690075Sobrien      value = DECL_INITIAL (decl);
624790075Sobrien    }
624890075Sobrien
624918334Speter  if (value == error_mark_node)
625018334Speter    constructor_erroneous = 1;
625118334Speter  else if (!TREE_CONSTANT (value))
625218334Speter    constructor_constant = 0;
625318334Speter  else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0
625418334Speter	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
625518334Speter		|| TREE_CODE (constructor_type) == UNION_TYPE)
625650397Sobrien	       && DECL_C_BIT_FIELD (field)
625750397Sobrien	       && TREE_CODE (value) != INTEGER_CST))
625818334Speter    constructor_simple = 0;
625918334Speter
626018334Speter  if (require_constant_value && ! TREE_CONSTANT (value))
626118334Speter    {
626252284Sobrien      error_init ("initializer element is not constant");
626318334Speter      value = error_mark_node;
626418334Speter    }
626518334Speter  else if (require_constant_elements
626618334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
626790075Sobrien    pedwarn ("initializer element is not computable at load time");
626818334Speter
626990075Sobrien  /* If this field is empty (and not at the end of structure),
627090075Sobrien     don't do anything other than checking the initializer.  */
627190075Sobrien  if (field
627290075Sobrien      && (TREE_TYPE (field) == error_mark_node
627390075Sobrien	  || (COMPLETE_TYPE_P (TREE_TYPE (field))
627490075Sobrien	      && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))
627590075Sobrien	      && (TREE_CODE (constructor_type) == ARRAY_TYPE
627690075Sobrien		  || TREE_CHAIN (field)))))
627790075Sobrien    return;
627890075Sobrien
627990075Sobrien  value = digest_init (type, value, require_constant_value,
628090075Sobrien		       require_constant_elements);
628190075Sobrien  if (value == error_mark_node)
628218334Speter    {
628390075Sobrien      constructor_erroneous = 1;
628490075Sobrien      return;
628518334Speter    }
628618334Speter
628718334Speter  /* If this element doesn't come next in sequence,
628818334Speter     put it on constructor_pending_elts.  */
628918334Speter  if (TREE_CODE (constructor_type) == ARRAY_TYPE
629090075Sobrien      && (!constructor_incremental
629190075Sobrien	  || !tree_int_cst_equal (field, constructor_unfilled_index)))
629218334Speter    {
629390075Sobrien      if (constructor_incremental
629490075Sobrien	  && tree_int_cst_lt (field, constructor_unfilled_index))
629590075Sobrien	set_nonincremental_init ();
629690075Sobrien
629790075Sobrien      add_pending_init (field, value);
629890075Sobrien      return;
629918334Speter    }
630018334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
630190075Sobrien	   && (!constructor_incremental
630290075Sobrien	       || field != constructor_unfilled_fields))
630318334Speter    {
630418334Speter      /* We do this for records but not for unions.  In a union,
630518334Speter	 no matter which field is specified, it can be initialized
630618334Speter	 right away since it starts at the beginning of the union.  */
630790075Sobrien      if (constructor_incremental)
630818334Speter	{
630990075Sobrien	  if (!constructor_unfilled_fields)
631090075Sobrien	    set_nonincremental_init ();
631118334Speter	  else
631218334Speter	    {
631390075Sobrien	      tree bitpos, unfillpos;
631418334Speter
631590075Sobrien	      bitpos = bit_position (field);
631690075Sobrien	      unfillpos = bit_position (constructor_unfilled_fields);
631718334Speter
631890075Sobrien	      if (tree_int_cst_lt (bitpos, unfillpos))
631990075Sobrien		set_nonincremental_init ();
632018334Speter	    }
632118334Speter	}
632218334Speter
632390075Sobrien      add_pending_init (field, value);
632490075Sobrien      return;
632590075Sobrien    }
632690075Sobrien  else if (TREE_CODE (constructor_type) == UNION_TYPE
632790075Sobrien	   && constructor_elements)
632890075Sobrien    {
632990075Sobrien      if (TREE_SIDE_EFFECTS (TREE_VALUE (constructor_elements)))
633090075Sobrien	warning_init ("initialized field with side-effects overwritten");
633118334Speter
633290075Sobrien      /* We can have just one union field set.  */
633390075Sobrien      constructor_elements = 0;
633418334Speter    }
633590075Sobrien
633690075Sobrien  /* Otherwise, output this element either to
633790075Sobrien     constructor_elements or to the assembler file.  */
633890075Sobrien
633990075Sobrien  if (field && TREE_CODE (field) == INTEGER_CST)
634090075Sobrien    field = copy_node (field);
634190075Sobrien  constructor_elements
634290075Sobrien    = tree_cons (field, value, constructor_elements);
634390075Sobrien
634490075Sobrien  /* Advance the variable that indicates sequential elements output.  */
634590075Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
634690075Sobrien    constructor_unfilled_index
634790075Sobrien      = size_binop (PLUS_EXPR, constructor_unfilled_index,
634890075Sobrien		    bitsize_one_node);
634990075Sobrien  else if (TREE_CODE (constructor_type) == RECORD_TYPE)
635090075Sobrien    {
635190075Sobrien      constructor_unfilled_fields
635290075Sobrien	= TREE_CHAIN (constructor_unfilled_fields);
635390075Sobrien
635490075Sobrien      /* Skip any nameless bit fields.  */
635590075Sobrien      while (constructor_unfilled_fields != 0
635690075Sobrien	     && DECL_C_BIT_FIELD (constructor_unfilled_fields)
635790075Sobrien	     && DECL_NAME (constructor_unfilled_fields) == 0)
635890075Sobrien	constructor_unfilled_fields =
635990075Sobrien	  TREE_CHAIN (constructor_unfilled_fields);
636090075Sobrien    }
636190075Sobrien  else if (TREE_CODE (constructor_type) == UNION_TYPE)
636290075Sobrien    constructor_unfilled_fields = 0;
636390075Sobrien
636490075Sobrien  /* Now output any pending elements which have become next.  */
636590075Sobrien  if (pending)
636690075Sobrien    output_pending_init_elements (0);
636718334Speter}
636818334Speter
636918334Speter/* Output any pending elements which have become next.
637018334Speter   As we output elements, constructor_unfilled_{fields,index}
637118334Speter   advances, which may cause other elements to become next;
637218334Speter   if so, they too are output.
637318334Speter
637418334Speter   If ALL is 0, we return when there are
637518334Speter   no more pending elements to output now.
637618334Speter
637718334Speter   If ALL is 1, we output space as necessary so that
637818334Speter   we can output all the pending elements.  */
637918334Speter
638018334Speterstatic void
638118334Speteroutput_pending_init_elements (all)
638218334Speter     int all;
638318334Speter{
638450397Sobrien  struct init_node *elt = constructor_pending_elts;
638518334Speter  tree next;
638618334Speter
638718334Speter retry:
638818334Speter
638950397Sobrien  /* Look thru the whole pending tree.
639018334Speter     If we find an element that should be output now,
639118334Speter     output it.  Otherwise, set NEXT to the element
639218334Speter     that comes first among those still pending.  */
639318334Speter
639418334Speter  next = 0;
639550397Sobrien  while (elt)
639618334Speter    {
639718334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
639818334Speter	{
639950397Sobrien	  if (tree_int_cst_equal (elt->purpose,
640018334Speter				  constructor_unfilled_index))
640150397Sobrien	    output_init_element (elt->value,
640250397Sobrien				 TREE_TYPE (constructor_type),
640350397Sobrien				 constructor_unfilled_index, 0);
640450397Sobrien	  else if (tree_int_cst_lt (constructor_unfilled_index,
640550397Sobrien				    elt->purpose))
640618334Speter	    {
640750397Sobrien	      /* Advance to the next smaller node.  */
640850397Sobrien	      if (elt->left)
640950397Sobrien		elt = elt->left;
641050397Sobrien	      else
641150397Sobrien		{
641250397Sobrien		  /* We have reached the smallest node bigger than the
641350397Sobrien		     current unfilled index.  Fill the space first.  */
641450397Sobrien		  next = elt->purpose;
641550397Sobrien		  break;
641650397Sobrien		}
641718334Speter	    }
641850397Sobrien	  else
641950397Sobrien	    {
642050397Sobrien	      /* Advance to the next bigger node.  */
642150397Sobrien	      if (elt->right)
642250397Sobrien		elt = elt->right;
642350397Sobrien	      else
642450397Sobrien		{
642550397Sobrien		  /* We have reached the biggest node in a subtree.  Find
642650397Sobrien		     the parent of it, which is the next bigger node.  */
642750397Sobrien		  while (elt->parent && elt->parent->right == elt)
642850397Sobrien		    elt = elt->parent;
642950397Sobrien		  elt = elt->parent;
643050397Sobrien		  if (elt && tree_int_cst_lt (constructor_unfilled_index,
643150397Sobrien					      elt->purpose))
643250397Sobrien		    {
643350397Sobrien		      next = elt->purpose;
643450397Sobrien		      break;
643550397Sobrien		    }
643650397Sobrien		}
643750397Sobrien	    }
643818334Speter	}
643918334Speter      else if (TREE_CODE (constructor_type) == RECORD_TYPE
644018334Speter	       || TREE_CODE (constructor_type) == UNION_TYPE)
644118334Speter	{
644290075Sobrien	  tree ctor_unfilled_bitpos, elt_bitpos;
644390075Sobrien
644450397Sobrien	  /* If the current record is complete we are done.  */
644550397Sobrien	  if (constructor_unfilled_fields == 0)
644650397Sobrien	    break;
644790075Sobrien
644890075Sobrien	  ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields);
644990075Sobrien	  elt_bitpos = bit_position (elt->purpose);
645090075Sobrien	  /* We can't compare fields here because there might be empty
645190075Sobrien	     fields in between.  */
645290075Sobrien	  if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
645318334Speter	    {
645490075Sobrien	      constructor_unfilled_fields = elt->purpose;
645590075Sobrien	      output_init_element (elt->value, TREE_TYPE (elt->purpose),
645690075Sobrien				   elt->purpose, 0);
645718334Speter	    }
645890075Sobrien	  else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
645950397Sobrien	    {
646050397Sobrien	      /* Advance to the next smaller node.  */
646150397Sobrien	      if (elt->left)
646250397Sobrien		elt = elt->left;
646350397Sobrien	      else
646450397Sobrien		{
646550397Sobrien		  /* We have reached the smallest node bigger than the
646650397Sobrien		     current unfilled field.  Fill the space first.  */
646750397Sobrien		  next = elt->purpose;
646850397Sobrien		  break;
646950397Sobrien		}
647050397Sobrien	    }
647150397Sobrien	  else
647250397Sobrien	    {
647350397Sobrien	      /* Advance to the next bigger node.  */
647450397Sobrien	      if (elt->right)
647550397Sobrien		elt = elt->right;
647650397Sobrien	      else
647750397Sobrien		{
647850397Sobrien		  /* We have reached the biggest node in a subtree.  Find
647950397Sobrien		     the parent of it, which is the next bigger node.  */
648050397Sobrien		  while (elt->parent && elt->parent->right == elt)
648150397Sobrien		    elt = elt->parent;
648250397Sobrien		  elt = elt->parent;
648350397Sobrien		  if (elt
648490075Sobrien		      && (tree_int_cst_lt (ctor_unfilled_bitpos,
648590075Sobrien					   bit_position (elt->purpose))))
648650397Sobrien		    {
648750397Sobrien		      next = elt->purpose;
648850397Sobrien		      break;
648950397Sobrien		    }
649050397Sobrien		}
649150397Sobrien	    }
649218334Speter	}
649318334Speter    }
649418334Speter
649518334Speter  /* Ordinarily return, but not if we want to output all
649618334Speter     and there are elements left.  */
649718334Speter  if (! (all && next != 0))
649818334Speter    return;
649918334Speter
650090075Sobrien  /* If it's not incremental, just skip over the gap, so that after
650190075Sobrien     jumping to retry we will output the next successive element.  */
650290075Sobrien  if (TREE_CODE (constructor_type) == RECORD_TYPE
650390075Sobrien      || TREE_CODE (constructor_type) == UNION_TYPE)
650490075Sobrien    constructor_unfilled_fields = next;
650590075Sobrien  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
650690075Sobrien    constructor_unfilled_index = next;
650718334Speter
650850397Sobrien  /* ELT now points to the node in the pending tree with the next
650950397Sobrien     initializer to output.  */
651018334Speter  goto retry;
651118334Speter}
651218334Speter
651318334Speter/* Add one non-braced element to the current constructor level.
651418334Speter   This adjusts the current position within the constructor's type.
651518334Speter   This may also start or terminate implicit levels
651618334Speter   to handle a partly-braced initializer.
651718334Speter
651818334Speter   Once this has found the correct level for the new element,
651990075Sobrien   it calls output_init_element.  */
652018334Speter
652118334Spetervoid
652218334Speterprocess_init_element (value)
652318334Speter     tree value;
652418334Speter{
652518334Speter  tree orig_value = value;
652618334Speter  int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
652718334Speter
652890075Sobrien  designator_depth = 0;
652990075Sobrien  designator_errorneous = 0;
653090075Sobrien
653118334Speter  /* Handle superfluous braces around string cst as in
653218334Speter     char x[] = {"foo"}; */
653318334Speter  if (string_flag
653418334Speter      && constructor_type
653518334Speter      && TREE_CODE (constructor_type) == ARRAY_TYPE
653618334Speter      && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE
653718334Speter      && integer_zerop (constructor_unfilled_index))
653818334Speter    {
653990075Sobrien      if (constructor_stack->replacement_value)
654090075Sobrien        error_init ("excess elements in char array initializer");
654118334Speter      constructor_stack->replacement_value = value;
654218334Speter      return;
654318334Speter    }
654418334Speter
654518334Speter  if (constructor_stack->replacement_value != 0)
654618334Speter    {
654752284Sobrien      error_init ("excess elements in struct initializer");
654818334Speter      return;
654918334Speter    }
655018334Speter
655118334Speter  /* Ignore elements of a brace group if it is entirely superfluous
655218334Speter     and has already been diagnosed.  */
655318334Speter  if (constructor_type == 0)
655418334Speter    return;
655518334Speter
655618334Speter  /* If we've exhausted any levels that didn't have braces,
655718334Speter     pop them now.  */
655818334Speter  while (constructor_stack->implicit)
655918334Speter    {
656018334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
656118334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
656218334Speter	  && constructor_fields == 0)
656318334Speter	process_init_element (pop_init_level (1));
656418334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
656550397Sobrien	       && (constructor_max_index == 0
656650397Sobrien		   || tree_int_cst_lt (constructor_max_index,
656750397Sobrien				       constructor_index)))
656818334Speter	process_init_element (pop_init_level (1));
656918334Speter      else
657018334Speter	break;
657118334Speter    }
657218334Speter
657390075Sobrien  /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once.  */
657490075Sobrien  if (constructor_range_stack)
657590075Sobrien    {
657690075Sobrien      /* If value is a compound literal and we'll be just using its
657790075Sobrien	 content, don't put it into a SAVE_EXPR.  */
657890075Sobrien      if (TREE_CODE (value) != COMPOUND_LITERAL_EXPR
657990075Sobrien	  || !require_constant_value
658090075Sobrien	  || flag_isoc99)
658190075Sobrien	value = save_expr (value);
658290075Sobrien    }
658390075Sobrien
658418334Speter  while (1)
658518334Speter    {
658618334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE)
658718334Speter	{
658818334Speter	  tree fieldtype;
658918334Speter	  enum tree_code fieldcode;
659018334Speter
659118334Speter	  if (constructor_fields == 0)
659218334Speter	    {
659352284Sobrien	      pedwarn_init ("excess elements in struct initializer");
659418334Speter	      break;
659518334Speter	    }
659618334Speter
659718334Speter	  fieldtype = TREE_TYPE (constructor_fields);
659818334Speter	  if (fieldtype != error_mark_node)
659918334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
660018334Speter	  fieldcode = TREE_CODE (fieldtype);
660118334Speter
660296263Sobrien	  /* Error for non-static initialization of a flexible array member.  */
660396263Sobrien	  if (fieldcode == ARRAY_TYPE
660496263Sobrien	      && !require_constant_value
660596263Sobrien	      && TYPE_SIZE (fieldtype) == NULL_TREE
660696263Sobrien	      && TREE_CHAIN (constructor_fields) == NULL_TREE)
660796263Sobrien	    {
660896263Sobrien	      error_init ("non-static initialization of a flexible array member");
660996263Sobrien	      break;
661096263Sobrien	    }
661196263Sobrien
661218334Speter	  /* Accept a string constant to initialize a subarray.  */
661318334Speter	  if (value != 0
661418334Speter	      && fieldcode == ARRAY_TYPE
661518334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
661618334Speter	      && string_flag)
661718334Speter	    value = orig_value;
661818334Speter	  /* Otherwise, if we have come to a subaggregate,
661918334Speter	     and we don't have an element of its type, push into it.  */
662018334Speter	  else if (value != 0 && !constructor_no_implicit
662118334Speter		   && value != error_mark_node
662218334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
662318334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
662418334Speter		       || fieldcode == UNION_TYPE))
662518334Speter	    {
662618334Speter	      push_init_level (1);
662718334Speter	      continue;
662818334Speter	    }
662918334Speter
663018334Speter	  if (value)
663118334Speter	    {
663218334Speter	      push_member_name (constructor_fields);
663318334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
663418334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
663518334Speter	    }
663618334Speter	  else
663718334Speter	    /* Do the bookkeeping for an element that was
663818334Speter	       directly output as a constructor.  */
663918334Speter	    {
664018334Speter	      /* For a record, keep track of end position of last field.  */
664190075Sobrien	      if (DECL_SIZE (constructor_fields))
664290075Sobrien	        constructor_bit_index
664390075Sobrien		  = size_binop (PLUS_EXPR,
664490075Sobrien			        bit_position (constructor_fields),
664590075Sobrien			        DECL_SIZE (constructor_fields));
664618334Speter
664718334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
664890075Sobrien	      /* Skip any nameless bit fields.  */
664990075Sobrien	      while (constructor_unfilled_fields != 0
665090075Sobrien		     && DECL_C_BIT_FIELD (constructor_unfilled_fields)
665190075Sobrien		     && DECL_NAME (constructor_unfilled_fields) == 0)
665290075Sobrien		constructor_unfilled_fields =
665390075Sobrien		  TREE_CHAIN (constructor_unfilled_fields);
665418334Speter	    }
665518334Speter
665618334Speter	  constructor_fields = TREE_CHAIN (constructor_fields);
665718334Speter	  /* Skip any nameless bit fields at the beginning.  */
665850397Sobrien	  while (constructor_fields != 0
665950397Sobrien		 && DECL_C_BIT_FIELD (constructor_fields)
666018334Speter		 && DECL_NAME (constructor_fields) == 0)
666118334Speter	    constructor_fields = TREE_CHAIN (constructor_fields);
666218334Speter	}
666390075Sobrien      else if (TREE_CODE (constructor_type) == UNION_TYPE)
666418334Speter	{
666518334Speter	  tree fieldtype;
666618334Speter	  enum tree_code fieldcode;
666718334Speter
666818334Speter	  if (constructor_fields == 0)
666918334Speter	    {
667052284Sobrien	      pedwarn_init ("excess elements in union initializer");
667118334Speter	      break;
667218334Speter	    }
667318334Speter
667418334Speter	  fieldtype = TREE_TYPE (constructor_fields);
667518334Speter	  if (fieldtype != error_mark_node)
667618334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
667718334Speter	  fieldcode = TREE_CODE (fieldtype);
667818334Speter
667990075Sobrien	  /* Warn that traditional C rejects initialization of unions.
668090075Sobrien	     We skip the warning if the value is zero.  This is done
668190075Sobrien	     under the assumption that the zero initializer in user
668290075Sobrien	     code appears conditioned on e.g. __STDC__ to avoid
668390075Sobrien	     "missing initializer" warnings and relies on default
668490075Sobrien	     initialization to zero in the traditional C case.
668590075Sobrien	     We also skip the warning if the initializer is designated,
668690075Sobrien	     again on the assumption that this must be conditional on
668790075Sobrien	     __STDC__ anyway (and we've already complained about the
668890075Sobrien	     member-designator already).  */
668990075Sobrien	  if (warn_traditional && !in_system_header && !constructor_designated
669090075Sobrien	      && !(value && (integer_zerop (value) || real_zerop (value))))
669190075Sobrien	    warning ("traditional C rejects initialization of unions");
669290075Sobrien
669318334Speter	  /* Accept a string constant to initialize a subarray.  */
669418334Speter	  if (value != 0
669518334Speter	      && fieldcode == ARRAY_TYPE
669618334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
669718334Speter	      && string_flag)
669818334Speter	    value = orig_value;
669918334Speter	  /* Otherwise, if we have come to a subaggregate,
670018334Speter	     and we don't have an element of its type, push into it.  */
670118334Speter	  else if (value != 0 && !constructor_no_implicit
670218334Speter		   && value != error_mark_node
670318334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
670418334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
670518334Speter		       || fieldcode == UNION_TYPE))
670618334Speter	    {
670718334Speter	      push_init_level (1);
670818334Speter	      continue;
670918334Speter	    }
671018334Speter
671118334Speter	  if (value)
671218334Speter	    {
671318334Speter	      push_member_name (constructor_fields);
671418334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
671518334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
671618334Speter	    }
671718334Speter	  else
671818334Speter	    /* Do the bookkeeping for an element that was
671918334Speter	       directly output as a constructor.  */
672018334Speter	    {
672190075Sobrien	      constructor_bit_index = DECL_SIZE (constructor_fields);
672218334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
672318334Speter	    }
672418334Speter
672518334Speter	  constructor_fields = 0;
672618334Speter	}
672790075Sobrien      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
672818334Speter	{
672918334Speter	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
673018334Speter	  enum tree_code eltcode = TREE_CODE (elttype);
673118334Speter
673218334Speter	  /* Accept a string constant to initialize a subarray.  */
673318334Speter	  if (value != 0
673418334Speter	      && eltcode == ARRAY_TYPE
673518334Speter	      && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE
673618334Speter	      && string_flag)
673718334Speter	    value = orig_value;
673818334Speter	  /* Otherwise, if we have come to a subaggregate,
673918334Speter	     and we don't have an element of its type, push into it.  */
674018334Speter	  else if (value != 0 && !constructor_no_implicit
674118334Speter		   && value != error_mark_node
674218334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
674318334Speter		   && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
674418334Speter		       || eltcode == UNION_TYPE))
674518334Speter	    {
674618334Speter	      push_init_level (1);
674718334Speter	      continue;
674818334Speter	    }
674918334Speter
675018334Speter	  if (constructor_max_index != 0
675190075Sobrien	      && (tree_int_cst_lt (constructor_max_index, constructor_index)
675290075Sobrien		  || integer_all_onesp (constructor_max_index)))
675318334Speter	    {
675452284Sobrien	      pedwarn_init ("excess elements in array initializer");
675518334Speter	      break;
675618334Speter	    }
675718334Speter
675890075Sobrien	  /* Now output the actual element.  */
675990075Sobrien	  if (value)
676050397Sobrien	    {
676190075Sobrien	      push_array_bounds (tree_low_cst (constructor_index, 0));
676290075Sobrien	      output_init_element (value, elttype, constructor_index, 1);
676390075Sobrien	      RESTORE_SPELLING_DEPTH (constructor_depth);
676450397Sobrien	    }
676550397Sobrien
676690075Sobrien	  constructor_index
676790075Sobrien	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
676818334Speter
676990075Sobrien	  if (! value)
677090075Sobrien	    /* If we are doing the bookkeeping for an element that was
677190075Sobrien	       directly output as a constructor, we must update
677290075Sobrien	       constructor_unfilled_index.  */
677390075Sobrien	    constructor_unfilled_index = constructor_index;
677418334Speter	}
677596263Sobrien      else if (TREE_CODE (constructor_type) == VECTOR_TYPE)
677696263Sobrien	{
677796263Sobrien	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
677818334Speter
677996263Sobrien         /* Do a basic check of initializer size.  Note that vectors
678096263Sobrien            always have a fixed size derived from their type.  */
678196263Sobrien	  if (tree_int_cst_lt (constructor_max_index, constructor_index))
678296263Sobrien	    {
678396263Sobrien	      pedwarn_init ("excess elements in vector initializer");
678496263Sobrien	      break;
678596263Sobrien	    }
678696263Sobrien
678796263Sobrien	  /* Now output the actual element.  */
678896263Sobrien	  if (value)
678996263Sobrien	    output_init_element (value, elttype, constructor_index, 1);
679096263Sobrien
679196263Sobrien	  constructor_index
679296263Sobrien	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
679396263Sobrien
679496263Sobrien	  if (! value)
679596263Sobrien	    /* If we are doing the bookkeeping for an element that was
679696263Sobrien	       directly output as a constructor, we must update
679796263Sobrien	       constructor_unfilled_index.  */
679896263Sobrien	    constructor_unfilled_index = constructor_index;
679996263Sobrien	}
680096263Sobrien
680118334Speter      /* Handle the sole element allowed in a braced initializer
680218334Speter	 for a scalar variable.  */
680390075Sobrien      else if (constructor_fields == 0)
680418334Speter	{
680552284Sobrien	  pedwarn_init ("excess elements in scalar initializer");
680618334Speter	  break;
680718334Speter	}
680890075Sobrien      else
680990075Sobrien	{
681090075Sobrien	  if (value)
681190075Sobrien	    output_init_element (value, constructor_type, NULL_TREE, 1);
681290075Sobrien	  constructor_fields = 0;
681390075Sobrien	}
681418334Speter
681590075Sobrien      /* Handle range initializers either at this level or anywhere higher
681690075Sobrien	 in the designator stack.  */
681790075Sobrien      if (constructor_range_stack)
681890075Sobrien	{
681990075Sobrien	  struct constructor_range_stack *p, *range_stack;
682090075Sobrien	  int finish = 0;
682190075Sobrien
682290075Sobrien	  range_stack = constructor_range_stack;
682390075Sobrien	  constructor_range_stack = 0;
682490075Sobrien	  while (constructor_stack != range_stack->stack)
682590075Sobrien	    {
682690075Sobrien	      if (!constructor_stack->implicit)
682790075Sobrien		abort ();
682890075Sobrien	      process_init_element (pop_init_level (1));
682990075Sobrien	    }
683090075Sobrien	  for (p = range_stack;
683190075Sobrien	       !p->range_end || tree_int_cst_equal (p->index, p->range_end);
683290075Sobrien	       p = p->prev)
683390075Sobrien	    {
683490075Sobrien	      if (!constructor_stack->implicit)
683590075Sobrien		abort ();
683690075Sobrien	      process_init_element (pop_init_level (1));
683790075Sobrien	    }
683890075Sobrien
683990075Sobrien	  p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node);
684090075Sobrien	  if (tree_int_cst_equal (p->index, p->range_end) && !p->prev)
684190075Sobrien	    finish = 1;
684290075Sobrien
684390075Sobrien	  while (1)
684490075Sobrien	    {
684590075Sobrien	      constructor_index = p->index;
684690075Sobrien	      constructor_fields = p->fields;
684790075Sobrien	      if (finish && p->range_end && p->index == p->range_start)
684890075Sobrien		{
684990075Sobrien		  finish = 0;
685090075Sobrien		  p->prev = 0;
685190075Sobrien		}
685290075Sobrien	      p = p->next;
685390075Sobrien	      if (!p)
685490075Sobrien		break;
685590075Sobrien	      push_init_level (2);
685690075Sobrien	      p->stack = constructor_stack;
685790075Sobrien	      if (p->range_end && tree_int_cst_equal (p->index, p->range_end))
685890075Sobrien		p->index = p->range_start;
685990075Sobrien	    }
686090075Sobrien
686190075Sobrien	  if (!finish)
686290075Sobrien	    constructor_range_stack = range_stack;
686390075Sobrien	  continue;
686490075Sobrien	}
686590075Sobrien
686618334Speter      break;
686718334Speter    }
686818334Speter
686990075Sobrien  constructor_range_stack = 0;
687018334Speter}
687118334Speter
687290075Sobrien/* Build a simple asm-statement, from one string literal.  */
687390075Sobrientree
687490075Sobriensimple_asm_stmt (expr)
687590075Sobrien     tree expr;
687690075Sobrien{
687790075Sobrien  STRIP_NOPS (expr);
687890075Sobrien
687990075Sobrien  if (TREE_CODE (expr) == ADDR_EXPR)
688090075Sobrien    expr = TREE_OPERAND (expr, 0);
688190075Sobrien
688290075Sobrien  if (TREE_CODE (expr) == STRING_CST)
688390075Sobrien    {
688490075Sobrien      tree stmt;
688590075Sobrien
688690075Sobrien      if (TREE_CHAIN (expr))
688790075Sobrien	expr = combine_strings (expr);
688890075Sobrien      stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr,
688990075Sobrien				   NULL_TREE, NULL_TREE,
689090075Sobrien				   NULL_TREE));
689190075Sobrien      ASM_INPUT_P (stmt) = 1;
689290075Sobrien      return stmt;
689390075Sobrien    }
689490075Sobrien
689590075Sobrien  error ("argument of `asm' is not a constant string");
689690075Sobrien  return NULL_TREE;
689790075Sobrien}
689890075Sobrien
689990075Sobrien/* Build an asm-statement, whose components are a CV_QUALIFIER, a
690090075Sobrien   STRING, some OUTPUTS, some INPUTS, and some CLOBBERS.  */
690190075Sobrien
690290075Sobrientree
690390075Sobrienbuild_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
690490075Sobrien     tree cv_qualifier;
690590075Sobrien     tree string;
690690075Sobrien     tree outputs;
690790075Sobrien     tree inputs;
690890075Sobrien     tree clobbers;
690990075Sobrien{
691090075Sobrien  tree tail;
691190075Sobrien
691290075Sobrien  if (TREE_CHAIN (string))
691390075Sobrien    string = combine_strings (string);
691490075Sobrien  if (TREE_CODE (string) != STRING_CST)
691590075Sobrien    {
691690075Sobrien      error ("asm template is not a string constant");
691790075Sobrien      return NULL_TREE;
691890075Sobrien    }
691990075Sobrien
692090075Sobrien  if (cv_qualifier != NULL_TREE
692190075Sobrien      && cv_qualifier != ridpointers[(int) RID_VOLATILE])
692290075Sobrien    {
692390075Sobrien      warning ("%s qualifier ignored on asm",
692490075Sobrien	       IDENTIFIER_POINTER (cv_qualifier));
692590075Sobrien      cv_qualifier = NULL_TREE;
692690075Sobrien    }
692790075Sobrien
692890075Sobrien  /* We can remove output conversions that change the type,
692990075Sobrien     but not the mode.  */
693090075Sobrien  for (tail = outputs; tail; tail = TREE_CHAIN (tail))
693190075Sobrien    {
693290075Sobrien      tree output = TREE_VALUE (tail);
693390075Sobrien
693490075Sobrien      STRIP_NOPS (output);
693590075Sobrien      TREE_VALUE (tail) = output;
693690075Sobrien
693790075Sobrien      /* Allow conversions as LHS here.  build_modify_expr as called below
693890075Sobrien	 will do the right thing with them.  */
693990075Sobrien      while (TREE_CODE (output) == NOP_EXPR
694090075Sobrien	     || TREE_CODE (output) == CONVERT_EXPR
694190075Sobrien	     || TREE_CODE (output) == FLOAT_EXPR
694290075Sobrien	     || TREE_CODE (output) == FIX_TRUNC_EXPR
694390075Sobrien	     || TREE_CODE (output) == FIX_FLOOR_EXPR
694490075Sobrien	     || TREE_CODE (output) == FIX_ROUND_EXPR
694590075Sobrien	     || TREE_CODE (output) == FIX_CEIL_EXPR)
694690075Sobrien	output = TREE_OPERAND (output, 0);
694790075Sobrien
694890075Sobrien      lvalue_or_else (TREE_VALUE (tail), "invalid lvalue in asm statement");
694990075Sobrien    }
695090075Sobrien
695190075Sobrien  /* Remove output conversions that change the type but not the mode.  */
695290075Sobrien  for (tail = outputs; tail; tail = TREE_CHAIN (tail))
695390075Sobrien    {
695490075Sobrien      tree output = TREE_VALUE (tail);
695590075Sobrien      STRIP_NOPS (output);
695690075Sobrien      TREE_VALUE (tail) = output;
695790075Sobrien    }
695890075Sobrien
695990075Sobrien  /* Perform default conversions on array and function inputs.
696090075Sobrien     Don't do this for other types as it would screw up operands
696190075Sobrien     expected to be in memory.  */
696290075Sobrien  for (tail = inputs; tail; tail = TREE_CHAIN (tail))
696390075Sobrien    TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
696490075Sobrien
696590075Sobrien  return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string,
696690075Sobrien			       outputs, inputs, clobbers));
696790075Sobrien}
696890075Sobrien
696918334Speter/* Expand an ASM statement with operands, handling output operands
697018334Speter   that are not variables or INDIRECT_REFS by transforming such
697118334Speter   cases into cases that expand_asm_operands can handle.
697218334Speter
697318334Speter   Arguments are same as for expand_asm_operands.  */
697418334Speter
697518334Spetervoid
697618334Speterc_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
697718334Speter     tree string, outputs, inputs, clobbers;
697818334Speter     int vol;
697990075Sobrien     const char *filename;
698018334Speter     int line;
698118334Speter{
698218334Speter  int noutputs = list_length (outputs);
698390075Sobrien  int i;
698418334Speter  /* o[I] is the place that output number I should be written.  */
698590075Sobrien  tree *o = (tree *) alloca (noutputs * sizeof (tree));
698690075Sobrien  tree tail;
698718334Speter
698818334Speter  /* Record the contents of OUTPUTS before it is modified.  */
698918334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
699018334Speter    o[i] = TREE_VALUE (tail);
699118334Speter
699290075Sobrien  /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
699390075Sobrien     OUTPUTS some trees for where the values were actually stored.  */
699418334Speter  expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
699518334Speter
699618334Speter  /* Copy all the intermediate outputs into the specified outputs.  */
699718334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
699818334Speter    {
699918334Speter      if (o[i] != TREE_VALUE (tail))
700018334Speter	{
700118334Speter	  expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
700250397Sobrien		       NULL_RTX, VOIDmode, EXPAND_NORMAL);
700318334Speter	  free_temp_slots ();
700490075Sobrien
700590075Sobrien	  /* Restore the original value so that it's correct the next
700690075Sobrien	     time we expand this function.  */
700790075Sobrien	  TREE_VALUE (tail) = o[i];
700818334Speter	}
700918334Speter      /* Detect modification of read-only values.
701018334Speter	 (Otherwise done by build_modify_expr.)  */
701118334Speter      else
701218334Speter	{
701318334Speter	  tree type = TREE_TYPE (o[i]);
701418334Speter	  if (TREE_READONLY (o[i])
701518334Speter	      || TYPE_READONLY (type)
701618334Speter	      || ((TREE_CODE (type) == RECORD_TYPE
701718334Speter		   || TREE_CODE (type) == UNION_TYPE)
701818334Speter		  && C_TYPE_FIELDS_READONLY (type)))
701918334Speter	    readonly_warning (o[i], "modification by `asm'");
702018334Speter	}
702118334Speter    }
702218334Speter
702318334Speter  /* Those MODIFY_EXPRs could do autoincrements.  */
702418334Speter  emit_queue ();
702518334Speter}
702618334Speter
702718334Speter/* Expand a C `return' statement.
702818334Speter   RETVAL is the expression for what to return,
702918334Speter   or a null pointer for `return;' with no value.  */
703018334Speter
703190075Sobrientree
703218334Speterc_expand_return (retval)
703318334Speter     tree retval;
703418334Speter{
703518334Speter  tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
703618334Speter
703718334Speter  if (TREE_THIS_VOLATILE (current_function_decl))
703818334Speter    warning ("function declared `noreturn' has a `return' statement");
703918334Speter
704018334Speter  if (!retval)
704118334Speter    {
704218334Speter      current_function_returns_null = 1;
704390075Sobrien      if ((warn_return_type || flag_isoc99)
704490075Sobrien	  && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
704590075Sobrien	pedwarn_c99 ("`return' with no value, in function returning non-void");
704618334Speter    }
704718334Speter  else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
704818334Speter    {
704918334Speter      current_function_returns_null = 1;
705018334Speter      if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
705118334Speter	pedwarn ("`return' with a value, in function returning void");
705218334Speter    }
705318334Speter  else
705418334Speter    {
705552284Sobrien      tree t = convert_for_assignment (valtype, retval, _("return"),
705618334Speter				       NULL_TREE, NULL_TREE, 0);
705718334Speter      tree res = DECL_RESULT (current_function_decl);
705818334Speter      tree inner;
705918334Speter
706096263Sobrien      current_function_returns_value = 1;
706118334Speter      if (t == error_mark_node)
706290075Sobrien	return NULL_TREE;
706318334Speter
706418334Speter      inner = t = convert (TREE_TYPE (res), t);
706518334Speter
706618334Speter      /* Strip any conversions, additions, and subtractions, and see if
706718334Speter	 we are returning the address of a local variable.  Warn if so.  */
706818334Speter      while (1)
706918334Speter	{
707018334Speter	  switch (TREE_CODE (inner))
707118334Speter	    {
707218334Speter	    case NOP_EXPR:   case NON_LVALUE_EXPR:  case CONVERT_EXPR:
707318334Speter	    case PLUS_EXPR:
707418334Speter	      inner = TREE_OPERAND (inner, 0);
707518334Speter	      continue;
707618334Speter
707718334Speter	    case MINUS_EXPR:
707818334Speter	      /* If the second operand of the MINUS_EXPR has a pointer
707918334Speter		 type (or is converted from it), this may be valid, so
708018334Speter		 don't give a warning.  */
708118334Speter	      {
708218334Speter		tree op1 = TREE_OPERAND (inner, 1);
708318334Speter
708418334Speter		while (! POINTER_TYPE_P (TREE_TYPE (op1))
708518334Speter		       && (TREE_CODE (op1) == NOP_EXPR
708618334Speter			   || TREE_CODE (op1) == NON_LVALUE_EXPR
708718334Speter			   || TREE_CODE (op1) == CONVERT_EXPR))
708818334Speter		  op1 = TREE_OPERAND (op1, 0);
708918334Speter
709018334Speter		if (POINTER_TYPE_P (TREE_TYPE (op1)))
709118334Speter		  break;
709218334Speter
709318334Speter		inner = TREE_OPERAND (inner, 0);
709418334Speter		continue;
709518334Speter	      }
709618334Speter
709718334Speter	    case ADDR_EXPR:
709818334Speter	      inner = TREE_OPERAND (inner, 0);
709918334Speter
710018334Speter	      while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
710118334Speter		inner = TREE_OPERAND (inner, 0);
710218334Speter
710318334Speter	      if (TREE_CODE (inner) == VAR_DECL
710418334Speter		  && ! DECL_EXTERNAL (inner)
710518334Speter		  && ! TREE_STATIC (inner)
710618334Speter		  && DECL_CONTEXT (inner) == current_function_decl)
710718334Speter		warning ("function returns address of local variable");
710818334Speter	      break;
710950397Sobrien
711050397Sobrien	    default:
711150397Sobrien	      break;
711218334Speter	    }
711318334Speter
711418334Speter	  break;
711518334Speter	}
711618334Speter
711790075Sobrien      retval = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
711818334Speter    }
711990075Sobrien
712090075Sobrien return add_stmt (build_return_stmt (retval));
712118334Speter}
712218334Speter
712390075Sobrienstruct c_switch {
712490075Sobrien  /* The SWITCH_STMT being built.  */
712590075Sobrien  tree switch_stmt;
712690075Sobrien  /* A splay-tree mapping the low element of a case range to the high
712790075Sobrien     element, or NULL_TREE if there is no high element.  Used to
712890075Sobrien     determine whether or not a new case label duplicates an old case
712990075Sobrien     label.  We need a tree, rather than simply a hash table, because
713090075Sobrien     of the GNU case range extension.  */
713190075Sobrien  splay_tree cases;
713290075Sobrien  /* The next node on the stack.  */
713390075Sobrien  struct c_switch *next;
713490075Sobrien};
713518334Speter
713690075Sobrien/* A stack of the currently active switch statements.  The innermost
713790075Sobrien   switch statement is on the top of the stack.  There is no need to
713890075Sobrien   mark the stack for garbage collection because it is only active
713990075Sobrien   during the processing of the body of a function, and we never
714090075Sobrien   collect at that point.  */
714190075Sobrien
714290075Sobrienstatic struct c_switch *switch_stack;
714390075Sobrien
714490075Sobrien/* Start a C switch statement, testing expression EXP.  Return the new
714590075Sobrien   SWITCH_STMT.  */
714690075Sobrien
714718334Spetertree
714890075Sobrienc_start_case (exp)
714918334Speter     tree exp;
715018334Speter{
715190075Sobrien  enum tree_code code;
715296263Sobrien  tree type, orig_type = error_mark_node;
715390075Sobrien  struct c_switch *cs;
715418334Speter
715590075Sobrien  if (exp != error_mark_node)
715618334Speter    {
715790075Sobrien      code = TREE_CODE (TREE_TYPE (exp));
715896263Sobrien      orig_type = TREE_TYPE (exp);
715990075Sobrien
716096263Sobrien      if (! INTEGRAL_TYPE_P (orig_type)
716190075Sobrien	  && code != ERROR_MARK)
716290075Sobrien	{
716390075Sobrien	  error ("switch quantity not an integer");
716490075Sobrien	  exp = integer_zero_node;
716590075Sobrien	}
716690075Sobrien      else
716790075Sobrien	{
716890075Sobrien	  type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
716990075Sobrien
717090075Sobrien	  if (warn_traditional && !in_system_header
717190075Sobrien	      && (type == long_integer_type_node
717290075Sobrien		  || type == long_unsigned_type_node))
717390075Sobrien	    warning ("`long' switch expression not converted to `int' in ISO C");
717490075Sobrien
717590075Sobrien	  exp = default_conversion (exp);
717690075Sobrien	  type = TREE_TYPE (exp);
717790075Sobrien	}
717818334Speter    }
717918334Speter
718090075Sobrien  /* Add this new SWITCH_STMT to the stack.  */
718190075Sobrien  cs = (struct c_switch *) xmalloc (sizeof (*cs));
718296263Sobrien  cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type);
718390075Sobrien  cs->cases = splay_tree_new (case_compare, NULL, NULL);
718490075Sobrien  cs->next = switch_stack;
718590075Sobrien  switch_stack = cs;
718618334Speter
718790075Sobrien  return add_stmt (switch_stack->switch_stmt);
718890075Sobrien}
718990075Sobrien
719090075Sobrien/* Process a case label.  */
719190075Sobrien
719290075Sobrientree
719390075Sobriendo_case (low_value, high_value)
719490075Sobrien     tree low_value;
719590075Sobrien     tree high_value;
719690075Sobrien{
719790075Sobrien  tree label = NULL_TREE;
719890075Sobrien
719990075Sobrien  if (switch_stack)
720090075Sobrien    {
720190075Sobrien      label = c_add_case_label (switch_stack->cases,
720290075Sobrien				SWITCH_COND (switch_stack->switch_stmt),
720390075Sobrien				low_value, high_value);
720490075Sobrien      if (label == error_mark_node)
720590075Sobrien	label = NULL_TREE;
720618334Speter    }
720790075Sobrien  else if (low_value)
720890075Sobrien    error ("case label not within a switch statement");
720990075Sobrien  else
721090075Sobrien    error ("`default' label not within a switch statement");
721118334Speter
721290075Sobrien  return label;
721390075Sobrien}
721418334Speter
721590075Sobrien/* Finish the switch statement.  */
721690075Sobrien
721790075Sobrienvoid
721890075Sobrienc_finish_case ()
721990075Sobrien{
722090075Sobrien  struct c_switch *cs = switch_stack;
722190075Sobrien
722290075Sobrien  RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt));
722390075Sobrien
722490075Sobrien  /* Pop the stack.  */
722590075Sobrien  switch_stack = switch_stack->next;
722690075Sobrien  splay_tree_delete (cs->cases);
722790075Sobrien  free (cs);
722818334Speter}
7229