c-typeck.c revision 52284
118334Speter/* Build expressions with type checking for C compiler.
250397Sobrien   Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2118334Speter
2218334Speter/* This file is part of the C front end.
2318334Speter   It contains routines to build C expressions given their operands,
2418334Speter   including computing the types of the result, C-specific error checks,
2518334Speter   and some optimization.
2618334Speter
2718334Speter   There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
2818334Speter   and to process initializations in declarations (since they work
2918334Speter   like a strange sort of assignment).  */
3018334Speter
3118334Speter#include "config.h"
3250397Sobrien#include "system.h"
3318334Speter#include "tree.h"
3418334Speter#include "c-tree.h"
3518334Speter#include "flags.h"
3618334Speter#include "output.h"
3750397Sobrien#include "rtl.h"
3850397Sobrien#include "expr.h"
3950397Sobrien#include "toplev.h"
4052284Sobrien#include "intl.h"
4118334Speter
4218334Speter/* Nonzero if we've already printed a "missing braces around initializer"
4318334Speter   message within this initializer.  */
4418334Speterstatic int missing_braces_mentioned;
4518334Speter
4650397Sobrienstatic tree qualify_type		PROTO((tree, tree));
4718334Speterstatic int comp_target_types		PROTO((tree, tree));
4818334Speterstatic int function_types_compatible_p	PROTO((tree, tree));
4918334Speterstatic int type_lists_compatible_p	PROTO((tree, tree));
5018334Speterstatic int self_promoting_type_p	PROTO((tree));
5118334Speterstatic tree decl_constant_value		PROTO((tree));
5218334Speterstatic tree lookup_field		PROTO((tree, tree, tree *));
5318334Speterstatic tree convert_arguments		PROTO((tree, tree, tree, tree));
5418334Speterstatic tree pointer_int_sum		PROTO((enum tree_code, tree, tree));
5518334Speterstatic tree pointer_diff		PROTO((tree, tree));
5618334Speterstatic tree unary_complex_lvalue	PROTO((enum tree_code, tree));
5718334Speterstatic void pedantic_lvalue_warning	PROTO((enum tree_code));
5818334Speterstatic tree internal_build_compound_expr PROTO((tree, int));
5952284Sobrienstatic tree convert_for_assignment	PROTO((tree, tree, const char *, tree,
6018334Speter					       tree, int));
6152284Sobrienstatic void warn_for_assignment		PROTO((const char *, const char *,
6252284Sobrien					       tree, int));
6318334Speterstatic tree valid_compound_expr_initializer PROTO((tree, tree));
6452284Sobrienstatic void push_string			PROTO((const char *));
6518334Speterstatic void push_member_name		PROTO((tree));
6618334Speterstatic void push_array_bounds		PROTO((int));
6718334Speterstatic int spelling_length		PROTO((void));
6818334Speterstatic char *print_spelling		PROTO((char *));
6952284Sobrienstatic void warning_init		PROTO((const char *));
7018334Speterstatic tree digest_init			PROTO((tree, tree, int, int));
7118334Speterstatic void check_init_type_bitfields	PROTO((tree));
7218334Speterstatic void output_init_element		PROTO((tree, tree, tree, int));
7318334Speterstatic void output_pending_init_elements PROTO((int));
7450397Sobrienstatic void add_pending_init		PROTO((tree, tree));
7550397Sobrienstatic int pending_init_member		PROTO((tree));
7618334Speter
7718334Speter/* Do `exp = require_complete_type (exp);' to make sure exp
7818334Speter   does not have an incomplete type.  (That includes void types.)  */
7918334Speter
8018334Spetertree
8118334Speterrequire_complete_type (value)
8218334Speter     tree value;
8318334Speter{
8418334Speter  tree type = TREE_TYPE (value);
8518334Speter
8652284Sobrien  if (TREE_CODE (value) == ERROR_MARK)
8752284Sobrien    return error_mark_node;
8852284Sobrien
8918334Speter  /* First, detect a valid value with a complete type.  */
9018334Speter  if (TYPE_SIZE (type) != 0
9118334Speter      && type != void_type_node)
9218334Speter    return value;
9318334Speter
9418334Speter  incomplete_type_error (value, type);
9518334Speter  return error_mark_node;
9618334Speter}
9718334Speter
9818334Speter/* Print an error message for invalid use of an incomplete type.
9918334Speter   VALUE is the expression that was used (or 0 if that isn't known)
10018334Speter   and TYPE is the type that was invalid.  */
10118334Speter
10218334Spetervoid
10318334Speterincomplete_type_error (value, type)
10418334Speter     tree value;
10518334Speter     tree type;
10618334Speter{
10752284Sobrien  const char *type_code_string;
10818334Speter
10918334Speter  /* Avoid duplicate error message.  */
11018334Speter  if (TREE_CODE (type) == ERROR_MARK)
11118334Speter    return;
11218334Speter
11318334Speter  if (value != 0 && (TREE_CODE (value) == VAR_DECL
11418334Speter		     || TREE_CODE (value) == PARM_DECL))
11518334Speter    error ("`%s' has an incomplete type",
11618334Speter	   IDENTIFIER_POINTER (DECL_NAME (value)));
11718334Speter  else
11818334Speter    {
11918334Speter    retry:
12018334Speter      /* We must print an error message.  Be clever about what it says.  */
12118334Speter
12218334Speter      switch (TREE_CODE (type))
12318334Speter	{
12418334Speter	case RECORD_TYPE:
12552284Sobrien	  type_code_string = "struct";
12618334Speter	  break;
12718334Speter
12818334Speter	case UNION_TYPE:
12952284Sobrien	  type_code_string = "union";
13018334Speter	  break;
13118334Speter
13218334Speter	case ENUMERAL_TYPE:
13352284Sobrien	  type_code_string = "enum";
13418334Speter	  break;
13518334Speter
13618334Speter	case VOID_TYPE:
13718334Speter	  error ("invalid use of void expression");
13818334Speter	  return;
13918334Speter
14018334Speter	case ARRAY_TYPE:
14118334Speter	  if (TYPE_DOMAIN (type))
14218334Speter	    {
14318334Speter	      type = TREE_TYPE (type);
14418334Speter	      goto retry;
14518334Speter	    }
14618334Speter	  error ("invalid use of array with unspecified bounds");
14718334Speter	  return;
14818334Speter
14918334Speter	default:
15018334Speter	  abort ();
15118334Speter	}
15218334Speter
15318334Speter      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
15452284Sobrien	error ("invalid use of undefined type `%s %s'",
15552284Sobrien	       type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
15618334Speter      else
15718334Speter	/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
15818334Speter	error ("invalid use of incomplete typedef `%s'",
15918334Speter	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
16018334Speter    }
16118334Speter}
16218334Speter
16318334Speter/* Return a variant of TYPE which has all the type qualifiers of LIKE
16418334Speter   as well as those of TYPE.  */
16518334Speter
16618334Speterstatic tree
16718334Speterqualify_type (type, like)
16818334Speter     tree type, like;
16918334Speter{
17052284Sobrien  return c_build_qualified_type (type, TYPE_QUALS (like));
17118334Speter}
17218334Speter
17318334Speter/* Return the common type of two types.
17418334Speter   We assume that comptypes has already been done and returned 1;
17518334Speter   if that isn't so, this may crash.  In particular, we assume that qualifiers
17618334Speter   match.
17718334Speter
17818334Speter   This is the type for the result of most arithmetic operations
17918334Speter   if the operands have the given two types.  */
18018334Speter
18118334Spetertree
18218334Spetercommon_type (t1, t2)
18318334Speter     tree t1, t2;
18418334Speter{
18518334Speter  register enum tree_code code1;
18618334Speter  register enum tree_code code2;
18718334Speter  tree attributes;
18818334Speter
18918334Speter  /* Save time if the two types are the same.  */
19018334Speter
19118334Speter  if (t1 == t2) return t1;
19218334Speter
19318334Speter  /* If one type is nonsense, use the other.  */
19418334Speter  if (t1 == error_mark_node)
19518334Speter    return t2;
19618334Speter  if (t2 == error_mark_node)
19718334Speter    return t1;
19818334Speter
19950397Sobrien  /* Merge the attributes.  */
20050397Sobrien  attributes = merge_machine_type_attributes (t1, t2);
20118334Speter
20218334Speter  /* Treat an enum type as the unsigned integer type of the same width.  */
20318334Speter
20418334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
20518334Speter    t1 = type_for_size (TYPE_PRECISION (t1), 1);
20618334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
20718334Speter    t2 = type_for_size (TYPE_PRECISION (t2), 1);
20818334Speter
20918334Speter  code1 = TREE_CODE (t1);
21018334Speter  code2 = TREE_CODE (t2);
21118334Speter
21218334Speter  /* If one type is complex, form the common type of the non-complex
21318334Speter     components, then make that complex.  Use T1 or T2 if it is the
21418334Speter     required type.  */
21518334Speter  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
21618334Speter    {
21718334Speter      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
21818334Speter      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
21918334Speter      tree subtype = common_type (subtype1, subtype2);
22018334Speter
22118334Speter      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
22218334Speter	return build_type_attribute_variant (t1, attributes);
22318334Speter      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
22418334Speter	return build_type_attribute_variant (t2, attributes);
22518334Speter      else
22618334Speter	return build_type_attribute_variant (build_complex_type (subtype),
22718334Speter					     attributes);
22818334Speter    }
22918334Speter
23018334Speter  switch (code1)
23118334Speter    {
23218334Speter    case INTEGER_TYPE:
23318334Speter    case REAL_TYPE:
23418334Speter      /* If only one is real, use it as the result.  */
23518334Speter
23618334Speter      if (code1 == REAL_TYPE && code2 != REAL_TYPE)
23718334Speter	return build_type_attribute_variant (t1, attributes);
23818334Speter
23918334Speter      if (code2 == REAL_TYPE && code1 != REAL_TYPE)
24018334Speter	return build_type_attribute_variant (t2, attributes);
24118334Speter
24218334Speter      /* Both real or both integers; use the one with greater precision.  */
24318334Speter
24418334Speter      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
24518334Speter	return build_type_attribute_variant (t1, attributes);
24618334Speter      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
24718334Speter	return build_type_attribute_variant (t2, attributes);
24818334Speter
24918334Speter      /* Same precision.  Prefer longs to ints even when same size.  */
25018334Speter
25118334Speter      if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
25218334Speter	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
25318334Speter	return build_type_attribute_variant (long_unsigned_type_node,
25418334Speter					     attributes);
25518334Speter
25618334Speter      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
25718334Speter	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
25818334Speter	{
25918334Speter	  /* But preserve unsignedness from the other type,
26018334Speter	     since long cannot hold all the values of an unsigned int.  */
26118334Speter	  if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
26218334Speter	     t1 = long_unsigned_type_node;
26318334Speter	  else
26418334Speter	     t1 = long_integer_type_node;
26518334Speter	  return build_type_attribute_variant (t1, attributes);
26618334Speter	}
26718334Speter
26850397Sobrien      /* Likewise, prefer long double to double even if same size.  */
26950397Sobrien      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
27050397Sobrien	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
27150397Sobrien	return build_type_attribute_variant (long_double_type_node,
27250397Sobrien					     attributes);
27350397Sobrien
27418334Speter      /* Otherwise prefer the unsigned one.  */
27518334Speter
27618334Speter      if (TREE_UNSIGNED (t1))
27718334Speter	return build_type_attribute_variant (t1, attributes);
27818334Speter      else
27918334Speter	return build_type_attribute_variant (t2, attributes);
28018334Speter
28118334Speter    case POINTER_TYPE:
28218334Speter      /* For two pointers, do this recursively on the target type,
28318334Speter	 and combine the qualifiers of the two types' targets.  */
28418334Speter      /* This code was turned off; I don't know why.
28518334Speter	 But ANSI C specifies doing this with the qualifiers.
28618334Speter	 So I turned it on again.  */
28718334Speter      {
28852284Sobrien	tree pointed_to_1 = TREE_TYPE (t1);
28952284Sobrien	tree pointed_to_2 = TREE_TYPE (t2);
29052284Sobrien	tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
29152284Sobrien				   TYPE_MAIN_VARIANT (pointed_to_2));
29252284Sobrien	t1 = build_pointer_type (c_build_qualified_type
29352284Sobrien				 (target,
29452284Sobrien				  TYPE_QUALS (pointed_to_1) |
29552284Sobrien				  TYPE_QUALS (pointed_to_2)));
29618334Speter	return build_type_attribute_variant (t1, attributes);
29718334Speter      }
29818334Speter#if 0
29918334Speter      t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
30018334Speter      return build_type_attribute_variant (t1, attributes);
30118334Speter#endif
30218334Speter
30318334Speter    case ARRAY_TYPE:
30418334Speter      {
30518334Speter	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
30618334Speter	/* Save space: see if the result is identical to one of the args.  */
30718334Speter	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
30818334Speter	  return build_type_attribute_variant (t1, attributes);
30918334Speter	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
31018334Speter	  return build_type_attribute_variant (t2, attributes);
31118334Speter	/* Merge the element types, and have a size if either arg has one.  */
31218334Speter	t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
31318334Speter	return build_type_attribute_variant (t1, attributes);
31418334Speter      }
31518334Speter
31618334Speter    case FUNCTION_TYPE:
31718334Speter      /* Function types: prefer the one that specified arg types.
31818334Speter	 If both do, merge the arg types.  Also merge the return types.  */
31918334Speter      {
32018334Speter	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
32118334Speter	tree p1 = TYPE_ARG_TYPES (t1);
32218334Speter	tree p2 = TYPE_ARG_TYPES (t2);
32318334Speter	int len;
32418334Speter	tree newargs, n;
32518334Speter	int i;
32618334Speter
32718334Speter	/* Save space: see if the result is identical to one of the args.  */
32818334Speter	if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2))
32918334Speter	  return build_type_attribute_variant (t1, attributes);
33018334Speter	if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1))
33118334Speter	  return build_type_attribute_variant (t2, attributes);
33218334Speter
33318334Speter	/* Simple way if one arg fails to specify argument types.  */
33418334Speter	if (TYPE_ARG_TYPES (t1) == 0)
33518334Speter	 {
33618334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2));
33718334Speter	   return build_type_attribute_variant (t1, attributes);
33818334Speter	 }
33918334Speter	if (TYPE_ARG_TYPES (t2) == 0)
34018334Speter	 {
34118334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1));
34218334Speter	   return build_type_attribute_variant (t1, attributes);
34318334Speter	 }
34418334Speter
34518334Speter	/* If both args specify argument types, we must merge the two
34618334Speter	   lists, argument by argument.  */
34718334Speter
34818334Speter	len = list_length (p1);
34918334Speter	newargs = 0;
35018334Speter
35118334Speter	for (i = 0; i < len; i++)
35218334Speter	  newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
35318334Speter
35418334Speter	n = newargs;
35518334Speter
35618334Speter	for (; p1;
35718334Speter	     p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
35818334Speter	  {
35918334Speter	    /* A null type means arg type is not specified.
36018334Speter	       Take whatever the other function type has.  */
36118334Speter	    if (TREE_VALUE (p1) == 0)
36218334Speter	      {
36318334Speter		TREE_VALUE (n) = TREE_VALUE (p2);
36418334Speter		goto parm_done;
36518334Speter	      }
36618334Speter	    if (TREE_VALUE (p2) == 0)
36718334Speter	      {
36818334Speter		TREE_VALUE (n) = TREE_VALUE (p1);
36918334Speter		goto parm_done;
37018334Speter	      }
37118334Speter
37218334Speter	    /* Given  wait (union {union wait *u; int *i} *)
37318334Speter	       and  wait (union wait *),
37418334Speter	       prefer  union wait *  as type of parm.  */
37518334Speter	    if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
37618334Speter		&& TREE_VALUE (p1) != TREE_VALUE (p2))
37718334Speter	      {
37818334Speter		tree memb;
37918334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p1));
38018334Speter		     memb; memb = TREE_CHAIN (memb))
38118334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
38218334Speter		    {
38318334Speter		      TREE_VALUE (n) = TREE_VALUE (p2);
38418334Speter		      if (pedantic)
38518334Speter			pedwarn ("function types not truly compatible in ANSI C");
38618334Speter		      goto parm_done;
38718334Speter		    }
38818334Speter	      }
38918334Speter	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
39018334Speter		&& TREE_VALUE (p2) != TREE_VALUE (p1))
39118334Speter	      {
39218334Speter		tree memb;
39318334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p2));
39418334Speter		     memb; memb = TREE_CHAIN (memb))
39518334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
39618334Speter		    {
39718334Speter		      TREE_VALUE (n) = TREE_VALUE (p1);
39818334Speter		      if (pedantic)
39918334Speter			pedwarn ("function types not truly compatible in ANSI C");
40018334Speter		      goto parm_done;
40118334Speter		    }
40218334Speter	      }
40318334Speter	    TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
40418334Speter	  parm_done: ;
40518334Speter	  }
40618334Speter
40718334Speter	t1 = build_function_type (valtype, newargs);
40850397Sobrien	/* ... falls through ...  */
40918334Speter      }
41018334Speter
41118334Speter    default:
41218334Speter      return build_type_attribute_variant (t1, attributes);
41318334Speter    }
41418334Speter
41518334Speter}
41618334Speter
41718334Speter/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
41818334Speter   or various other operations.  Return 2 if they are compatible
41918334Speter   but a warning may be needed if you use them together.  */
42018334Speter
42118334Speterint
42218334Spetercomptypes (type1, type2)
42318334Speter     tree type1, type2;
42418334Speter{
42518334Speter  register tree t1 = type1;
42618334Speter  register tree t2 = type2;
42718334Speter  int attrval, val;
42818334Speter
42918334Speter  /* Suppress errors caused by previously reported errors.  */
43018334Speter
43150397Sobrien  if (t1 == t2 || !t1 || !t2
43250397Sobrien      || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
43318334Speter    return 1;
43418334Speter
43518334Speter  /* Treat an enum type as the integer type of the same width and
43618334Speter     signedness.  */
43718334Speter
43818334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
43918334Speter    t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
44018334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
44118334Speter    t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
44218334Speter
44318334Speter  if (t1 == t2)
44418334Speter    return 1;
44518334Speter
44618334Speter  /* Different classes of types can't be compatible.  */
44718334Speter
44818334Speter  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
44918334Speter
45018334Speter  /* Qualifiers must match.  */
45118334Speter
45252284Sobrien  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
45318334Speter    return 0;
45418334Speter
45518334Speter  /* Allow for two different type nodes which have essentially the same
45618334Speter     definition.  Note that we already checked for equality of the type
45750397Sobrien     qualifiers (just above).  */
45818334Speter
45918334Speter  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
46018334Speter    return 1;
46118334Speter
46218334Speter#ifndef COMP_TYPE_ATTRIBUTES
46318334Speter#define COMP_TYPE_ATTRIBUTES(t1,t2)	1
46418334Speter#endif
46518334Speter
46618334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
46718334Speter  if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
46818334Speter     return 0;
46918334Speter
47018334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
47118334Speter  val = 0;
47218334Speter
47318334Speter  switch (TREE_CODE (t1))
47418334Speter    {
47518334Speter    case POINTER_TYPE:
47618334Speter      val = (TREE_TYPE (t1) == TREE_TYPE (t2)
47718334Speter	      ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
47818334Speter      break;
47918334Speter
48018334Speter    case FUNCTION_TYPE:
48118334Speter      val = function_types_compatible_p (t1, t2);
48218334Speter      break;
48318334Speter
48418334Speter    case ARRAY_TYPE:
48518334Speter      {
48618334Speter	tree d1 = TYPE_DOMAIN (t1);
48718334Speter	tree d2 = TYPE_DOMAIN (t2);
48818334Speter	val = 1;
48918334Speter
49018334Speter	/* Target types must match incl. qualifiers.  */
49118334Speter	if (TREE_TYPE (t1) != TREE_TYPE (t2)
49218334Speter	    && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
49318334Speter	  return 0;
49418334Speter
49518334Speter	/* Sizes must match unless one is missing or variable.  */
49618334Speter	if (d1 == 0 || d2 == 0 || d1 == d2
49718334Speter	    || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
49818334Speter	    || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
49918334Speter	    || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST
50018334Speter	    || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
50118334Speter	  break;
50218334Speter
50318334Speter	if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
50418334Speter		  == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
50518334Speter		 && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
50618334Speter		     == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
50718334Speter		 && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
50818334Speter		     == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
50918334Speter		 && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
51018334Speter		     == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))))
51118334Speter	   val = 0;
51218334Speter        break;
51318334Speter      }
51418334Speter
51518334Speter    case RECORD_TYPE:
51618334Speter      if (maybe_objc_comptypes (t1, t2, 0) == 1)
51718334Speter	val = 1;
51818334Speter      break;
51950397Sobrien
52050397Sobrien    default:
52150397Sobrien      break;
52218334Speter    }
52318334Speter  return attrval == 2 && val == 1 ? 2 : val;
52418334Speter}
52518334Speter
52618334Speter/* Return 1 if TTL and TTR are pointers to types that are equivalent,
52718334Speter   ignoring their qualifiers.  */
52818334Speter
52918334Speterstatic int
53018334Spetercomp_target_types (ttl, ttr)
53118334Speter     tree ttl, ttr;
53218334Speter{
53318334Speter  int val;
53418334Speter
53518334Speter  /* Give maybe_objc_comptypes a crack at letting these types through.  */
53650397Sobrien  if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0)
53718334Speter    return val;
53818334Speter
53918334Speter  val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
54018334Speter		   TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
54118334Speter
54218334Speter  if (val == 2 && pedantic)
54318334Speter    pedwarn ("types are not quite compatible");
54418334Speter  return val;
54518334Speter}
54618334Speter
54718334Speter/* Subroutines of `comptypes'.  */
54818334Speter
54918334Speter/* Return 1 if two function types F1 and F2 are compatible.
55018334Speter   If either type specifies no argument types,
55118334Speter   the other must specify a fixed number of self-promoting arg types.
55218334Speter   Otherwise, if one type specifies only the number of arguments,
55318334Speter   the other must specify that number of self-promoting arg types.
55418334Speter   Otherwise, the argument types must match.  */
55518334Speter
55618334Speterstatic int
55718334Speterfunction_types_compatible_p (f1, f2)
55818334Speter     tree f1, f2;
55918334Speter{
56018334Speter  tree args1, args2;
56118334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
56218334Speter  int val = 1;
56318334Speter  int val1;
56418334Speter
56518334Speter  if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
56618334Speter	|| (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
56718334Speter    return 0;
56818334Speter
56918334Speter  args1 = TYPE_ARG_TYPES (f1);
57018334Speter  args2 = TYPE_ARG_TYPES (f2);
57118334Speter
57218334Speter  /* An unspecified parmlist matches any specified parmlist
57318334Speter     whose argument types don't need default promotions.  */
57418334Speter
57518334Speter  if (args1 == 0)
57618334Speter    {
57718334Speter      if (!self_promoting_args_p (args2))
57818334Speter	return 0;
57918334Speter      /* If one of these types comes from a non-prototype fn definition,
58018334Speter	 compare that with the other type's arglist.
58118334Speter	 If they don't match, ask for a warning (but no error).  */
58218334Speter      if (TYPE_ACTUAL_ARG_TYPES (f1)
58318334Speter	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
58418334Speter	val = 2;
58518334Speter      return val;
58618334Speter    }
58718334Speter  if (args2 == 0)
58818334Speter    {
58918334Speter      if (!self_promoting_args_p (args1))
59018334Speter	return 0;
59118334Speter      if (TYPE_ACTUAL_ARG_TYPES (f2)
59218334Speter	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
59318334Speter	val = 2;
59418334Speter      return val;
59518334Speter    }
59618334Speter
59718334Speter  /* Both types have argument lists: compare them and propagate results.  */
59818334Speter  val1 = type_lists_compatible_p (args1, args2);
59918334Speter  return val1 != 1 ? val1 : val;
60018334Speter}
60118334Speter
60218334Speter/* Check two lists of types for compatibility,
60318334Speter   returning 0 for incompatible, 1 for compatible,
60418334Speter   or 2 for compatible with warning.  */
60518334Speter
60618334Speterstatic int
60718334Spetertype_lists_compatible_p (args1, args2)
60818334Speter     tree args1, args2;
60918334Speter{
61018334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
61118334Speter  int val = 1;
61218334Speter  int newval = 0;
61318334Speter
61418334Speter  while (1)
61518334Speter    {
61618334Speter      if (args1 == 0 && args2 == 0)
61718334Speter	return val;
61818334Speter      /* If one list is shorter than the other,
61918334Speter	 they fail to match.  */
62018334Speter      if (args1 == 0 || args2 == 0)
62118334Speter	return 0;
62218334Speter      /* A null pointer instead of a type
62318334Speter	 means there is supposed to be an argument
62418334Speter	 but nothing is specified about what type it has.
62518334Speter	 So match anything that self-promotes.  */
62618334Speter      if (TREE_VALUE (args1) == 0)
62718334Speter	{
62818334Speter	  if (! self_promoting_type_p (TREE_VALUE (args2)))
62918334Speter	    return 0;
63018334Speter	}
63118334Speter      else if (TREE_VALUE (args2) == 0)
63218334Speter	{
63318334Speter	  if (! self_promoting_type_p (TREE_VALUE (args1)))
63418334Speter	    return 0;
63518334Speter	}
63618334Speter      else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
63718334Speter	{
63818334Speter	  /* Allow  wait (union {union wait *u; int *i} *)
63918334Speter	     and  wait (union wait *)  to be compatible.  */
64018334Speter	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
64118334Speter	      && (TYPE_NAME (TREE_VALUE (args1)) == 0
64218334Speter		  || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
64318334Speter	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
64418334Speter	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
64518334Speter				     TYPE_SIZE (TREE_VALUE (args2))))
64618334Speter	    {
64718334Speter	      tree memb;
64818334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));
64918334Speter		   memb; memb = TREE_CHAIN (memb))
65018334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
65118334Speter		  break;
65218334Speter	      if (memb == 0)
65318334Speter		return 0;
65418334Speter	    }
65518334Speter	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
65618334Speter		   && (TYPE_NAME (TREE_VALUE (args2)) == 0
65718334Speter		       || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
65818334Speter		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
65918334Speter		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
66018334Speter					  TYPE_SIZE (TREE_VALUE (args1))))
66118334Speter	    {
66218334Speter	      tree memb;
66318334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));
66418334Speter		   memb; memb = TREE_CHAIN (memb))
66518334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
66618334Speter		  break;
66718334Speter	      if (memb == 0)
66818334Speter		return 0;
66918334Speter	    }
67018334Speter	  else
67118334Speter	    return 0;
67218334Speter	}
67318334Speter
67418334Speter      /* comptypes said ok, but record if it said to warn.  */
67518334Speter      if (newval > val)
67618334Speter	val = newval;
67718334Speter
67818334Speter      args1 = TREE_CHAIN (args1);
67918334Speter      args2 = TREE_CHAIN (args2);
68018334Speter    }
68118334Speter}
68218334Speter
68318334Speter/* Return 1 if PARMS specifies a fixed number of parameters
68418334Speter   and none of their types is affected by default promotions.  */
68518334Speter
68618334Speterint
68718334Speterself_promoting_args_p (parms)
68818334Speter     tree parms;
68918334Speter{
69018334Speter  register tree t;
69118334Speter  for (t = parms; t; t = TREE_CHAIN (t))
69218334Speter    {
69318334Speter      register tree type = TREE_VALUE (t);
69418334Speter
69518334Speter      if (TREE_CHAIN (t) == 0 && type != void_type_node)
69618334Speter	return 0;
69718334Speter
69818334Speter      if (type == 0)
69918334Speter	return 0;
70018334Speter
70118334Speter      if (TYPE_MAIN_VARIANT (type) == float_type_node)
70218334Speter	return 0;
70318334Speter
70418334Speter      if (C_PROMOTING_INTEGER_TYPE_P (type))
70518334Speter	return 0;
70618334Speter    }
70718334Speter  return 1;
70818334Speter}
70918334Speter
71018334Speter/* Return 1 if TYPE is not affected by default promotions.  */
71118334Speter
71218334Speterstatic int
71318334Speterself_promoting_type_p (type)
71418334Speter     tree type;
71518334Speter{
71618334Speter  if (TYPE_MAIN_VARIANT (type) == float_type_node)
71718334Speter    return 0;
71818334Speter
71918334Speter  if (C_PROMOTING_INTEGER_TYPE_P (type))
72018334Speter    return 0;
72118334Speter
72218334Speter  return 1;
72318334Speter}
72418334Speter
72518334Speter/* Return an unsigned type the same as TYPE in other respects.  */
72618334Speter
72718334Spetertree
72818334Speterunsigned_type (type)
72918334Speter     tree type;
73018334Speter{
73118334Speter  tree type1 = TYPE_MAIN_VARIANT (type);
73218334Speter  if (type1 == signed_char_type_node || type1 == char_type_node)
73318334Speter    return unsigned_char_type_node;
73418334Speter  if (type1 == integer_type_node)
73518334Speter    return unsigned_type_node;
73618334Speter  if (type1 == short_integer_type_node)
73718334Speter    return short_unsigned_type_node;
73818334Speter  if (type1 == long_integer_type_node)
73918334Speter    return long_unsigned_type_node;
74018334Speter  if (type1 == long_long_integer_type_node)
74118334Speter    return long_long_unsigned_type_node;
74218334Speter  if (type1 == intDI_type_node)
74318334Speter    return unsigned_intDI_type_node;
74418334Speter  if (type1 == intSI_type_node)
74518334Speter    return unsigned_intSI_type_node;
74618334Speter  if (type1 == intHI_type_node)
74718334Speter    return unsigned_intHI_type_node;
74818334Speter  if (type1 == intQI_type_node)
74918334Speter    return unsigned_intQI_type_node;
75050397Sobrien
75150397Sobrien  return signed_or_unsigned_type (1, type);
75218334Speter}
75318334Speter
75418334Speter/* Return a signed type the same as TYPE in other respects.  */
75518334Speter
75618334Spetertree
75718334Spetersigned_type (type)
75818334Speter     tree type;
75918334Speter{
76018334Speter  tree type1 = TYPE_MAIN_VARIANT (type);
76118334Speter  if (type1 == unsigned_char_type_node || type1 == char_type_node)
76218334Speter    return signed_char_type_node;
76318334Speter  if (type1 == unsigned_type_node)
76418334Speter    return integer_type_node;
76518334Speter  if (type1 == short_unsigned_type_node)
76618334Speter    return short_integer_type_node;
76718334Speter  if (type1 == long_unsigned_type_node)
76818334Speter    return long_integer_type_node;
76918334Speter  if (type1 == long_long_unsigned_type_node)
77018334Speter    return long_long_integer_type_node;
77118334Speter  if (type1 == unsigned_intDI_type_node)
77218334Speter    return intDI_type_node;
77318334Speter  if (type1 == unsigned_intSI_type_node)
77418334Speter    return intSI_type_node;
77518334Speter  if (type1 == unsigned_intHI_type_node)
77618334Speter    return intHI_type_node;
77718334Speter  if (type1 == unsigned_intQI_type_node)
77818334Speter    return intQI_type_node;
77950397Sobrien
78050397Sobrien  return signed_or_unsigned_type (0, type);
78118334Speter}
78218334Speter
78318334Speter/* Return a type the same as TYPE except unsigned or
78418334Speter   signed according to UNSIGNEDP.  */
78518334Speter
78618334Spetertree
78718334Spetersigned_or_unsigned_type (unsignedp, type)
78818334Speter     int unsignedp;
78918334Speter     tree type;
79018334Speter{
79150397Sobrien  if ((! INTEGRAL_TYPE_P (type) && ! POINTER_TYPE_P (type))
79250397Sobrien      || TREE_UNSIGNED (type) == unsignedp)
79318334Speter    return type;
79418334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
79518334Speter    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
79618334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
79718334Speter    return unsignedp ? unsigned_type_node : integer_type_node;
79818334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
79918334Speter    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
80018334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
80118334Speter    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
80218334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
80318334Speter    return (unsignedp ? long_long_unsigned_type_node
80418334Speter	    : long_long_integer_type_node);
80518334Speter  return type;
80618334Speter}
80718334Speter
80818334Speter/* Compute the value of the `sizeof' operator.  */
80918334Speter
81018334Spetertree
81118334Speterc_sizeof (type)
81218334Speter     tree type;
81318334Speter{
81418334Speter  enum tree_code code = TREE_CODE (type);
81518334Speter  tree t;
81618334Speter
81718334Speter  if (code == FUNCTION_TYPE)
81818334Speter    {
81918334Speter      if (pedantic || warn_pointer_arith)
82018334Speter	pedwarn ("sizeof applied to a function type");
82118334Speter      return size_int (1);
82218334Speter    }
82318334Speter  if (code == VOID_TYPE)
82418334Speter    {
82518334Speter      if (pedantic || warn_pointer_arith)
82618334Speter	pedwarn ("sizeof applied to a void type");
82718334Speter      return size_int (1);
82818334Speter    }
82918334Speter  if (code == ERROR_MARK)
83018334Speter    return size_int (1);
83118334Speter  if (TYPE_SIZE (type) == 0)
83218334Speter    {
83318334Speter      error ("sizeof applied to an incomplete type");
83418334Speter      return size_int (0);
83518334Speter    }
83618334Speter
83718334Speter  /* Convert in case a char is more than one unit.  */
83818334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
83918334Speter		  size_int (TYPE_PRECISION (char_type_node)));
84050397Sobrien  t = convert (sizetype, t);
84118334Speter  /* size_binop does not put the constant in range, so do it now.  */
84218334Speter  if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
84318334Speter    TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
84418334Speter  return t;
84518334Speter}
84618334Speter
84718334Spetertree
84818334Speterc_sizeof_nowarn (type)
84918334Speter     tree type;
85018334Speter{
85118334Speter  enum tree_code code = TREE_CODE (type);
85218334Speter  tree t;
85318334Speter
85418334Speter  if (code == FUNCTION_TYPE
85518334Speter      || code == VOID_TYPE
85618334Speter      || code == ERROR_MARK)
85718334Speter    return size_int (1);
85818334Speter  if (TYPE_SIZE (type) == 0)
85918334Speter    return size_int (0);
86018334Speter
86118334Speter  /* Convert in case a char is more than one unit.  */
86218334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
86318334Speter		  size_int (TYPE_PRECISION (char_type_node)));
86450397Sobrien  t = convert (sizetype, t);
86518334Speter  force_fit_type (t, 0);
86618334Speter  return t;
86718334Speter}
86818334Speter
86918334Speter/* Compute the size to increment a pointer by.  */
87018334Speter
87118334Spetertree
87218334Speterc_size_in_bytes (type)
87318334Speter     tree type;
87418334Speter{
87518334Speter  enum tree_code code = TREE_CODE (type);
87618334Speter  tree t;
87718334Speter
87818334Speter  if (code == FUNCTION_TYPE)
87918334Speter    return size_int (1);
88018334Speter  if (code == VOID_TYPE)
88118334Speter    return size_int (1);
88218334Speter  if (code == ERROR_MARK)
88318334Speter    return size_int (1);
88418334Speter  if (TYPE_SIZE (type) == 0)
88518334Speter    {
88618334Speter      error ("arithmetic on pointer to an incomplete type");
88718334Speter      return size_int (1);
88818334Speter    }
88918334Speter
89018334Speter  /* Convert in case a char is more than one unit.  */
89118334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
89218334Speter		     size_int (BITS_PER_UNIT));
89350397Sobrien  t = convert (sizetype, t);
89418334Speter  force_fit_type (t, 0);
89518334Speter  return t;
89618334Speter}
89718334Speter
89818334Speter/* Implement the __alignof keyword: Return the minimum required
89918334Speter   alignment of TYPE, measured in bytes.  */
90018334Speter
90118334Spetertree
90218334Speterc_alignof (type)
90318334Speter     tree type;
90418334Speter{
90518334Speter  enum tree_code code = TREE_CODE (type);
90618334Speter
90718334Speter  if (code == FUNCTION_TYPE)
90818334Speter    return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
90918334Speter
91018334Speter  if (code == VOID_TYPE || code == ERROR_MARK)
91118334Speter    return size_int (1);
91218334Speter
91318334Speter  return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
91418334Speter}
91518334Speter
91618334Speter/* Implement the __alignof keyword: Return the minimum required
91718334Speter   alignment of EXPR, measured in bytes.  For VAR_DECL's and
91818334Speter   FIELD_DECL's return DECL_ALIGN (which can be set from an
91918334Speter   "aligned" __attribute__ specification).  */
92018334Speter
92118334Spetertree
92218334Speterc_alignof_expr (expr)
92318334Speter     tree expr;
92418334Speter{
92518334Speter  if (TREE_CODE (expr) == VAR_DECL)
92618334Speter    return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
92718334Speter
92818334Speter  if (TREE_CODE (expr) == COMPONENT_REF
92950397Sobrien      && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
93018334Speter    {
93118334Speter      error ("`__alignof' applied to a bit-field");
93218334Speter      return size_int (1);
93318334Speter    }
93418334Speter  else if (TREE_CODE (expr) == COMPONENT_REF
93518334Speter      && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
93618334Speter    return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
93718334Speter
93818334Speter  if (TREE_CODE (expr) == INDIRECT_REF)
93918334Speter    {
94018334Speter      tree t = TREE_OPERAND (expr, 0);
94118334Speter      tree best = t;
94218334Speter      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
94318334Speter
94418334Speter      while (TREE_CODE (t) == NOP_EXPR
94518334Speter	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
94618334Speter	{
94718334Speter	  int thisalign;
94818334Speter
94918334Speter	  t = TREE_OPERAND (t, 0);
95018334Speter	  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
95118334Speter	  if (thisalign > bestalign)
95218334Speter	    best = t, bestalign = thisalign;
95318334Speter	}
95418334Speter      return c_alignof (TREE_TYPE (TREE_TYPE (best)));
95518334Speter    }
95618334Speter  else
95718334Speter    return c_alignof (TREE_TYPE (expr));
95818334Speter}
95950397Sobrien
96018334Speter/* Return either DECL or its known constant value (if it has one).  */
96118334Speter
96218334Speterstatic tree
96318334Speterdecl_constant_value (decl)
96418334Speter     tree decl;
96518334Speter{
96650397Sobrien  if (/* Don't change a variable array bound or initial value to a constant
96718334Speter	 in a place where a variable is invalid.  */
96850397Sobrien      current_function_decl != 0
96918334Speter      && ! pedantic
97018334Speter      && ! TREE_THIS_VOLATILE (decl)
97118334Speter      && TREE_READONLY (decl) && ! ITERATOR_P (decl)
97218334Speter      && DECL_INITIAL (decl) != 0
97318334Speter      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
97418334Speter      /* This is invalid if initial value is not constant.
97518334Speter	 If it has either a function call, a memory reference,
97618334Speter	 or a variable, then re-evaluating it could give different results.  */
97718334Speter      && TREE_CONSTANT (DECL_INITIAL (decl))
97818334Speter      /* Check for cases where this is sub-optimal, even though valid.  */
97918334Speter      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
98018334Speter      && DECL_MODE (decl) != BLKmode)
98118334Speter    return DECL_INITIAL (decl);
98218334Speter  return decl;
98318334Speter}
98418334Speter
98518334Speter/* Perform default promotions for C data used in expressions.
98618334Speter   Arrays and functions are converted to pointers;
98718334Speter   enumeral types or short or char, to int.
98818334Speter   In addition, manifest constants symbols are replaced by their values.  */
98918334Speter
99018334Spetertree
99118334Speterdefault_conversion (exp)
99218334Speter     tree exp;
99318334Speter{
99418334Speter  register tree type = TREE_TYPE (exp);
99518334Speter  register enum tree_code code = TREE_CODE (type);
99618334Speter
99718334Speter  /* Constants can be used directly unless they're not loadable.  */
99818334Speter  if (TREE_CODE (exp) == CONST_DECL)
99918334Speter    exp = DECL_INITIAL (exp);
100018334Speter
100118334Speter  /* Replace a nonvolatile const static variable with its value unless
100218334Speter     it is an array, in which case we must be sure that taking the
100318334Speter     address of the array produces consistent results.  */
100418334Speter  else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
100518334Speter    {
100618334Speter      exp = decl_constant_value (exp);
100718334Speter      type = TREE_TYPE (exp);
100818334Speter    }
100918334Speter
101018334Speter  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
101118334Speter     an lvalue.  */
101218334Speter  /* Do not use STRIP_NOPS here!  It will remove conversions from pointer
101318334Speter     to integer and cause infinite recursion.  */
101418334Speter  while (TREE_CODE (exp) == NON_LVALUE_EXPR
101518334Speter	 || (TREE_CODE (exp) == NOP_EXPR
101618334Speter	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
101718334Speter    exp = TREE_OPERAND (exp, 0);
101818334Speter
101918334Speter  /* Normally convert enums to int,
102018334Speter     but convert wide enums to something wider.  */
102118334Speter  if (code == ENUMERAL_TYPE)
102218334Speter    {
102318334Speter      type = type_for_size (MAX (TYPE_PRECISION (type),
102418334Speter				 TYPE_PRECISION (integer_type_node)),
102518334Speter			    ((flag_traditional
102650397Sobrien			      || (TYPE_PRECISION (type)
102750397Sobrien				  >= TYPE_PRECISION (integer_type_node)))
102818334Speter			     && TREE_UNSIGNED (type)));
102918334Speter      return convert (type, exp);
103018334Speter    }
103118334Speter
103250397Sobrien  if (TREE_CODE (exp) == COMPONENT_REF
103350397Sobrien      && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
103450397Sobrien    {
103550397Sobrien      tree width = DECL_SIZE (TREE_OPERAND (exp, 1));
103650397Sobrien      HOST_WIDE_INT low = TREE_INT_CST_LOW (width);
103750397Sobrien
103850397Sobrien      /* If it's thinner than an int, promote it like a
103950397Sobrien	 C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone.  */
104050397Sobrien
104150397Sobrien      if (low < TYPE_PRECISION (integer_type_node))
104250397Sobrien	{
104350397Sobrien	  if (flag_traditional && TREE_UNSIGNED (type))
104450397Sobrien	    return convert (unsigned_type_node, exp);
104550397Sobrien	  else
104650397Sobrien	    return convert (integer_type_node, exp);
104750397Sobrien	}
104850397Sobrien    }
104950397Sobrien
105018334Speter  if (C_PROMOTING_INTEGER_TYPE_P (type))
105118334Speter    {
105218334Speter      /* Traditionally, unsignedness is preserved in default promotions.
105318334Speter         Also preserve unsignedness if not really getting any wider.  */
105418334Speter      if (TREE_UNSIGNED (type)
105518334Speter	  && (flag_traditional
105618334Speter	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
105718334Speter	return convert (unsigned_type_node, exp);
105818334Speter      return convert (integer_type_node, exp);
105918334Speter    }
106018334Speter  if (flag_traditional && !flag_allow_single_precision
106118334Speter      && TYPE_MAIN_VARIANT (type) == float_type_node)
106218334Speter    return convert (double_type_node, exp);
106318334Speter  if (code == VOID_TYPE)
106418334Speter    {
106518334Speter      error ("void value not ignored as it ought to be");
106618334Speter      return error_mark_node;
106718334Speter    }
106818334Speter  if (code == FUNCTION_TYPE)
106918334Speter    {
107018334Speter      return build_unary_op (ADDR_EXPR, exp, 0);
107118334Speter    }
107218334Speter  if (code == ARRAY_TYPE)
107318334Speter    {
107418334Speter      register tree adr;
107518334Speter      tree restype = TREE_TYPE (type);
107618334Speter      tree ptrtype;
107718334Speter      int constp = 0;
107818334Speter      int volatilep = 0;
107918334Speter
108018334Speter      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
108118334Speter	  || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
108218334Speter	{
108318334Speter	  constp = TREE_READONLY (exp);
108418334Speter	  volatilep = TREE_THIS_VOLATILE (exp);
108518334Speter	}
108618334Speter
108752284Sobrien      if (TYPE_QUALS (type) || constp || volatilep)
108852284Sobrien	restype
108952284Sobrien	  = c_build_qualified_type (restype,
109052284Sobrien				    TYPE_QUALS (type)
109152284Sobrien				    | (constp * TYPE_QUAL_CONST)
109252284Sobrien				    | (volatilep * TYPE_QUAL_VOLATILE));
109318334Speter
109418334Speter      if (TREE_CODE (exp) == INDIRECT_REF)
109518334Speter	return convert (TYPE_POINTER_TO (restype),
109618334Speter			TREE_OPERAND (exp, 0));
109718334Speter
109818334Speter      if (TREE_CODE (exp) == COMPOUND_EXPR)
109918334Speter	{
110018334Speter	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));
110118334Speter	  return build (COMPOUND_EXPR, TREE_TYPE (op1),
110218334Speter			TREE_OPERAND (exp, 0), op1);
110318334Speter	}
110418334Speter
110550397Sobrien      if (! lvalue_p (exp)
110618334Speter	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
110718334Speter	{
110818334Speter	  error ("invalid use of non-lvalue array");
110918334Speter	  return error_mark_node;
111018334Speter	}
111118334Speter
111218334Speter      ptrtype = build_pointer_type (restype);
111318334Speter
111418334Speter      if (TREE_CODE (exp) == VAR_DECL)
111518334Speter	{
111618334Speter	  /* ??? This is not really quite correct
111718334Speter	     in that the type of the operand of ADDR_EXPR
111818334Speter	     is not the target type of the type of the ADDR_EXPR itself.
111918334Speter	     Question is, can this lossage be avoided?  */
112018334Speter	  adr = build1 (ADDR_EXPR, ptrtype, exp);
112118334Speter	  if (mark_addressable (exp) == 0)
112218334Speter	    return error_mark_node;
112318334Speter	  TREE_CONSTANT (adr) = staticp (exp);
112418334Speter	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
112518334Speter	  return adr;
112618334Speter	}
112718334Speter      /* This way is better for a COMPONENT_REF since it can
112818334Speter	 simplify the offset for a component.  */
112918334Speter      adr = build_unary_op (ADDR_EXPR, exp, 1);
113018334Speter      return convert (ptrtype, adr);
113118334Speter    }
113218334Speter  return exp;
113318334Speter}
113418334Speter
113518334Speter/* Look up component name in the structure type definition.
113618334Speter
113718334Speter   If this component name is found indirectly within an anonymous union,
113818334Speter   store in *INDIRECT the component which directly contains
113918334Speter   that anonymous union.  Otherwise, set *INDIRECT to 0.  */
114018334Speter
114118334Speterstatic tree
114218334Speterlookup_field (type, component, indirect)
114318334Speter     tree type, component;
114418334Speter     tree *indirect;
114518334Speter{
114618334Speter  tree field;
114718334Speter
114818334Speter  /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
114918334Speter     to the field elements.  Use a binary search on this array to quickly
115018334Speter     find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC
115118334Speter     will always be set for structures which have many elements.  */
115218334Speter
115318334Speter  if (TYPE_LANG_SPECIFIC (type))
115418334Speter    {
115518334Speter      int bot, top, half;
115618334Speter      tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];
115718334Speter
115818334Speter      field = TYPE_FIELDS (type);
115918334Speter      bot = 0;
116018334Speter      top = TYPE_LANG_SPECIFIC (type)->len;
116118334Speter      while (top - bot > 1)
116218334Speter	{
116318334Speter	  half = (top - bot + 1) >> 1;
116418334Speter	  field = field_array[bot+half];
116518334Speter
116618334Speter	  if (DECL_NAME (field) == NULL_TREE)
116718334Speter	    {
116818334Speter	      /* Step through all anon unions in linear fashion.  */
116918334Speter	      while (DECL_NAME (field_array[bot]) == NULL_TREE)
117018334Speter		{
117150397Sobrien		  tree anon = 0, junk;
117218334Speter
117318334Speter		  field = field_array[bot++];
117450397Sobrien		  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
117550397Sobrien		      || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
117650397Sobrien		    anon = lookup_field (TREE_TYPE (field), component, &junk);
117750397Sobrien
117818334Speter		  if (anon != NULL_TREE)
117918334Speter		    {
118018334Speter		      *indirect = field;
118118334Speter		      return anon;
118218334Speter		    }
118318334Speter		}
118418334Speter
118518334Speter	      /* Entire record is only anon unions.  */
118618334Speter	      if (bot > top)
118718334Speter		return NULL_TREE;
118818334Speter
118918334Speter	      /* Restart the binary search, with new lower bound.  */
119018334Speter	      continue;
119118334Speter	    }
119218334Speter
119318334Speter	  if (DECL_NAME (field) == component)
119418334Speter	    break;
119518334Speter	  if (DECL_NAME (field) < component)
119618334Speter	    bot += half;
119718334Speter	  else
119818334Speter	    top = bot + half;
119918334Speter	}
120018334Speter
120118334Speter      if (DECL_NAME (field_array[bot]) == component)
120218334Speter	field = field_array[bot];
120318334Speter      else if (DECL_NAME (field) != component)
120418334Speter	field = 0;
120518334Speter    }
120618334Speter  else
120718334Speter    {
120818334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
120918334Speter	{
121018334Speter	  if (DECL_NAME (field) == NULL_TREE)
121118334Speter	    {
121218334Speter	      tree junk;
121350397Sobrien	      tree anon = 0;
121450397Sobrien
121550397Sobrien	      if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
121650397Sobrien		  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
121750397Sobrien		anon = lookup_field (TREE_TYPE (field), component, &junk);
121850397Sobrien
121918334Speter	      if (anon != NULL_TREE)
122018334Speter		{
122118334Speter		  *indirect = field;
122218334Speter		  return anon;
122318334Speter		}
122418334Speter	    }
122518334Speter
122618334Speter	  if (DECL_NAME (field) == component)
122718334Speter	    break;
122818334Speter	}
122918334Speter    }
123018334Speter
123118334Speter  *indirect = NULL_TREE;
123218334Speter  return field;
123318334Speter}
123418334Speter
123518334Speter/* Make an expression to refer to the COMPONENT field of
123618334Speter   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
123718334Speter
123818334Spetertree
123918334Speterbuild_component_ref (datum, component)
124018334Speter     tree datum, component;
124118334Speter{
124218334Speter  register tree type = TREE_TYPE (datum);
124318334Speter  register enum tree_code code = TREE_CODE (type);
124418334Speter  register tree field = NULL;
124518334Speter  register tree ref;
124618334Speter
124718334Speter  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it
124818334Speter     unless we are not to support things not strictly ANSI.  */
124918334Speter  switch (TREE_CODE (datum))
125018334Speter    {
125118334Speter    case COMPOUND_EXPR:
125218334Speter      {
125318334Speter	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
125418334Speter	return build (COMPOUND_EXPR, TREE_TYPE (value),
125518334Speter		      TREE_OPERAND (datum, 0), value);
125618334Speter      }
125718334Speter    case COND_EXPR:
125818334Speter      return build_conditional_expr
125918334Speter	(TREE_OPERAND (datum, 0),
126018334Speter	 build_component_ref (TREE_OPERAND (datum, 1), component),
126118334Speter	 build_component_ref (TREE_OPERAND (datum, 2), component));
126250397Sobrien
126350397Sobrien    default:
126450397Sobrien      break;
126518334Speter    }
126618334Speter
126718334Speter  /* See if there is a field or component with name COMPONENT.  */
126818334Speter
126918334Speter  if (code == RECORD_TYPE || code == UNION_TYPE)
127018334Speter    {
127118334Speter      tree indirect = 0;
127218334Speter
127318334Speter      if (TYPE_SIZE (type) == 0)
127418334Speter	{
127518334Speter	  incomplete_type_error (NULL_TREE, type);
127618334Speter	  return error_mark_node;
127718334Speter	}
127818334Speter
127918334Speter      field = lookup_field (type, component, &indirect);
128018334Speter
128118334Speter      if (!field)
128218334Speter	{
128318334Speter	  error (code == RECORD_TYPE
128418334Speter		 ? "structure has no member named `%s'"
128518334Speter		 : "union has no member named `%s'",
128618334Speter		 IDENTIFIER_POINTER (component));
128718334Speter	  return error_mark_node;
128818334Speter	}
128918334Speter      if (TREE_TYPE (field) == error_mark_node)
129018334Speter	return error_mark_node;
129118334Speter
129218334Speter      /* If FIELD was found buried within an anonymous union,
129318334Speter	 make one COMPONENT_REF to get that anonymous union,
129418334Speter	 then fall thru to make a second COMPONENT_REF to get FIELD.  */
129518334Speter      if (indirect != 0)
129618334Speter	{
129718334Speter	  ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect);
129818334Speter	  if (TREE_READONLY (datum) || TREE_READONLY (indirect))
129918334Speter	    TREE_READONLY (ref) = 1;
130018334Speter	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect))
130118334Speter	    TREE_THIS_VOLATILE (ref) = 1;
130218334Speter	  datum = ref;
130318334Speter	}
130418334Speter
130518334Speter      ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field);
130618334Speter
130718334Speter      if (TREE_READONLY (datum) || TREE_READONLY (field))
130818334Speter	TREE_READONLY (ref) = 1;
130918334Speter      if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
131018334Speter	TREE_THIS_VOLATILE (ref) = 1;
131118334Speter
131218334Speter      return ref;
131318334Speter    }
131418334Speter  else if (code != ERROR_MARK)
131518334Speter    error ("request for member `%s' in something not a structure or union",
131618334Speter	    IDENTIFIER_POINTER (component));
131718334Speter
131818334Speter  return error_mark_node;
131918334Speter}
132018334Speter
132118334Speter/* Given an expression PTR for a pointer, return an expression
132218334Speter   for the value pointed to.
132318334Speter   ERRORSTRING is the name of the operator to appear in error messages.  */
132418334Speter
132518334Spetertree
132618334Speterbuild_indirect_ref (ptr, errorstring)
132718334Speter     tree ptr;
132852284Sobrien     const char *errorstring;
132918334Speter{
133018334Speter  register tree pointer = default_conversion (ptr);
133118334Speter  register tree type = TREE_TYPE (pointer);
133218334Speter
133318334Speter  if (TREE_CODE (type) == POINTER_TYPE)
133418334Speter    {
133518334Speter      if (TREE_CODE (pointer) == ADDR_EXPR
133618334Speter	  && !flag_volatile
133718334Speter	  && (TREE_TYPE (TREE_OPERAND (pointer, 0))
133818334Speter	      == TREE_TYPE (type)))
133918334Speter	return TREE_OPERAND (pointer, 0);
134018334Speter      else
134118334Speter	{
134218334Speter	  tree t = TREE_TYPE (type);
134318334Speter	  register tree ref = build1 (INDIRECT_REF,
134418334Speter				      TYPE_MAIN_VARIANT (t), pointer);
134518334Speter
134618334Speter	  if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
134718334Speter	    {
134818334Speter	      error ("dereferencing pointer to incomplete type");
134918334Speter	      return error_mark_node;
135018334Speter	    }
135150397Sobrien	  if (TREE_CODE (t) == VOID_TYPE && skip_evaluation == 0)
135218334Speter	    warning ("dereferencing `void *' pointer");
135318334Speter
135418334Speter	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
135518334Speter	     so that we get the proper error message if the result is used
135618334Speter	     to assign to.  Also, &* is supposed to be a no-op.
135718334Speter	     And ANSI C seems to specify that the type of the result
135818334Speter	     should be the const type.  */
135918334Speter	  /* A de-reference of a pointer to const is not a const.  It is valid
136018334Speter	     to change it via some other pointer.  */
136118334Speter	  TREE_READONLY (ref) = TYPE_READONLY (t);
136218334Speter	  TREE_SIDE_EFFECTS (ref)
136318334Speter	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
136418334Speter	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
136518334Speter	  return ref;
136618334Speter	}
136718334Speter    }
136818334Speter  else if (TREE_CODE (pointer) != ERROR_MARK)
136918334Speter    error ("invalid type argument of `%s'", errorstring);
137018334Speter  return error_mark_node;
137118334Speter}
137218334Speter
137318334Speter/* This handles expressions of the form "a[i]", which denotes
137418334Speter   an array reference.
137518334Speter
137618334Speter   This is logically equivalent in C to *(a+i), but we may do it differently.
137718334Speter   If A is a variable or a member, we generate a primitive ARRAY_REF.
137818334Speter   This avoids forcing the array out of registers, and can work on
137918334Speter   arrays that are not lvalues (for example, members of structures returned
138018334Speter   by functions).  */
138118334Speter
138218334Spetertree
138318334Speterbuild_array_ref (array, index)
138418334Speter     tree array, index;
138518334Speter{
138618334Speter  if (index == 0)
138718334Speter    {
138818334Speter      error ("subscript missing in array reference");
138918334Speter      return error_mark_node;
139018334Speter    }
139118334Speter
139218334Speter  if (TREE_TYPE (array) == error_mark_node
139318334Speter      || TREE_TYPE (index) == error_mark_node)
139418334Speter    return error_mark_node;
139518334Speter
139618334Speter  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
139718334Speter      && TREE_CODE (array) != INDIRECT_REF)
139818334Speter    {
139918334Speter      tree rval, type;
140018334Speter
140118334Speter      /* Subscripting with type char is likely to lose
140218334Speter	 on a machine where chars are signed.
140318334Speter	 So warn on any machine, but optionally.
140418334Speter	 Don't warn for unsigned char since that type is safe.
140518334Speter	 Don't warn for signed char because anyone who uses that
140618334Speter	 must have done so deliberately.  */
140718334Speter      if (warn_char_subscripts
140818334Speter	  && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
140918334Speter	warning ("array subscript has type `char'");
141018334Speter
141118334Speter      /* Apply default promotions *after* noticing character types.  */
141218334Speter      index = default_conversion (index);
141318334Speter
141418334Speter      /* Require integer *after* promotion, for sake of enums.  */
141518334Speter      if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
141618334Speter	{
141718334Speter	  error ("array subscript is not an integer");
141818334Speter	  return error_mark_node;
141918334Speter	}
142018334Speter
142118334Speter      /* An array that is indexed by a non-constant
142218334Speter	 cannot be stored in a register; we must be able to do
142318334Speter	 address arithmetic on its address.
142418334Speter	 Likewise an array of elements of variable size.  */
142518334Speter      if (TREE_CODE (index) != INTEGER_CST
142618334Speter	  || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
142718334Speter	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
142818334Speter	{
142918334Speter	  if (mark_addressable (array) == 0)
143018334Speter	    return error_mark_node;
143118334Speter	}
143218334Speter      /* An array that is indexed by a constant value which is not within
143318334Speter	 the array bounds cannot be stored in a register either; because we
143418334Speter	 would get a crash in store_bit_field/extract_bit_field when trying
143518334Speter	 to access a non-existent part of the register.  */
143618334Speter      if (TREE_CODE (index) == INTEGER_CST
143718334Speter	  && TYPE_VALUES (TREE_TYPE (array))
143818334Speter	  && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array))))
143918334Speter	{
144018334Speter	  if (mark_addressable (array) == 0)
144118334Speter	    return error_mark_node;
144218334Speter	}
144318334Speter
144418334Speter      if (pedantic && !lvalue_p (array))
144518334Speter	{
144618334Speter	  if (DECL_REGISTER (array))
144718334Speter	    pedwarn ("ANSI C forbids subscripting `register' array");
144818334Speter	  else
144918334Speter	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
145018334Speter	}
145118334Speter
145218334Speter      if (pedantic)
145318334Speter	{
145418334Speter	  tree foo = array;
145518334Speter	  while (TREE_CODE (foo) == COMPONENT_REF)
145618334Speter	    foo = TREE_OPERAND (foo, 0);
145718334Speter	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
145818334Speter	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
145918334Speter	}
146018334Speter
146118334Speter      type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
146218334Speter      rval = build (ARRAY_REF, type, array, index);
146318334Speter      /* Array ref is const/volatile if the array elements are
146418334Speter         or if the array is.  */
146518334Speter      TREE_READONLY (rval)
146618334Speter	|= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
146718334Speter	    | TREE_READONLY (array));
146818334Speter      TREE_SIDE_EFFECTS (rval)
146918334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
147018334Speter	    | TREE_SIDE_EFFECTS (array));
147118334Speter      TREE_THIS_VOLATILE (rval)
147218334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
147318334Speter	    /* This was added by rms on 16 Nov 91.
147418334Speter	       It fixes  vol struct foo *a;  a->elts[1]
147518334Speter	       in an inline function.
147618334Speter	       Hope it doesn't break something else.  */
147718334Speter	    | TREE_THIS_VOLATILE (array));
147818334Speter      return require_complete_type (fold (rval));
147918334Speter    }
148018334Speter
148118334Speter  {
148218334Speter    tree ar = default_conversion (array);
148318334Speter    tree ind = default_conversion (index);
148418334Speter
148550397Sobrien    /* Do the same warning check as above, but only on the part that's
148650397Sobrien       syntactically the index and only if it is also semantically
148750397Sobrien       the index.  */
148850397Sobrien    if (warn_char_subscripts
148950397Sobrien	&& TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
149050397Sobrien	&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
149150397Sobrien      warning ("subscript has type `char'");
149250397Sobrien
149318334Speter    /* Put the integer in IND to simplify error checking.  */
149418334Speter    if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
149518334Speter      {
149618334Speter	tree temp = ar;
149718334Speter	ar = ind;
149818334Speter	ind = temp;
149918334Speter      }
150018334Speter
150118334Speter    if (ar == error_mark_node)
150218334Speter      return ar;
150318334Speter
150450397Sobrien    if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE
150550397Sobrien	|| TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE)
150618334Speter      {
150718334Speter	error ("subscripted value is neither array nor pointer");
150818334Speter	return error_mark_node;
150918334Speter      }
151018334Speter    if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
151118334Speter      {
151218334Speter	error ("array subscript is not an integer");
151318334Speter	return error_mark_node;
151418334Speter      }
151518334Speter
151618334Speter    return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
151718334Speter			       "array indexing");
151818334Speter  }
151918334Speter}
152018334Speter
152118334Speter/* Build a function call to function FUNCTION with parameters PARAMS.
152218334Speter   PARAMS is a list--a chain of TREE_LIST nodes--in which the
152318334Speter   TREE_VALUE of each node is a parameter-expression.
152418334Speter   FUNCTION's data type may be a function type or a pointer-to-function.  */
152518334Speter
152618334Spetertree
152718334Speterbuild_function_call (function, params)
152818334Speter     tree function, params;
152918334Speter{
153018334Speter  register tree fntype, fundecl = 0;
153118334Speter  register tree coerced_params;
153218334Speter  tree name = NULL_TREE, assembler_name = NULL_TREE;
153318334Speter
153418334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
153518334Speter  STRIP_TYPE_NOPS (function);
153618334Speter
153718334Speter  /* Convert anything with function type to a pointer-to-function.  */
153818334Speter  if (TREE_CODE (function) == FUNCTION_DECL)
153918334Speter    {
154018334Speter      name = DECL_NAME (function);
154118334Speter      assembler_name = DECL_ASSEMBLER_NAME (function);
154218334Speter
154318334Speter      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
154418334Speter	 (because calling an inline function does not mean the function
154518334Speter	 needs to be separately compiled).  */
154618334Speter      fntype = build_type_variant (TREE_TYPE (function),
154718334Speter				   TREE_READONLY (function),
154818334Speter				   TREE_THIS_VOLATILE (function));
154918334Speter      fundecl = function;
155018334Speter      function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
155118334Speter    }
155218334Speter  else
155318334Speter    function = default_conversion (function);
155418334Speter
155518334Speter  fntype = TREE_TYPE (function);
155618334Speter
155718334Speter  if (TREE_CODE (fntype) == ERROR_MARK)
155818334Speter    return error_mark_node;
155918334Speter
156018334Speter  if (!(TREE_CODE (fntype) == POINTER_TYPE
156118334Speter	&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
156218334Speter    {
156318334Speter      error ("called object is not a function");
156418334Speter      return error_mark_node;
156518334Speter    }
156618334Speter
156718334Speter  /* fntype now gets the type of function pointed to.  */
156818334Speter  fntype = TREE_TYPE (fntype);
156918334Speter
157018334Speter  /* Convert the parameters to the types declared in the
157118334Speter     function prototype, or apply default promotions.  */
157218334Speter
157318334Speter  coerced_params
157418334Speter    = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
157518334Speter
157618334Speter  /* Check for errors in format strings.  */
157718334Speter
157818334Speter  if (warn_format && (name || assembler_name))
157918334Speter    check_function_format (name, assembler_name, coerced_params);
158018334Speter
158118334Speter  /* Recognize certain built-in functions so we can make tree-codes
158218334Speter     other than CALL_EXPR.  We do this when it enables fold-const.c
158318334Speter     to do something useful.  */
158418334Speter
158518334Speter  if (TREE_CODE (function) == ADDR_EXPR
158618334Speter      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
158718334Speter      && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
158818334Speter    switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
158918334Speter      {
159018334Speter      case BUILT_IN_ABS:
159118334Speter      case BUILT_IN_LABS:
159218334Speter      case BUILT_IN_FABS:
159318334Speter	if (coerced_params == 0)
159418334Speter	  return integer_zero_node;
159518334Speter	return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
159650397Sobrien      default:
159750397Sobrien	break;
159818334Speter      }
159918334Speter
160018334Speter  {
160118334Speter    register tree result
160218334Speter      = build (CALL_EXPR, TREE_TYPE (fntype),
160318334Speter	       function, coerced_params, NULL_TREE);
160418334Speter
160518334Speter    TREE_SIDE_EFFECTS (result) = 1;
160618334Speter    if (TREE_TYPE (result) == void_type_node)
160718334Speter      return result;
160818334Speter    return require_complete_type (result);
160918334Speter  }
161018334Speter}
161118334Speter
161218334Speter/* Convert the argument expressions in the list VALUES
161318334Speter   to the types in the list TYPELIST.  The result is a list of converted
161418334Speter   argument expressions.
161518334Speter
161618334Speter   If TYPELIST is exhausted, or when an element has NULL as its type,
161718334Speter   perform the default conversions.
161818334Speter
161918334Speter   PARMLIST is the chain of parm decls for the function being called.
162018334Speter   It may be 0, if that info is not available.
162118334Speter   It is used only for generating error messages.
162218334Speter
162318334Speter   NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
162418334Speter
162518334Speter   This is also where warnings about wrong number of args are generated.
162618334Speter
162718334Speter   Both VALUES and the returned value are chains of TREE_LIST nodes
162818334Speter   with the elements of the list in the TREE_VALUE slots of those nodes.  */
162918334Speter
163018334Speterstatic tree
163118334Speterconvert_arguments (typelist, values, name, fundecl)
163218334Speter     tree typelist, values, name, fundecl;
163318334Speter{
163418334Speter  register tree typetail, valtail;
163518334Speter  register tree result = NULL;
163618334Speter  int parmnum;
163718334Speter
163818334Speter  /* Scan the given expressions and types, producing individual
163918334Speter     converted arguments and pushing them on RESULT in reverse order.  */
164018334Speter
164118334Speter  for (valtail = values, typetail = typelist, parmnum = 0;
164218334Speter       valtail;
164318334Speter       valtail = TREE_CHAIN (valtail), parmnum++)
164418334Speter    {
164518334Speter      register tree type = typetail ? TREE_VALUE (typetail) : 0;
164618334Speter      register tree val = TREE_VALUE (valtail);
164718334Speter
164818334Speter      if (type == void_type_node)
164918334Speter	{
165018334Speter	  if (name)
165118334Speter	    error ("too many arguments to function `%s'",
165218334Speter		   IDENTIFIER_POINTER (name));
165318334Speter	  else
165418334Speter	    error ("too many arguments to function");
165518334Speter	  break;
165618334Speter	}
165718334Speter
165818334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
165918334Speter      /* Do not use STRIP_NOPS here!  We do not want an enumerator with value 0
166018334Speter	 to convert automatically to a pointer.  */
166118334Speter      if (TREE_CODE (val) == NON_LVALUE_EXPR)
166218334Speter	val = TREE_OPERAND (val, 0);
166318334Speter
166418334Speter      if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
166518334Speter	  || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE)
166618334Speter	val = default_conversion (val);
166718334Speter
166818334Speter      val = require_complete_type (val);
166918334Speter
167018334Speter      if (type != 0)
167118334Speter	{
167218334Speter	  /* Formal parm type is specified by a function prototype.  */
167318334Speter	  tree parmval;
167418334Speter
167518334Speter	  if (TYPE_SIZE (type) == 0)
167618334Speter	    {
167718334Speter	      error ("type of formal parameter %d is incomplete", parmnum + 1);
167818334Speter	      parmval = val;
167918334Speter	    }
168018334Speter	  else
168118334Speter	    {
168218334Speter	      /* Optionally warn about conversions that
168318334Speter		 differ from the default conversions.  */
168418334Speter	      if (warn_conversion)
168518334Speter		{
168618334Speter		  int formal_prec = TYPE_PRECISION (type);
168718334Speter
168818334Speter		  if (INTEGRAL_TYPE_P (type)
168918334Speter		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
169018334Speter		    warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
169118334Speter		  else if (TREE_CODE (type) == COMPLEX_TYPE
169218334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
169318334Speter		    warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
169418334Speter		  else if (TREE_CODE (type) == REAL_TYPE
169518334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
169618334Speter		    warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
169718334Speter		  else if (TREE_CODE (type) == REAL_TYPE
169818334Speter			   && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
169918334Speter		    warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
170018334Speter		  /* ??? At some point, messages should be written about
170118334Speter		     conversions between complex types, but that's too messy
170218334Speter		     to do now.  */
170318334Speter		  else if (TREE_CODE (type) == REAL_TYPE
170418334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
170518334Speter		    {
170618334Speter		      /* Warn if any argument is passed as `float',
170718334Speter			 since without a prototype it would be `double'.  */
170818334Speter		      if (formal_prec == TYPE_PRECISION (float_type_node))
170918334Speter			warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1);
171018334Speter		    }
171118334Speter		  /* Detect integer changing in width or signedness.  */
171218334Speter		  else if (INTEGRAL_TYPE_P (type)
171318334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
171418334Speter		    {
171518334Speter		      tree would_have_been = default_conversion (val);
171618334Speter		      tree type1 = TREE_TYPE (would_have_been);
171718334Speter
171818334Speter		      if (TREE_CODE (type) == ENUMERAL_TYPE
171918334Speter			  && type == TREE_TYPE (val))
172018334Speter			/* No warning if function asks for enum
172118334Speter			   and the actual arg is that enum type.  */
172218334Speter			;
172318334Speter		      else if (formal_prec != TYPE_PRECISION (type1))
172418334Speter			warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
172518334Speter		      else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1))
172618334Speter			;
172718334Speter		      /* Don't complain if the formal parameter type
172818334Speter			 is an enum, because we can't tell now whether
172918334Speter			 the value was an enum--even the same enum.  */
173018334Speter		      else if (TREE_CODE (type) == ENUMERAL_TYPE)
173118334Speter			;
173218334Speter		      else if (TREE_CODE (val) == INTEGER_CST
173318334Speter			       && int_fits_type_p (val, type))
173418334Speter			/* Change in signedness doesn't matter
173518334Speter			   if a constant value is unaffected.  */
173618334Speter			;
173718334Speter		      /* Likewise for a constant in a NOP_EXPR.  */
173818334Speter		      else if (TREE_CODE (val) == NOP_EXPR
173918334Speter			       && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST
174018334Speter			       && int_fits_type_p (TREE_OPERAND (val, 0), type))
174118334Speter			;
174218334Speter#if 0 /* We never get such tree structure here.  */
174318334Speter		      else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE
174418334Speter			       && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type)
174518334Speter			       && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type))
174618334Speter			/* Change in signedness doesn't matter
174718334Speter			   if an enum value is unaffected.  */
174818334Speter			;
174918334Speter#endif
175018334Speter		      /* If the value is extended from a narrower
175118334Speter			 unsigned type, it doesn't matter whether we
175218334Speter			 pass it as signed or unsigned; the value
175318334Speter			 certainly is the same either way.  */
175418334Speter		      else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)
175518334Speter			       && TREE_UNSIGNED (TREE_TYPE (val)))
175618334Speter			;
175718334Speter		      else if (TREE_UNSIGNED (type))
175818334Speter			warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
175918334Speter		      else
176018334Speter			warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
176118334Speter		    }
176218334Speter		}
176318334Speter
176418334Speter	      parmval = convert_for_assignment (type, val,
176550397Sobrien					        (char *) 0, /* arg passing  */
176618334Speter						fundecl, name, parmnum + 1);
176718334Speter
176818334Speter#ifdef PROMOTE_PROTOTYPES
176918334Speter	      if ((TREE_CODE (type) == INTEGER_TYPE
177018334Speter		   || TREE_CODE (type) == ENUMERAL_TYPE)
177118334Speter		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
177218334Speter		parmval = default_conversion (parmval);
177318334Speter#endif
177418334Speter	    }
177518334Speter	  result = tree_cons (NULL_TREE, parmval, result);
177618334Speter	}
177718334Speter      else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
177818334Speter               && (TYPE_PRECISION (TREE_TYPE (val))
177918334Speter	           < TYPE_PRECISION (double_type_node)))
178018334Speter	/* Convert `float' to `double'.  */
178118334Speter	result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
178218334Speter      else
178318334Speter	/* Convert `short' and `char' to full-size `int'.  */
178418334Speter	result = tree_cons (NULL_TREE, default_conversion (val), result);
178518334Speter
178618334Speter      if (typetail)
178718334Speter	typetail = TREE_CHAIN (typetail);
178818334Speter    }
178918334Speter
179018334Speter  if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
179118334Speter    {
179218334Speter      if (name)
179318334Speter	error ("too few arguments to function `%s'",
179418334Speter	       IDENTIFIER_POINTER (name));
179518334Speter      else
179618334Speter	error ("too few arguments to function");
179718334Speter    }
179818334Speter
179918334Speter  return nreverse (result);
180018334Speter}
180118334Speter
180218334Speter/* This is the entry point used by the parser
180318334Speter   for binary operators in the input.
180418334Speter   In addition to constructing the expression,
180518334Speter   we check for operands that were written with other binary operators
180618334Speter   in a way that is likely to confuse the user.  */
180718334Speter
180818334Spetertree
180918334Speterparser_build_binary_op (code, arg1, arg2)
181018334Speter     enum tree_code code;
181118334Speter     tree arg1, arg2;
181218334Speter{
181318334Speter  tree result = build_binary_op (code, arg1, arg2, 1);
181418334Speter
181518334Speter  char class;
181618334Speter  char class1 = TREE_CODE_CLASS (TREE_CODE (arg1));
181718334Speter  char class2 = TREE_CODE_CLASS (TREE_CODE (arg2));
181818334Speter  enum tree_code code1 = ERROR_MARK;
181918334Speter  enum tree_code code2 = ERROR_MARK;
182018334Speter
182118334Speter  if (class1 == 'e' || class1 == '1'
182218334Speter      || class1 == '2' || class1 == '<')
182318334Speter    code1 = C_EXP_ORIGINAL_CODE (arg1);
182418334Speter  if (class2 == 'e' || class2 == '1'
182518334Speter      || class2 == '2' || class2 == '<')
182618334Speter    code2 = C_EXP_ORIGINAL_CODE (arg2);
182718334Speter
182818334Speter  /* Check for cases such as x+y<<z which users are likely
182918334Speter     to misinterpret.  If parens are used, C_EXP_ORIGINAL_CODE
183018334Speter     is cleared to prevent these warnings.  */
183118334Speter  if (warn_parentheses)
183218334Speter    {
183318334Speter      if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
183418334Speter	{
183518334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
183618334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
183718334Speter	    warning ("suggest parentheses around + or - inside shift");
183818334Speter	}
183918334Speter
184018334Speter      if (code == TRUTH_ORIF_EXPR)
184118334Speter	{
184218334Speter	  if (code1 == TRUTH_ANDIF_EXPR
184318334Speter	      || code2 == TRUTH_ANDIF_EXPR)
184418334Speter	    warning ("suggest parentheses around && within ||");
184518334Speter	}
184618334Speter
184718334Speter      if (code == BIT_IOR_EXPR)
184818334Speter	{
184918334Speter	  if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
185018334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
185118334Speter	      || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
185218334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
185318334Speter	    warning ("suggest parentheses around arithmetic in operand of |");
185418334Speter	  /* Check cases like x|y==z */
185518334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
185618334Speter	    warning ("suggest parentheses around comparison in operand of |");
185718334Speter	}
185818334Speter
185918334Speter      if (code == BIT_XOR_EXPR)
186018334Speter	{
186118334Speter	  if (code1 == BIT_AND_EXPR
186218334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
186318334Speter	      || code2 == BIT_AND_EXPR
186418334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
186518334Speter	    warning ("suggest parentheses around arithmetic in operand of ^");
186618334Speter	  /* Check cases like x^y==z */
186718334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
186818334Speter	    warning ("suggest parentheses around comparison in operand of ^");
186918334Speter	}
187018334Speter
187118334Speter      if (code == BIT_AND_EXPR)
187218334Speter	{
187318334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
187418334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
187518334Speter	    warning ("suggest parentheses around + or - in operand of &");
187618334Speter	  /* Check cases like x&y==z */
187718334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
187818334Speter	    warning ("suggest parentheses around comparison in operand of &");
187918334Speter	}
188018334Speter    }
188118334Speter
188218334Speter  /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
188318334Speter  if (TREE_CODE_CLASS (code) == '<' && extra_warnings
188418334Speter      && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<'))
188518334Speter    warning ("comparisons like X<=Y<=Z do not have their mathematical meaning");
188618334Speter
188718334Speter  unsigned_conversion_warning (result, arg1);
188818334Speter  unsigned_conversion_warning (result, arg2);
188918334Speter  overflow_warning (result);
189018334Speter
189118334Speter  class = TREE_CODE_CLASS (TREE_CODE (result));
189218334Speter
189318334Speter  /* Record the code that was specified in the source,
189418334Speter     for the sake of warnings about confusing nesting.  */
189518334Speter  if (class == 'e' || class == '1'
189618334Speter      || class == '2' || class == '<')
189718334Speter    C_SET_EXP_ORIGINAL_CODE (result, code);
189818334Speter  else
189918334Speter    {
190018334Speter      int flag = TREE_CONSTANT (result);
190118334Speter      /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR
190218334Speter	 so that convert_for_assignment wouldn't strip it.
190318334Speter	 That way, we got warnings for things like p = (1 - 1).
190418334Speter	 But it turns out we should not get those warnings.  */
190518334Speter      result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
190618334Speter      C_SET_EXP_ORIGINAL_CODE (result, code);
190718334Speter      TREE_CONSTANT (result) = flag;
190818334Speter    }
190918334Speter
191018334Speter  return result;
191118334Speter}
191218334Speter
191318334Speter/* Build a binary-operation expression without default conversions.
191418334Speter   CODE is the kind of expression to build.
191518334Speter   This function differs from `build' in several ways:
191618334Speter   the data type of the result is computed and recorded in it,
191718334Speter   warnings are generated if arg data types are invalid,
191818334Speter   special handling for addition and subtraction of pointers is known,
191918334Speter   and some optimization is done (operations on narrow ints
192018334Speter   are done in the narrower type when that gives the same result).
192118334Speter   Constant folding is also done before the result is returned.
192218334Speter
192318334Speter   Note that the operands will never have enumeral types, or function
192418334Speter   or array types, because either they will have the default conversions
192518334Speter   performed or they have both just been converted to some other type in which
192618334Speter   the arithmetic is to be done.  */
192718334Speter
192818334Spetertree
192918334Speterbuild_binary_op (code, orig_op0, orig_op1, convert_p)
193018334Speter     enum tree_code code;
193118334Speter     tree orig_op0, orig_op1;
193218334Speter     int convert_p;
193318334Speter{
193418334Speter  tree type0, type1;
193518334Speter  register enum tree_code code0, code1;
193618334Speter  tree op0, op1;
193718334Speter
193818334Speter  /* Expression code to give to the expression when it is built.
193918334Speter     Normally this is CODE, which is what the caller asked for,
194018334Speter     but in some special cases we change it.  */
194118334Speter  register enum tree_code resultcode = code;
194218334Speter
194318334Speter  /* Data type in which the computation is to be performed.
194418334Speter     In the simplest cases this is the common type of the arguments.  */
194518334Speter  register tree result_type = NULL;
194618334Speter
194718334Speter  /* Nonzero means operands have already been type-converted
194818334Speter     in whatever way is necessary.
194918334Speter     Zero means they need to be converted to RESULT_TYPE.  */
195018334Speter  int converted = 0;
195118334Speter
195218334Speter  /* Nonzero means create the expression with this type, rather than
195318334Speter     RESULT_TYPE.  */
195418334Speter  tree build_type = 0;
195518334Speter
195618334Speter  /* Nonzero means after finally constructing the expression
195718334Speter     convert it to this type.  */
195818334Speter  tree final_type = 0;
195918334Speter
196018334Speter  /* Nonzero if this is an operation like MIN or MAX which can
196118334Speter     safely be computed in short if both args are promoted shorts.
196218334Speter     Also implies COMMON.
196318334Speter     -1 indicates a bitwise operation; this makes a difference
196418334Speter     in the exact conditions for when it is safe to do the operation
196518334Speter     in a narrower mode.  */
196618334Speter  int shorten = 0;
196718334Speter
196818334Speter  /* Nonzero if this is a comparison operation;
196918334Speter     if both args are promoted shorts, compare the original shorts.
197018334Speter     Also implies COMMON.  */
197118334Speter  int short_compare = 0;
197218334Speter
197318334Speter  /* Nonzero if this is a right-shift operation, which can be computed on the
197418334Speter     original short and then promoted if the operand is a promoted short.  */
197518334Speter  int short_shift = 0;
197618334Speter
197718334Speter  /* Nonzero means set RESULT_TYPE to the common type of the args.  */
197818334Speter  int common = 0;
197918334Speter
198018334Speter  if (convert_p)
198118334Speter    {
198218334Speter      op0 = default_conversion (orig_op0);
198318334Speter      op1 = default_conversion (orig_op1);
198418334Speter    }
198518334Speter  else
198618334Speter    {
198718334Speter      op0 = orig_op0;
198818334Speter      op1 = orig_op1;
198918334Speter    }
199018334Speter
199118334Speter  type0 = TREE_TYPE (op0);
199218334Speter  type1 = TREE_TYPE (op1);
199318334Speter
199418334Speter  /* The expression codes of the data types of the arguments tell us
199518334Speter     whether the arguments are integers, floating, pointers, etc.  */
199618334Speter  code0 = TREE_CODE (type0);
199718334Speter  code1 = TREE_CODE (type1);
199818334Speter
199918334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
200018334Speter  STRIP_TYPE_NOPS (op0);
200118334Speter  STRIP_TYPE_NOPS (op1);
200218334Speter
200318334Speter  /* If an error was already reported for one of the arguments,
200418334Speter     avoid reporting another error.  */
200518334Speter
200618334Speter  if (code0 == ERROR_MARK || code1 == ERROR_MARK)
200718334Speter    return error_mark_node;
200818334Speter
200918334Speter  switch (code)
201018334Speter    {
201118334Speter    case PLUS_EXPR:
201218334Speter      /* Handle the pointer + int case.  */
201318334Speter      if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
201418334Speter	return pointer_int_sum (PLUS_EXPR, op0, op1);
201518334Speter      else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
201618334Speter	return pointer_int_sum (PLUS_EXPR, op1, op0);
201718334Speter      else
201818334Speter	common = 1;
201918334Speter      break;
202018334Speter
202118334Speter    case MINUS_EXPR:
202218334Speter      /* Subtraction of two similar pointers.
202318334Speter	 We must subtract them as integers, then divide by object size.  */
202418334Speter      if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
202518334Speter	  && comp_target_types (type0, type1))
202618334Speter	return pointer_diff (op0, op1);
202718334Speter      /* Handle pointer minus int.  Just like pointer plus int.  */
202818334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
202918334Speter	return pointer_int_sum (MINUS_EXPR, op0, op1);
203018334Speter      else
203118334Speter	common = 1;
203218334Speter      break;
203318334Speter
203418334Speter    case MULT_EXPR:
203518334Speter      common = 1;
203618334Speter      break;
203718334Speter
203818334Speter    case TRUNC_DIV_EXPR:
203918334Speter    case CEIL_DIV_EXPR:
204018334Speter    case FLOOR_DIV_EXPR:
204118334Speter    case ROUND_DIV_EXPR:
204218334Speter    case EXACT_DIV_EXPR:
204318334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
204418334Speter	   || code0 == COMPLEX_TYPE)
204518334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
204618334Speter	      || code1 == COMPLEX_TYPE))
204718334Speter	{
204818334Speter	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
204918334Speter	    resultcode = RDIV_EXPR;
205018334Speter	  else
205118334Speter	    {
205218334Speter	      /* Although it would be tempting to shorten always here, that
205318334Speter		 loses on some targets, since the modulo instruction is
205418334Speter		 undefined if the quotient can't be represented in the
205518334Speter		 computation mode.  We shorten only if unsigned or if
205618334Speter		 dividing by something we know != -1.  */
205718334Speter	      shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
205818334Speter			 || (TREE_CODE (op1) == INTEGER_CST
205918334Speter			     && (TREE_INT_CST_LOW (op1) != -1
206018334Speter				 || TREE_INT_CST_HIGH (op1) != -1)));
206118334Speter	    }
206218334Speter	  common = 1;
206318334Speter	}
206418334Speter      break;
206518334Speter
206618334Speter    case BIT_AND_EXPR:
206718334Speter    case BIT_ANDTC_EXPR:
206818334Speter    case BIT_IOR_EXPR:
206918334Speter    case BIT_XOR_EXPR:
207018334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
207118334Speter	shorten = -1;
207218334Speter      /* If one operand is a constant, and the other is a short type
207318334Speter	 that has been converted to an int,
207418334Speter	 really do the work in the short type and then convert the
207518334Speter	 result to int.  If we are lucky, the constant will be 0 or 1
207618334Speter	 in the short type, making the entire operation go away.  */
207718334Speter      if (TREE_CODE (op0) == INTEGER_CST
207818334Speter	  && TREE_CODE (op1) == NOP_EXPR
207918334Speter	  && TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))
208018334Speter	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
208118334Speter	{
208218334Speter	  final_type = result_type;
208318334Speter	  op1 = TREE_OPERAND (op1, 0);
208418334Speter	  result_type = TREE_TYPE (op1);
208518334Speter	}
208618334Speter      if (TREE_CODE (op1) == INTEGER_CST
208718334Speter	  && TREE_CODE (op0) == NOP_EXPR
208818334Speter	  && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))
208918334Speter	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
209018334Speter	{
209118334Speter	  final_type = result_type;
209218334Speter	  op0 = TREE_OPERAND (op0, 0);
209318334Speter	  result_type = TREE_TYPE (op0);
209418334Speter	}
209518334Speter      break;
209618334Speter
209718334Speter    case TRUNC_MOD_EXPR:
209818334Speter    case FLOOR_MOD_EXPR:
209918334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
210018334Speter	{
210118334Speter	  /* Although it would be tempting to shorten always here, that loses
210218334Speter	     on some targets, since the modulo instruction is undefined if the
210318334Speter	     quotient can't be represented in the computation mode.  We shorten
210418334Speter	     only if unsigned or if dividing by something we know != -1.  */
210518334Speter	  shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
210618334Speter		     || (TREE_CODE (op1) == INTEGER_CST
210718334Speter			 && (TREE_INT_CST_LOW (op1) != -1
210818334Speter			     || TREE_INT_CST_HIGH (op1) != -1)));
210918334Speter	  common = 1;
211018334Speter	}
211118334Speter      break;
211218334Speter
211318334Speter    case TRUTH_ANDIF_EXPR:
211418334Speter    case TRUTH_ORIF_EXPR:
211518334Speter    case TRUTH_AND_EXPR:
211618334Speter    case TRUTH_OR_EXPR:
211718334Speter    case TRUTH_XOR_EXPR:
211818334Speter      if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
211918334Speter	   || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
212018334Speter	  && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
212118334Speter	      || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
212218334Speter	{
212318334Speter	  /* Result of these operations is always an int,
212418334Speter	     but that does not mean the operands should be
212518334Speter	     converted to ints!  */
212618334Speter	  result_type = integer_type_node;
212718334Speter	  op0 = truthvalue_conversion (op0);
212818334Speter	  op1 = truthvalue_conversion (op1);
212918334Speter	  converted = 1;
213018334Speter	}
213118334Speter      break;
213218334Speter
213318334Speter      /* Shift operations: result has same type as first operand;
213418334Speter	 always convert second operand to int.
213518334Speter	 Also set SHORT_SHIFT if shifting rightward.  */
213618334Speter
213718334Speter    case RSHIFT_EXPR:
213818334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
213918334Speter	{
214050397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
214118334Speter	    {
214218334Speter	      if (tree_int_cst_sgn (op1) < 0)
214318334Speter		warning ("right shift count is negative");
214418334Speter	      else
214518334Speter		{
214618334Speter		  if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
214718334Speter		    short_shift = 1;
214818334Speter		  if (TREE_INT_CST_HIGH (op1) != 0
214918334Speter		      || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
215018334Speter			  >= TYPE_PRECISION (type0)))
215118334Speter		    warning ("right shift count >= width of type");
215218334Speter		}
215318334Speter	    }
215418334Speter	  /* Use the type of the value to be shifted.
215518334Speter	     This is what most traditional C compilers do.  */
215618334Speter	  result_type = type0;
215718334Speter	  /* Unless traditional, convert the shift-count to an integer,
215818334Speter	     regardless of size of value being shifted.  */
215918334Speter	  if (! flag_traditional)
216018334Speter	    {
216118334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
216218334Speter		op1 = convert (integer_type_node, op1);
216318334Speter	      /* Avoid converting op1 to result_type later.  */
216418334Speter	      converted = 1;
216518334Speter	    }
216618334Speter	}
216718334Speter      break;
216818334Speter
216918334Speter    case LSHIFT_EXPR:
217018334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
217118334Speter	{
217250397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
217318334Speter	    {
217418334Speter	      if (tree_int_cst_sgn (op1) < 0)
217518334Speter		warning ("left shift count is negative");
217618334Speter	      else if (TREE_INT_CST_HIGH (op1) != 0
217718334Speter		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
217818334Speter			   >= TYPE_PRECISION (type0)))
217918334Speter		warning ("left shift count >= width of type");
218018334Speter	    }
218118334Speter	  /* Use the type of the value to be shifted.
218218334Speter	     This is what most traditional C compilers do.  */
218318334Speter	  result_type = type0;
218418334Speter	  /* Unless traditional, convert the shift-count to an integer,
218518334Speter	     regardless of size of value being shifted.  */
218618334Speter	  if (! flag_traditional)
218718334Speter	    {
218818334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
218918334Speter		op1 = convert (integer_type_node, op1);
219018334Speter	      /* Avoid converting op1 to result_type later.  */
219118334Speter	      converted = 1;
219218334Speter	    }
219318334Speter	}
219418334Speter      break;
219518334Speter
219618334Speter    case RROTATE_EXPR:
219718334Speter    case LROTATE_EXPR:
219818334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
219918334Speter	{
220050397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
220118334Speter	    {
220218334Speter	      if (tree_int_cst_sgn (op1) < 0)
220318334Speter		warning ("shift count is negative");
220418334Speter	      else if (TREE_INT_CST_HIGH (op1) != 0
220518334Speter		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
220618334Speter			   >= TYPE_PRECISION (type0)))
220718334Speter		warning ("shift count >= width of type");
220818334Speter	    }
220918334Speter	  /* Use the type of the value to be shifted.
221018334Speter	     This is what most traditional C compilers do.  */
221118334Speter	  result_type = type0;
221218334Speter	  /* Unless traditional, convert the shift-count to an integer,
221318334Speter	     regardless of size of value being shifted.  */
221418334Speter	  if (! flag_traditional)
221518334Speter	    {
221618334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
221718334Speter		op1 = convert (integer_type_node, op1);
221818334Speter	      /* Avoid converting op1 to result_type later.  */
221918334Speter	      converted = 1;
222018334Speter	    }
222118334Speter	}
222218334Speter      break;
222318334Speter
222418334Speter    case EQ_EXPR:
222518334Speter    case NE_EXPR:
222618334Speter      /* Result of comparison is always int,
222718334Speter	 but don't convert the args to int!  */
222818334Speter      build_type = integer_type_node;
222918334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
223018334Speter	   || code0 == COMPLEX_TYPE)
223118334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
223218334Speter	      || code1 == COMPLEX_TYPE))
223318334Speter	short_compare = 1;
223418334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
223518334Speter	{
223618334Speter	  register tree tt0 = TREE_TYPE (type0);
223718334Speter	  register tree tt1 = TREE_TYPE (type1);
223818334Speter	  /* Anything compares with void *.  void * compares with anything.
223918334Speter	     Otherwise, the targets must be compatible
224018334Speter	     and both must be object or both incomplete.  */
224118334Speter	  if (comp_target_types (type0, type1))
224218334Speter	    result_type = common_type (type0, type1);
224318334Speter	  else if (TYPE_MAIN_VARIANT (tt0) == void_type_node)
224418334Speter	    {
224518334Speter	      /* op0 != orig_op0 detects the case of something
224618334Speter		 whose value is 0 but which isn't a valid null ptr const.  */
224718334Speter	      if (pedantic && (!integer_zerop (op0) || op0 != orig_op0)
224818334Speter		  && TREE_CODE (tt1) == FUNCTION_TYPE)
224918334Speter		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
225018334Speter	    }
225118334Speter	  else if (TYPE_MAIN_VARIANT (tt1) == void_type_node)
225218334Speter	    {
225318334Speter	      if (pedantic && (!integer_zerop (op1) || op1 != orig_op1)
225418334Speter		  && TREE_CODE (tt0) == FUNCTION_TYPE)
225518334Speter		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
225618334Speter	    }
225718334Speter	  else
225818334Speter	    pedwarn ("comparison of distinct pointer types lacks a cast");
225918334Speter
226018334Speter	  if (result_type == NULL_TREE)
226118334Speter	    result_type = ptr_type_node;
226218334Speter	}
226318334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
226418334Speter	       && integer_zerop (op1))
226518334Speter	result_type = type0;
226618334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
226718334Speter	       && integer_zerop (op0))
226818334Speter	result_type = type1;
226918334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
227018334Speter	{
227118334Speter	  result_type = type0;
227218334Speter	  if (! flag_traditional)
227318334Speter	    pedwarn ("comparison between pointer and integer");
227418334Speter	}
227518334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
227618334Speter	{
227718334Speter	  result_type = type1;
227818334Speter	  if (! flag_traditional)
227918334Speter	    pedwarn ("comparison between pointer and integer");
228018334Speter	}
228118334Speter      break;
228218334Speter
228318334Speter    case MAX_EXPR:
228418334Speter    case MIN_EXPR:
228518334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
228618334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
228718334Speter	shorten = 1;
228818334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
228918334Speter	{
229018334Speter	  if (comp_target_types (type0, type1))
229118334Speter	    {
229218334Speter	      result_type = common_type (type0, type1);
229318334Speter	      if (pedantic
229418334Speter		  && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
229518334Speter		pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
229618334Speter	    }
229718334Speter	  else
229818334Speter	    {
229918334Speter	      result_type = ptr_type_node;
230018334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
230118334Speter	    }
230218334Speter	}
230318334Speter      break;
230418334Speter
230518334Speter    case LE_EXPR:
230618334Speter    case GE_EXPR:
230718334Speter    case LT_EXPR:
230818334Speter    case GT_EXPR:
230918334Speter      build_type = integer_type_node;
231018334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
231118334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
231218334Speter	short_compare = 1;
231318334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
231418334Speter	{
231518334Speter	  if (comp_target_types (type0, type1))
231618334Speter	    {
231718334Speter	      result_type = common_type (type0, type1);
231818334Speter	      if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
231918334Speter		  != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
232018334Speter		pedwarn ("comparison of complete and incomplete pointers");
232118334Speter	      else if (pedantic
232218334Speter		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
232318334Speter		pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
232418334Speter	    }
232518334Speter	  else
232618334Speter	    {
232718334Speter	      result_type = ptr_type_node;
232818334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
232918334Speter	    }
233018334Speter	}
233118334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
233218334Speter	       && integer_zerop (op1))
233318334Speter	{
233418334Speter	  result_type = type0;
233518334Speter	  if (pedantic || extra_warnings)
233618334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
233718334Speter	}
233818334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
233918334Speter	       && integer_zerop (op0))
234018334Speter	{
234118334Speter	  result_type = type1;
234218334Speter	  if (pedantic)
234318334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
234418334Speter	}
234518334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
234618334Speter	{
234718334Speter	  result_type = type0;
234818334Speter	  if (! flag_traditional)
234918334Speter	    pedwarn ("comparison between pointer and integer");
235018334Speter	}
235118334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
235218334Speter	{
235318334Speter	  result_type = type1;
235418334Speter	  if (! flag_traditional)
235518334Speter	    pedwarn ("comparison between pointer and integer");
235618334Speter	}
235718334Speter      break;
235850397Sobrien
235950397Sobrien    default:
236050397Sobrien      break;
236118334Speter    }
236218334Speter
236318334Speter  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
236418334Speter      &&
236518334Speter      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
236618334Speter    {
236718334Speter      int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
236818334Speter
236918334Speter      if (shorten || common || short_compare)
237018334Speter	result_type = common_type (type0, type1);
237118334Speter
237218334Speter      /* For certain operations (which identify themselves by shorten != 0)
237318334Speter	 if both args were extended from the same smaller type,
237418334Speter	 do the arithmetic in that type and then extend.
237518334Speter
237618334Speter	 shorten !=0 and !=1 indicates a bitwise operation.
237718334Speter	 For them, this optimization is safe only if
237818334Speter	 both args are zero-extended or both are sign-extended.
237918334Speter	 Otherwise, we might change the result.
238018334Speter	 Eg, (short)-1 | (unsigned short)-1 is (int)-1
238118334Speter	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
238218334Speter
238318334Speter      if (shorten && none_complex)
238418334Speter	{
238518334Speter	  int unsigned0, unsigned1;
238618334Speter	  tree arg0 = get_narrower (op0, &unsigned0);
238718334Speter	  tree arg1 = get_narrower (op1, &unsigned1);
238818334Speter	  /* UNS is 1 if the operation to be done is an unsigned one.  */
238918334Speter	  int uns = TREE_UNSIGNED (result_type);
239018334Speter	  tree type;
239118334Speter
239218334Speter	  final_type = result_type;
239318334Speter
239418334Speter	  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
239518334Speter	     but it *requires* conversion to FINAL_TYPE.  */
239618334Speter
239718334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op0))
239818334Speter	       == TYPE_PRECISION (TREE_TYPE (arg0)))
239918334Speter	      && TREE_TYPE (op0) != final_type)
240018334Speter	    unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
240118334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op1))
240218334Speter	       == TYPE_PRECISION (TREE_TYPE (arg1)))
240318334Speter	      && TREE_TYPE (op1) != final_type)
240418334Speter	    unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
240518334Speter
240618334Speter	  /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
240718334Speter
240818334Speter	  /* For bitwise operations, signedness of nominal type
240918334Speter	     does not matter.  Consider only how operands were extended.  */
241018334Speter	  if (shorten == -1)
241118334Speter	    uns = unsigned0;
241218334Speter
241318334Speter	  /* Note that in all three cases below we refrain from optimizing
241418334Speter	     an unsigned operation on sign-extended args.
241518334Speter	     That would not be valid.  */
241618334Speter
241718334Speter	  /* Both args variable: if both extended in same way
241818334Speter	     from same width, do it in that width.
241918334Speter	     Do it unsigned if args were zero-extended.  */
242018334Speter	  if ((TYPE_PRECISION (TREE_TYPE (arg0))
242118334Speter	       < TYPE_PRECISION (result_type))
242218334Speter	      && (TYPE_PRECISION (TREE_TYPE (arg1))
242318334Speter		  == TYPE_PRECISION (TREE_TYPE (arg0)))
242418334Speter	      && unsigned0 == unsigned1
242518334Speter	      && (unsigned0 || !uns))
242618334Speter	    result_type
242718334Speter	      = signed_or_unsigned_type (unsigned0,
242818334Speter					 common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
242918334Speter	  else if (TREE_CODE (arg0) == INTEGER_CST
243018334Speter		   && (unsigned1 || !uns)
243118334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg1))
243218334Speter		       < TYPE_PRECISION (result_type))
243318334Speter		   && (type = signed_or_unsigned_type (unsigned1,
243418334Speter						       TREE_TYPE (arg1)),
243518334Speter		       int_fits_type_p (arg0, type)))
243618334Speter	    result_type = type;
243718334Speter	  else if (TREE_CODE (arg1) == INTEGER_CST
243818334Speter		   && (unsigned0 || !uns)
243918334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg0))
244018334Speter		       < TYPE_PRECISION (result_type))
244118334Speter		   && (type = signed_or_unsigned_type (unsigned0,
244218334Speter						       TREE_TYPE (arg0)),
244318334Speter		       int_fits_type_p (arg1, type)))
244418334Speter	    result_type = type;
244518334Speter	}
244618334Speter
244718334Speter      /* Shifts can be shortened if shifting right.  */
244818334Speter
244918334Speter      if (short_shift)
245018334Speter	{
245118334Speter	  int unsigned_arg;
245218334Speter	  tree arg0 = get_narrower (op0, &unsigned_arg);
245318334Speter
245418334Speter	  final_type = result_type;
245518334Speter
245618334Speter	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
245718334Speter	    unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
245818334Speter
245918334Speter	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
246018334Speter	      /* We can shorten only if the shift count is less than the
246118334Speter		 number of bits in the smaller type size.  */
246218334Speter	      && TREE_INT_CST_HIGH (op1) == 0
246318334Speter	      && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
246418334Speter	      /* If arg is sign-extended and then unsigned-shifted,
246518334Speter		 we can simulate this with a signed shift in arg's type
246618334Speter		 only if the extended result is at least twice as wide
246718334Speter		 as the arg.  Otherwise, the shift could use up all the
246818334Speter		 ones made by sign-extension and bring in zeros.
246918334Speter		 We can't optimize that case at all, but in most machines
247018334Speter		 it never happens because available widths are 2**N.  */
247118334Speter	      && (!TREE_UNSIGNED (final_type)
247218334Speter		  || unsigned_arg
247318334Speter		  || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type)))
247418334Speter	    {
247518334Speter	      /* Do an unsigned shift if the operand was zero-extended.  */
247618334Speter	      result_type
247718334Speter		= signed_or_unsigned_type (unsigned_arg,
247818334Speter					   TREE_TYPE (arg0));
247918334Speter	      /* Convert value-to-be-shifted to that type.  */
248018334Speter	      if (TREE_TYPE (op0) != result_type)
248118334Speter		op0 = convert (result_type, op0);
248218334Speter	      converted = 1;
248318334Speter	    }
248418334Speter	}
248518334Speter
248618334Speter      /* Comparison operations are shortened too but differently.
248718334Speter	 They identify themselves by setting short_compare = 1.  */
248818334Speter
248918334Speter      if (short_compare)
249018334Speter	{
249118334Speter	  /* Don't write &op0, etc., because that would prevent op0
249218334Speter	     from being kept in a register.
249318334Speter	     Instead, make copies of the our local variables and
249418334Speter	     pass the copies by reference, then copy them back afterward.  */
249518334Speter	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
249618334Speter	  enum tree_code xresultcode = resultcode;
249718334Speter	  tree val
249818334Speter	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
249918334Speter	  if (val != 0)
250018334Speter	    return val;
250118334Speter	  op0 = xop0, op1 = xop1;
250218334Speter	  converted = 1;
250318334Speter	  resultcode = xresultcode;
250418334Speter
250550397Sobrien	  if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0)
250650397Sobrien	      && skip_evaluation == 0)
250718334Speter	    {
250818334Speter	      int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
250918334Speter	      int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
251018334Speter
251118334Speter	      int unsignedp0, unsignedp1;
251218334Speter	      tree primop0 = get_narrower (op0, &unsignedp0);
251318334Speter	      tree primop1 = get_narrower (op1, &unsignedp1);
251418334Speter
251518334Speter	      /* Avoid spurious warnings for comparison with enumerators.  */
251618334Speter
251718334Speter	      xop0 = orig_op0;
251818334Speter	      xop1 = orig_op1;
251918334Speter	      STRIP_TYPE_NOPS (xop0);
252018334Speter	      STRIP_TYPE_NOPS (xop1);
252118334Speter
252218334Speter	      /* Give warnings for comparisons between signed and unsigned
252318334Speter		 quantities that may fail.  */
252418334Speter	      /* Do the checking based on the original operand trees, so that
252518334Speter		 casts will be considered, but default promotions won't be.  */
252618334Speter
252718334Speter	      /* Do not warn if the comparison is being done in a signed type,
252818334Speter		 since the signed type will only be chosen if it can represent
252918334Speter		 all the values of the unsigned type.  */
253018334Speter	      if (! TREE_UNSIGNED (result_type))
253118334Speter		/* OK */;
253218334Speter              /* Do not warn if both operands are unsigned.  */
253318334Speter              else if (op0_signed == op1_signed)
253418334Speter                /* OK */;
253518334Speter	      /* Do not warn if the signed quantity is an unsuffixed
253618334Speter		 integer literal (or some static constant expression
253718334Speter		 involving such literals) and it is non-negative.  */
253818334Speter	      else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST
253918334Speter			&& tree_int_cst_sgn (xop0) >= 0)
254018334Speter		       || (op1_signed && TREE_CODE (xop1) == INTEGER_CST
254118334Speter			   && tree_int_cst_sgn (xop1) >= 0))
254218334Speter		/* OK */;
254318334Speter	      /* Do not warn if the comparison is an equality operation,
254418334Speter                 the unsigned quantity is an integral constant and it does
254518334Speter                 not use the most significant bit of result_type.  */
254618334Speter	      else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
254718334Speter		       && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST
254850397Sobrien			    && int_fits_type_p (xop1, signed_type (result_type)))
254918334Speter			   || (op1_signed && TREE_CODE (xop0) == INTEGER_CST
255050397Sobrien			       && int_fits_type_p (xop0, signed_type (result_type)))))
255118334Speter		/* OK */;
255218334Speter	      else
255318334Speter		warning ("comparison between signed and unsigned");
255418334Speter
255518334Speter	      /* Warn if two unsigned values are being compared in a size
255618334Speter		 larger than their original size, and one (and only one) is the
255718334Speter		 result of a `~' operator.  This comparison will always fail.
255818334Speter
255918334Speter		 Also warn if one operand is a constant, and the constant
256018334Speter		 does not have all bits set that are set in the ~ operand
256118334Speter		 when it is extended.  */
256218334Speter
256318334Speter	      if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
256418334Speter		  != (TREE_CODE (primop1) == BIT_NOT_EXPR))
256518334Speter		{
256618334Speter		  if (TREE_CODE (primop0) == BIT_NOT_EXPR)
256718334Speter		    primop0 = get_narrower (TREE_OPERAND (primop0, 0),
256818334Speter					    &unsignedp0);
256918334Speter		  else
257018334Speter		    primop1 = get_narrower (TREE_OPERAND (primop1, 0),
257118334Speter					    &unsignedp1);
257218334Speter
257318334Speter		  if (TREE_CODE (primop0) == INTEGER_CST
257418334Speter		      || TREE_CODE (primop1) == INTEGER_CST)
257518334Speter		    {
257618334Speter		      tree primop;
257718334Speter		      long constant, mask;
257818334Speter		      int unsignedp, bits;
257918334Speter
258018334Speter		      if (TREE_CODE (primop0) == INTEGER_CST)
258118334Speter			{
258218334Speter			  primop = primop1;
258318334Speter			  unsignedp = unsignedp1;
258418334Speter			  constant = TREE_INT_CST_LOW (primop0);
258518334Speter			}
258618334Speter		      else
258718334Speter			{
258818334Speter			  primop = primop0;
258918334Speter			  unsignedp = unsignedp0;
259018334Speter			  constant = TREE_INT_CST_LOW (primop1);
259118334Speter			}
259218334Speter
259318334Speter		      bits = TYPE_PRECISION (TREE_TYPE (primop));
259418334Speter		      if (bits < TYPE_PRECISION (result_type)
259518334Speter			  && bits < HOST_BITS_PER_LONG && unsignedp)
259618334Speter			{
259718334Speter			  mask = (~0L) << bits;
259818334Speter			  if ((mask & constant) != mask)
259918334Speter			    warning ("comparison of promoted ~unsigned with constant");
260018334Speter			}
260118334Speter		    }
260218334Speter		  else if (unsignedp0 && unsignedp1
260318334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop0))
260418334Speter			       < TYPE_PRECISION (result_type))
260518334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop1))
260618334Speter			       < TYPE_PRECISION (result_type)))
260718334Speter		    warning ("comparison of promoted ~unsigned with unsigned");
260818334Speter		}
260918334Speter	    }
261018334Speter	}
261118334Speter    }
261218334Speter
261318334Speter  /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
261418334Speter     If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
261518334Speter     Then the expression will be built.
261618334Speter     It will be given type FINAL_TYPE if that is nonzero;
261718334Speter     otherwise, it will be given type RESULT_TYPE.  */
261818334Speter
261918334Speter  if (!result_type)
262018334Speter    {
262118334Speter      binary_op_error (code);
262218334Speter      return error_mark_node;
262318334Speter    }
262418334Speter
262518334Speter  if (! converted)
262618334Speter    {
262718334Speter      if (TREE_TYPE (op0) != result_type)
262818334Speter	op0 = convert (result_type, op0);
262918334Speter      if (TREE_TYPE (op1) != result_type)
263018334Speter	op1 = convert (result_type, op1);
263118334Speter    }
263218334Speter
263318334Speter  if (build_type == NULL_TREE)
263418334Speter    build_type = result_type;
263518334Speter
263618334Speter  {
263718334Speter    register tree result = build (resultcode, build_type, op0, op1);
263818334Speter    register tree folded;
263918334Speter
264018334Speter    folded = fold (result);
264118334Speter    if (folded == result)
264218334Speter      TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
264318334Speter    if (final_type != 0)
264418334Speter      return convert (final_type, folded);
264518334Speter    return folded;
264618334Speter  }
264718334Speter}
264818334Speter
264918334Speter/* Return a tree for the sum or difference (RESULTCODE says which)
265018334Speter   of pointer PTROP and integer INTOP.  */
265118334Speter
265218334Speterstatic tree
265318334Speterpointer_int_sum (resultcode, ptrop, intop)
265418334Speter     enum tree_code resultcode;
265518334Speter     register tree ptrop, intop;
265618334Speter{
265718334Speter  tree size_exp;
265818334Speter
265918334Speter  register tree result;
266018334Speter  register tree folded;
266118334Speter
266218334Speter  /* The result is a pointer of the same type that is being added.  */
266318334Speter
266418334Speter  register tree result_type = TREE_TYPE (ptrop);
266518334Speter
266618334Speter  if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
266718334Speter    {
266818334Speter      if (pedantic || warn_pointer_arith)
266918334Speter	pedwarn ("pointer of type `void *' used in arithmetic");
267018334Speter      size_exp = integer_one_node;
267118334Speter    }
267218334Speter  else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
267318334Speter    {
267418334Speter      if (pedantic || warn_pointer_arith)
267518334Speter	pedwarn ("pointer to a function used in arithmetic");
267618334Speter      size_exp = integer_one_node;
267718334Speter    }
267818334Speter  else
267918334Speter    size_exp = c_size_in_bytes (TREE_TYPE (result_type));
268018334Speter
268118334Speter  /* If what we are about to multiply by the size of the elements
268218334Speter     contains a constant term, apply distributive law
268318334Speter     and multiply that constant term separately.
268418334Speter     This helps produce common subexpressions.  */
268518334Speter
268618334Speter  if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
268718334Speter      && ! TREE_CONSTANT (intop)
268818334Speter      && TREE_CONSTANT (TREE_OPERAND (intop, 1))
268918334Speter      && TREE_CONSTANT (size_exp)
269018334Speter      /* If the constant comes from pointer subtraction,
269118334Speter	 skip this optimization--it would cause an error.  */
269218334Speter      && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
269318334Speter      /* If the constant is unsigned, and smaller than the pointer size,
269418334Speter	 then we must skip this optimization.  This is because it could cause
269518334Speter	 an overflow error if the constant is negative but INTOP is not.  */
269618334Speter      && (! TREE_UNSIGNED (TREE_TYPE (intop))
269718334Speter	  || (TYPE_PRECISION (TREE_TYPE (intop))
269818334Speter	      == TYPE_PRECISION (TREE_TYPE (ptrop)))))
269918334Speter    {
270018334Speter      enum tree_code subcode = resultcode;
270118334Speter      tree int_type = TREE_TYPE (intop);
270218334Speter      if (TREE_CODE (intop) == MINUS_EXPR)
270318334Speter	subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
270418334Speter      /* Convert both subexpression types to the type of intop,
270518334Speter	 because weird cases involving pointer arithmetic
270618334Speter	 can result in a sum or difference with different type args.  */
270718334Speter      ptrop = build_binary_op (subcode, ptrop,
270818334Speter			       convert (int_type, TREE_OPERAND (intop, 1)), 1);
270918334Speter      intop = convert (int_type, TREE_OPERAND (intop, 0));
271018334Speter    }
271118334Speter
271250397Sobrien  /* Convert the integer argument to a type the same size as sizetype
271318334Speter     so the multiply won't overflow spuriously.  */
271418334Speter
271550397Sobrien  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
271650397Sobrien      || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
271750397Sobrien    intop = convert (type_for_size (TYPE_PRECISION (sizetype),
271850397Sobrien				    TREE_UNSIGNED (sizetype)), intop);
271918334Speter
272018334Speter  /* Replace the integer argument with a suitable product by the object size.
272118334Speter     Do this multiplication as signed, then convert to the appropriate
272218334Speter     pointer type (actually unsigned integral).  */
272318334Speter
272418334Speter  intop = convert (result_type,
272518334Speter		   build_binary_op (MULT_EXPR, intop,
272618334Speter				    convert (TREE_TYPE (intop), size_exp), 1));
272718334Speter
272818334Speter  /* Create the sum or difference.  */
272918334Speter
273018334Speter  result = build (resultcode, result_type, ptrop, intop);
273118334Speter
273218334Speter  folded = fold (result);
273318334Speter  if (folded == result)
273418334Speter    TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
273518334Speter  return folded;
273618334Speter}
273718334Speter
273818334Speter/* Return a tree for the difference of pointers OP0 and OP1.
273918334Speter   The resulting tree has type int.  */
274018334Speter
274118334Speterstatic tree
274218334Speterpointer_diff (op0, op1)
274318334Speter     register tree op0, op1;
274418334Speter{
274518334Speter  register tree result, folded;
274618334Speter  tree restype = ptrdiff_type_node;
274718334Speter
274818334Speter  tree target_type = TREE_TYPE (TREE_TYPE (op0));
274918334Speter
275018334Speter  if (pedantic || warn_pointer_arith)
275118334Speter    {
275218334Speter      if (TREE_CODE (target_type) == VOID_TYPE)
275318334Speter	pedwarn ("pointer of type `void *' used in subtraction");
275418334Speter      if (TREE_CODE (target_type) == FUNCTION_TYPE)
275518334Speter	pedwarn ("pointer to a function used in subtraction");
275618334Speter    }
275718334Speter
275818334Speter  /* First do the subtraction as integers;
275950397Sobrien     then drop through to build the divide operator.
276050397Sobrien     Do not do default conversions on the minus operator
276150397Sobrien     in case restype is a short type.  */
276218334Speter
276318334Speter  op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
276450397Sobrien			 convert (restype, op1), 0);
276518334Speter  /* This generates an error if op1 is pointer to incomplete type.  */
276618334Speter  if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
276718334Speter    error ("arithmetic on pointer to an incomplete type");
276818334Speter
276918334Speter  /* This generates an error if op0 is pointer to incomplete type.  */
277018334Speter  op1 = c_size_in_bytes (target_type);
277118334Speter
277218334Speter  /* Divide by the size, in easiest possible way.  */
277318334Speter
277418334Speter  result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
277518334Speter
277618334Speter  folded = fold (result);
277718334Speter  if (folded == result)
277818334Speter    TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
277918334Speter  return folded;
278018334Speter}
278118334Speter
278218334Speter/* Construct and perhaps optimize a tree representation
278318334Speter   for a unary operation.  CODE, a tree_code, specifies the operation
278418334Speter   and XARG is the operand.  NOCONVERT nonzero suppresses
278518334Speter   the default promotions (such as from short to int).  */
278618334Speter
278718334Spetertree
278818334Speterbuild_unary_op (code, xarg, noconvert)
278918334Speter     enum tree_code code;
279018334Speter     tree xarg;
279118334Speter     int noconvert;
279218334Speter{
279318334Speter  /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
279418334Speter  register tree arg = xarg;
279518334Speter  register tree argtype = 0;
279618334Speter  register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
279718334Speter  tree val;
279818334Speter
279918334Speter  if (typecode == ERROR_MARK)
280018334Speter    return error_mark_node;
280118334Speter  if (typecode == ENUMERAL_TYPE)
280218334Speter    typecode = INTEGER_TYPE;
280318334Speter
280418334Speter  switch (code)
280518334Speter    {
280618334Speter    case CONVERT_EXPR:
280718334Speter      /* This is used for unary plus, because a CONVERT_EXPR
280818334Speter	 is enough to prevent anybody from looking inside for
280918334Speter	 associativity, but won't generate any code.  */
281018334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
281118334Speter	    || typecode == COMPLEX_TYPE))
281252284Sobrien	{
281352284Sobrien	  error ("wrong type argument to unary plus");
281452284Sobrien	  return error_mark_node;
281552284Sobrien	}
281618334Speter      else if (!noconvert)
281718334Speter	arg = default_conversion (arg);
281818334Speter      break;
281918334Speter
282018334Speter    case NEGATE_EXPR:
282118334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
282218334Speter	    || typecode == COMPLEX_TYPE))
282352284Sobrien	{
282452284Sobrien	  error ("wrong type argument to unary minus");
282552284Sobrien	  return error_mark_node;
282652284Sobrien	}
282718334Speter      else if (!noconvert)
282818334Speter	arg = default_conversion (arg);
282918334Speter      break;
283018334Speter
283118334Speter    case BIT_NOT_EXPR:
283218334Speter      if (typecode == COMPLEX_TYPE)
283318334Speter	{
283418334Speter	  code = CONJ_EXPR;
283518334Speter	  if (!noconvert)
283618334Speter	    arg = default_conversion (arg);
283718334Speter	}
283818334Speter      else if (typecode != INTEGER_TYPE)
283952284Sobrien	{
284052284Sobrien	  error ("wrong type argument to bit-complement");
284152284Sobrien	  return error_mark_node;
284252284Sobrien	}
284318334Speter      else if (!noconvert)
284418334Speter	arg = default_conversion (arg);
284518334Speter      break;
284618334Speter
284718334Speter    case ABS_EXPR:
284818334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
284918334Speter	    || typecode == COMPLEX_TYPE))
285052284Sobrien	{
285152284Sobrien	  error ("wrong type argument to abs");
285252284Sobrien	  return error_mark_node;
285352284Sobrien	}
285418334Speter      else if (!noconvert)
285518334Speter	arg = default_conversion (arg);
285618334Speter      break;
285718334Speter
285818334Speter    case CONJ_EXPR:
285918334Speter      /* Conjugating a real value is a no-op, but allow it anyway.  */
286018334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
286118334Speter	    || typecode == COMPLEX_TYPE))
286252284Sobrien	{
286352284Sobrien	  error ("wrong type argument to conjugation");
286452284Sobrien	  return error_mark_node;
286552284Sobrien	}
286618334Speter      else if (!noconvert)
286718334Speter	arg = default_conversion (arg);
286818334Speter      break;
286918334Speter
287018334Speter    case TRUTH_NOT_EXPR:
287118334Speter      if (typecode != INTEGER_TYPE
287218334Speter	  && typecode != REAL_TYPE && typecode != POINTER_TYPE
287318334Speter	  && typecode != COMPLEX_TYPE
287418334Speter	  /* These will convert to a pointer.  */
287518334Speter	  && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
287618334Speter	{
287752284Sobrien	  error ("wrong type argument to unary exclamation mark");
287852284Sobrien	  return error_mark_node;
287918334Speter	}
288018334Speter      arg = truthvalue_conversion (arg);
288118334Speter      return invert_truthvalue (arg);
288218334Speter
288318334Speter    case NOP_EXPR:
288418334Speter      break;
288518334Speter
288618334Speter    case REALPART_EXPR:
288718334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
288818334Speter	return TREE_REALPART (arg);
288918334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
289018334Speter	return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
289118334Speter      else
289218334Speter	return arg;
289318334Speter
289418334Speter    case IMAGPART_EXPR:
289518334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
289618334Speter	return TREE_IMAGPART (arg);
289718334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
289818334Speter	return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
289918334Speter      else
290018334Speter	return convert (TREE_TYPE (arg), integer_zero_node);
290118334Speter
290218334Speter    case PREINCREMENT_EXPR:
290318334Speter    case POSTINCREMENT_EXPR:
290418334Speter    case PREDECREMENT_EXPR:
290518334Speter    case POSTDECREMENT_EXPR:
290618334Speter      /* Handle complex lvalues (when permitted)
290718334Speter	 by reduction to simpler cases.  */
290818334Speter
290918334Speter      val = unary_complex_lvalue (code, arg);
291018334Speter      if (val != 0)
291118334Speter	return val;
291218334Speter
291318334Speter      /* Increment or decrement the real part of the value,
291418334Speter	 and don't change the imaginary part.  */
291518334Speter      if (typecode == COMPLEX_TYPE)
291618334Speter	{
291718334Speter	  tree real, imag;
291818334Speter
291918334Speter	  arg = stabilize_reference (arg);
292018334Speter	  real = build_unary_op (REALPART_EXPR, arg, 1);
292118334Speter	  imag = build_unary_op (IMAGPART_EXPR, arg, 1);
292218334Speter	  return build (COMPLEX_EXPR, TREE_TYPE (arg),
292318334Speter			build_unary_op (code, real, 1), imag);
292418334Speter	}
292518334Speter
292618334Speter      /* Report invalid types.  */
292718334Speter
292818334Speter      if (typecode != POINTER_TYPE
292918334Speter	  && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
293018334Speter	{
293152284Sobrien	  error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
293252284Sobrien		 ? "wrong type argument to increment"
293352284Sobrien		 : "wrong type argument to decrement");
293452284Sobrien	  return error_mark_node;
293518334Speter	}
293618334Speter
293718334Speter      {
293818334Speter	register tree inc;
293918334Speter	tree result_type = TREE_TYPE (arg);
294018334Speter
294118334Speter	arg = get_unwidened (arg, 0);
294218334Speter	argtype = TREE_TYPE (arg);
294318334Speter
294418334Speter	/* Compute the increment.  */
294518334Speter
294618334Speter	if (typecode == POINTER_TYPE)
294718334Speter	  {
294818334Speter	    /* If pointer target is an undefined struct,
294918334Speter	       we just cannot know how to do the arithmetic.  */
295018334Speter	    if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
295152284Sobrien	      error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
295252284Sobrien		     ? "increment of pointer to unknown structure"
295352284Sobrien		     : "decrement of pointer to unknown structure");
295418334Speter	    else if ((pedantic || warn_pointer_arith)
295518334Speter		     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
295618334Speter			 || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
295752284Sobrien	      pedwarn (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
295852284Sobrien		       ? "wrong type argument to increment"
295952284Sobrien		       : "wrong type argument to decrement");
296018334Speter	    inc = c_size_in_bytes (TREE_TYPE (result_type));
296118334Speter	  }
296218334Speter	else
296318334Speter	  inc = integer_one_node;
296418334Speter
296518334Speter	inc = convert (argtype, inc);
296618334Speter
296718334Speter	/* Handle incrementing a cast-expression.  */
296818334Speter
296918334Speter	while (1)
297018334Speter	  switch (TREE_CODE (arg))
297118334Speter	    {
297218334Speter	    case NOP_EXPR:
297318334Speter	    case CONVERT_EXPR:
297418334Speter	    case FLOAT_EXPR:
297518334Speter	    case FIX_TRUNC_EXPR:
297618334Speter	    case FIX_FLOOR_EXPR:
297718334Speter	    case FIX_ROUND_EXPR:
297818334Speter	    case FIX_CEIL_EXPR:
297918334Speter	      pedantic_lvalue_warning (CONVERT_EXPR);
298018334Speter	      /* If the real type has the same machine representation
298118334Speter		 as the type it is cast to, we can make better output
298218334Speter		 by adding directly to the inside of the cast.  */
298318334Speter	      if ((TREE_CODE (TREE_TYPE (arg))
298418334Speter		   == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
298518334Speter		  && (TYPE_MODE (TREE_TYPE (arg))
298618334Speter		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
298718334Speter		arg = TREE_OPERAND (arg, 0);
298818334Speter	      else
298918334Speter		{
299018334Speter		  tree incremented, modify, value;
299118334Speter		  arg = stabilize_reference (arg);
299218334Speter		  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
299318334Speter		    value = arg;
299418334Speter		  else
299518334Speter		    value = save_expr (arg);
299618334Speter		  incremented = build (((code == PREINCREMENT_EXPR
299718334Speter					 || code == POSTINCREMENT_EXPR)
299818334Speter					? PLUS_EXPR : MINUS_EXPR),
299918334Speter				       argtype, value, inc);
300018334Speter		  TREE_SIDE_EFFECTS (incremented) = 1;
300118334Speter		  modify = build_modify_expr (arg, NOP_EXPR, incremented);
300218334Speter		  value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
300318334Speter		  TREE_USED (value) = 1;
300418334Speter		  return value;
300518334Speter		}
300618334Speter	      break;
300718334Speter
300818334Speter	    default:
300918334Speter	      goto give_up;
301018334Speter	    }
301118334Speter      give_up:
301218334Speter
301318334Speter	/* Complain about anything else that is not a true lvalue.  */
301418334Speter	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
301518334Speter				    || code == POSTINCREMENT_EXPR)
301652284Sobrien				   ? "invalid lvalue in increment"
301752284Sobrien				   : "invalid lvalue in decrement")))
301818334Speter	  return error_mark_node;
301918334Speter
302018334Speter	/* Report a read-only lvalue.  */
302118334Speter	if (TREE_READONLY (arg))
302218334Speter	  readonly_warning (arg,
302318334Speter			    ((code == PREINCREMENT_EXPR
302418334Speter			      || code == POSTINCREMENT_EXPR)
302518334Speter			     ? "increment" : "decrement"));
302618334Speter
302718334Speter	val = build (code, TREE_TYPE (arg), arg, inc);
302818334Speter	TREE_SIDE_EFFECTS (val) = 1;
302918334Speter	val = convert (result_type, val);
303018334Speter	if (TREE_CODE (val) != code)
303118334Speter	  TREE_NO_UNUSED_WARNING (val) = 1;
303218334Speter	return val;
303318334Speter      }
303418334Speter
303518334Speter    case ADDR_EXPR:
303618334Speter      /* Note that this operation never does default_conversion
303718334Speter	 regardless of NOCONVERT.  */
303818334Speter
303918334Speter      /* Let &* cancel out to simplify resulting code.  */
304018334Speter      if (TREE_CODE (arg) == INDIRECT_REF)
304118334Speter	{
304218334Speter	  /* Don't let this be an lvalue.  */
304318334Speter	  if (lvalue_p (TREE_OPERAND (arg, 0)))
304418334Speter	    return non_lvalue (TREE_OPERAND (arg, 0));
304518334Speter	  return TREE_OPERAND (arg, 0);
304618334Speter	}
304718334Speter
304818334Speter      /* For &x[y], return x+y */
304918334Speter      if (TREE_CODE (arg) == ARRAY_REF)
305018334Speter	{
305118334Speter	  if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
305218334Speter	    return error_mark_node;
305318334Speter	  return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
305418334Speter				  TREE_OPERAND (arg, 1), 1);
305518334Speter	}
305618334Speter
305718334Speter      /* Handle complex lvalues (when permitted)
305818334Speter	 by reduction to simpler cases.  */
305918334Speter      val = unary_complex_lvalue (code, arg);
306018334Speter      if (val != 0)
306118334Speter	return val;
306218334Speter
306318334Speter#if 0 /* Turned off because inconsistent;
306418334Speter	 float f; *&(int)f = 3.4 stores in int format
306518334Speter	 whereas (int)f = 3.4 stores in float format.  */
306618334Speter      /* Address of a cast is just a cast of the address
306718334Speter	 of the operand of the cast.  */
306818334Speter      switch (TREE_CODE (arg))
306918334Speter	{
307018334Speter	case NOP_EXPR:
307118334Speter	case CONVERT_EXPR:
307218334Speter	case FLOAT_EXPR:
307318334Speter	case FIX_TRUNC_EXPR:
307418334Speter	case FIX_FLOOR_EXPR:
307518334Speter	case FIX_ROUND_EXPR:
307618334Speter	case FIX_CEIL_EXPR:
307718334Speter	  if (pedantic)
307818334Speter	    pedwarn ("ANSI C forbids the address of a cast expression");
307918334Speter	  return convert (build_pointer_type (TREE_TYPE (arg)),
308018334Speter			  build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0),
308118334Speter					  0));
308218334Speter	}
308318334Speter#endif
308418334Speter
308518334Speter      /* Allow the address of a constructor if all the elements
308618334Speter	 are constant.  */
308718334Speter      if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg))
308818334Speter	;
308918334Speter      /* Anything not already handled and not a true memory reference
309018334Speter	 is an error.  */
309152284Sobrien      else if (typecode != FUNCTION_TYPE
309252284Sobrien	       && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
309318334Speter	return error_mark_node;
309418334Speter
309518334Speter      /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
309618334Speter      argtype = TREE_TYPE (arg);
309752284Sobrien      /* If the lvalue is const or volatile, merge that into the type
309852284Sobrien         to which the address will point.  Note that you can't get a
309952284Sobrien	 restricted pointer by taking the address of something, so we
310052284Sobrien	 only have to deal with `const' and `volatile' here.  */
310118334Speter      if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
310218334Speter	  || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
310318334Speter	{
310418334Speter	  if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
310518334Speter	    argtype = c_build_type_variant (argtype,
310618334Speter					    TREE_READONLY (arg),
310718334Speter					    TREE_THIS_VOLATILE (arg));
310818334Speter	}
310918334Speter
311018334Speter      argtype = build_pointer_type (argtype);
311118334Speter
311218334Speter      if (mark_addressable (arg) == 0)
311318334Speter	return error_mark_node;
311418334Speter
311518334Speter      {
311618334Speter	tree addr;
311718334Speter
311818334Speter	if (TREE_CODE (arg) == COMPONENT_REF)
311918334Speter	  {
312018334Speter	    tree field = TREE_OPERAND (arg, 1);
312118334Speter
312218334Speter	    addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
312318334Speter
312450397Sobrien	    if (DECL_C_BIT_FIELD (field))
312518334Speter	      {
312618334Speter		error ("attempt to take address of bit-field structure member `%s'",
312718334Speter		       IDENTIFIER_POINTER (DECL_NAME (field)));
312818334Speter		return error_mark_node;
312918334Speter	      }
313018334Speter
313118334Speter	    addr = convert (argtype, addr);
313218334Speter
313318334Speter	    if (! integer_zerop (DECL_FIELD_BITPOS (field)))
313418334Speter	      {
313518334Speter		tree offset
313618334Speter		  = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
313718334Speter				size_int (BITS_PER_UNIT));
313818334Speter		int flag = TREE_CONSTANT (addr);
313918334Speter		addr = fold (build (PLUS_EXPR, argtype,
314018334Speter				    addr, convert (argtype, offset)));
314118334Speter		TREE_CONSTANT (addr) = flag;
314218334Speter	      }
314318334Speter	  }
314418334Speter	else
314518334Speter	  addr = build1 (code, argtype, arg);
314618334Speter
314718334Speter	/* Address of a static or external variable or
314818334Speter	   file-scope function counts as a constant.  */
314918334Speter	if (staticp (arg)
315018334Speter	    && ! (TREE_CODE (arg) == FUNCTION_DECL
315118334Speter		  && DECL_CONTEXT (arg) != 0))
315218334Speter	  TREE_CONSTANT (addr) = 1;
315318334Speter	return addr;
315418334Speter      }
315550397Sobrien
315650397Sobrien    default:
315750397Sobrien      break;
315818334Speter    }
315918334Speter
316052284Sobrien  if (argtype == 0)
316152284Sobrien    argtype = TREE_TYPE (arg);
316252284Sobrien  return fold (build1 (code, argtype, arg));
316318334Speter}
316418334Speter
316518334Speter#if 0
316618334Speter/* If CONVERSIONS is a conversion expression or a nested sequence of such,
316718334Speter   convert ARG with the same conversions in the same order
316818334Speter   and return the result.  */
316918334Speter
317018334Speterstatic tree
317118334Speterconvert_sequence (conversions, arg)
317218334Speter     tree conversions;
317318334Speter     tree arg;
317418334Speter{
317518334Speter  switch (TREE_CODE (conversions))
317618334Speter    {
317718334Speter    case NOP_EXPR:
317818334Speter    case CONVERT_EXPR:
317918334Speter    case FLOAT_EXPR:
318018334Speter    case FIX_TRUNC_EXPR:
318118334Speter    case FIX_FLOOR_EXPR:
318218334Speter    case FIX_ROUND_EXPR:
318318334Speter    case FIX_CEIL_EXPR:
318418334Speter      return convert (TREE_TYPE (conversions),
318518334Speter		      convert_sequence (TREE_OPERAND (conversions, 0),
318618334Speter					arg));
318718334Speter
318818334Speter    default:
318918334Speter      return arg;
319018334Speter    }
319118334Speter}
319218334Speter#endif /* 0 */
319318334Speter
319418334Speter/* Return nonzero if REF is an lvalue valid for this language.
319518334Speter   Lvalues can be assigned, unless their type has TYPE_READONLY.
319618334Speter   Lvalues can have their address taken, unless they have DECL_REGISTER.  */
319718334Speter
319818334Speterint
319918334Speterlvalue_p (ref)
320018334Speter     tree ref;
320118334Speter{
320218334Speter  register enum tree_code code = TREE_CODE (ref);
320318334Speter
320418334Speter  switch (code)
320518334Speter    {
320618334Speter    case REALPART_EXPR:
320718334Speter    case IMAGPART_EXPR:
320818334Speter    case COMPONENT_REF:
320918334Speter      return lvalue_p (TREE_OPERAND (ref, 0));
321018334Speter
321118334Speter    case STRING_CST:
321218334Speter      return 1;
321318334Speter
321418334Speter    case INDIRECT_REF:
321518334Speter    case ARRAY_REF:
321618334Speter    case VAR_DECL:
321718334Speter    case PARM_DECL:
321818334Speter    case RESULT_DECL:
321918334Speter    case ERROR_MARK:
322050397Sobrien      return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
322150397Sobrien	      && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
322250397Sobrien
322350397Sobrien    case BIND_EXPR:
322450397Sobrien    case RTL_EXPR:
322550397Sobrien      return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
322650397Sobrien
322750397Sobrien    default:
322850397Sobrien      return 0;
322918334Speter    }
323018334Speter}
323118334Speter
323218334Speter/* Return nonzero if REF is an lvalue valid for this language;
323318334Speter   otherwise, print an error message and return zero.  */
323418334Speter
323518334Speterint
323652284Sobrienlvalue_or_else (ref, msgid)
323718334Speter     tree ref;
323852284Sobrien     const char *msgid;
323918334Speter{
324018334Speter  int win = lvalue_p (ref);
324118334Speter  if (! win)
324252284Sobrien    error (msgid);
324318334Speter  return win;
324418334Speter}
324518334Speter
324618334Speter/* Apply unary lvalue-demanding operator CODE to the expression ARG
324718334Speter   for certain kinds of expressions which are not really lvalues
324818334Speter   but which we can accept as lvalues.
324918334Speter
325018334Speter   If ARG is not a kind of expression we can handle, return zero.  */
325118334Speter
325218334Speterstatic tree
325318334Speterunary_complex_lvalue (code, arg)
325418334Speter     enum tree_code code;
325518334Speter     tree arg;
325618334Speter{
325718334Speter  /* Handle (a, b) used as an "lvalue".  */
325818334Speter  if (TREE_CODE (arg) == COMPOUND_EXPR)
325918334Speter    {
326018334Speter      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
326150397Sobrien
326250397Sobrien      /* If this returns a function type, it isn't really being used as
326350397Sobrien	 an lvalue, so don't issue a warning about it.  */
326450397Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE)
326550397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
326650397Sobrien
326718334Speter      return build (COMPOUND_EXPR, TREE_TYPE (real_result),
326818334Speter		    TREE_OPERAND (arg, 0), real_result);
326918334Speter    }
327018334Speter
327118334Speter  /* Handle (a ? b : c) used as an "lvalue".  */
327218334Speter  if (TREE_CODE (arg) == COND_EXPR)
327318334Speter    {
327418334Speter      pedantic_lvalue_warning (COND_EXPR);
327550397Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE)
327650397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
327750397Sobrien
327818334Speter      return (build_conditional_expr
327918334Speter	      (TREE_OPERAND (arg, 0),
328018334Speter	       build_unary_op (code, TREE_OPERAND (arg, 1), 0),
328118334Speter	       build_unary_op (code, TREE_OPERAND (arg, 2), 0)));
328218334Speter    }
328318334Speter
328418334Speter  return 0;
328518334Speter}
328618334Speter
328718334Speter/* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
328818334Speter   COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
328918334Speter
329018334Speterstatic void
329118334Speterpedantic_lvalue_warning (code)
329218334Speter     enum tree_code code;
329318334Speter{
329418334Speter  if (pedantic)
329552284Sobrien    pedwarn (code == COND_EXPR
329652284Sobrien	     ? "ANSI C forbids use of conditional expressions as lvalues"
329752284Sobrien	     : code == COMPOUND_EXPR
329852284Sobrien	     ? "ANSI C forbids use of compound expressions as lvalues"
329952284Sobrien	     : "ANSI C forbids use of cast expressions as lvalues");
330018334Speter}
330118334Speter
330218334Speter/* Warn about storing in something that is `const'.  */
330318334Speter
330418334Spetervoid
330552284Sobrienreadonly_warning (arg, msgid)
330618334Speter     tree arg;
330752284Sobrien     const char *msgid;
330818334Speter{
330918334Speter  /* Forbid assignments to iterators.  */
331018334Speter  if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg))
331152284Sobrien    pedwarn ("%s of iterator `%s'",  _(msgid),
331252284Sobrien	     IDENTIFIER_POINTER (DECL_NAME (arg)));
331318334Speter
331418334Speter  if (TREE_CODE (arg) == COMPONENT_REF)
331518334Speter    {
331618334Speter      if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
331752284Sobrien	readonly_warning (TREE_OPERAND (arg, 0), msgid);
331818334Speter      else
331952284Sobrien	pedwarn ("%s of read-only member `%s'", _(msgid),
332052284Sobrien		 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
332118334Speter    }
332218334Speter  else if (TREE_CODE (arg) == VAR_DECL)
332352284Sobrien    pedwarn ("%s of read-only variable `%s'", _(msgid),
332452284Sobrien	     IDENTIFIER_POINTER (DECL_NAME (arg)));
332518334Speter  else
332652284Sobrien    pedwarn ("%s of read-only location", _(msgid));
332718334Speter}
332818334Speter
332918334Speter/* Mark EXP saying that we need to be able to take the
333018334Speter   address of it; it should not be allocated in a register.
333118334Speter   Value is 1 if successful.  */
333218334Speter
333318334Speterint
333418334Spetermark_addressable (exp)
333518334Speter     tree exp;
333618334Speter{
333718334Speter  register tree x = exp;
333818334Speter  while (1)
333918334Speter    switch (TREE_CODE (x))
334018334Speter      {
334150397Sobrien      case COMPONENT_REF:
334250397Sobrien	if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
334350397Sobrien	  {
334450397Sobrien	    error ("cannot take address of bitfield `%s'",
334550397Sobrien		   IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
334650397Sobrien	    return 0;
334750397Sobrien	  }
334850397Sobrien
334950397Sobrien	/* ... fall through ...  */
335050397Sobrien
335118334Speter      case ADDR_EXPR:
335218334Speter      case ARRAY_REF:
335318334Speter      case REALPART_EXPR:
335418334Speter      case IMAGPART_EXPR:
335518334Speter	x = TREE_OPERAND (x, 0);
335618334Speter	break;
335718334Speter
335818334Speter      case CONSTRUCTOR:
335918334Speter	TREE_ADDRESSABLE (x) = 1;
336018334Speter	return 1;
336118334Speter
336218334Speter      case VAR_DECL:
336318334Speter      case CONST_DECL:
336418334Speter      case PARM_DECL:
336518334Speter      case RESULT_DECL:
336618334Speter	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
336718334Speter	    && DECL_NONLOCAL (x))
336818334Speter	  {
336918334Speter	    if (TREE_PUBLIC (x))
337018334Speter	      {
337118334Speter		error ("global register variable `%s' used in nested function",
337218334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
337318334Speter		return 0;
337418334Speter	      }
337518334Speter	    pedwarn ("register variable `%s' used in nested function",
337618334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
337718334Speter	  }
337818334Speter	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
337918334Speter	  {
338018334Speter	    if (TREE_PUBLIC (x))
338118334Speter	      {
338218334Speter		error ("address of global register variable `%s' requested",
338318334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
338418334Speter		return 0;
338518334Speter	      }
338618334Speter
338718334Speter	    /* If we are making this addressable due to its having
338818334Speter	       volatile components, give a different error message.  Also
338918334Speter	       handle the case of an unnamed parameter by not trying
339018334Speter	       to give the name.  */
339118334Speter
339218334Speter	    else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
339318334Speter	      {
339418334Speter		error ("cannot put object with volatile field into register");
339518334Speter		return 0;
339618334Speter	      }
339718334Speter
339818334Speter	    pedwarn ("address of register variable `%s' requested",
339918334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
340018334Speter	  }
340118334Speter	put_var_into_stack (x);
340218334Speter
340318334Speter	/* drops in */
340418334Speter      case FUNCTION_DECL:
340518334Speter	TREE_ADDRESSABLE (x) = 1;
340618334Speter#if 0  /* poplevel deals with this now.  */
340718334Speter	if (DECL_CONTEXT (x) == 0)
340818334Speter	  TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
340918334Speter#endif
341018334Speter
341118334Speter      default:
341218334Speter	return 1;
341318334Speter    }
341418334Speter}
341518334Speter
341618334Speter/* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
341718334Speter
341818334Spetertree
341918334Speterbuild_conditional_expr (ifexp, op1, op2)
342018334Speter     tree ifexp, op1, op2;
342118334Speter{
342218334Speter  register tree type1;
342318334Speter  register tree type2;
342418334Speter  register enum tree_code code1;
342518334Speter  register enum tree_code code2;
342618334Speter  register tree result_type = NULL;
342718334Speter  tree orig_op1 = op1, orig_op2 = op2;
342818334Speter
342918334Speter  ifexp = truthvalue_conversion (default_conversion (ifexp));
343018334Speter
343118334Speter#if 0 /* Produces wrong result if within sizeof.  */
343218334Speter  /* Don't promote the operands separately if they promote
343318334Speter     the same way.  Return the unpromoted type and let the combined
343418334Speter     value get promoted if necessary.  */
343518334Speter
343618334Speter  if (TREE_TYPE (op1) == TREE_TYPE (op2)
343718334Speter      && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE
343818334Speter      && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE
343918334Speter      && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE)
344018334Speter    {
344118334Speter      if (TREE_CODE (ifexp) == INTEGER_CST)
344218334Speter	return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
344318334Speter
344418334Speter      return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2));
344518334Speter    }
344618334Speter#endif
344718334Speter
344818334Speter  /* Promote both alternatives.  */
344918334Speter
345018334Speter  if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
345118334Speter    op1 = default_conversion (op1);
345218334Speter  if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
345318334Speter    op2 = default_conversion (op2);
345418334Speter
345518334Speter  if (TREE_CODE (ifexp) == ERROR_MARK
345618334Speter      || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
345718334Speter      || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
345818334Speter    return error_mark_node;
345918334Speter
346018334Speter  type1 = TREE_TYPE (op1);
346118334Speter  code1 = TREE_CODE (type1);
346218334Speter  type2 = TREE_TYPE (op2);
346318334Speter  code2 = TREE_CODE (type2);
346418334Speter
346518334Speter  /* Quickly detect the usual case where op1 and op2 have the same type
346618334Speter     after promotion.  */
346718334Speter  if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
346818334Speter    {
346918334Speter      if (type1 == type2)
347018334Speter	result_type = type1;
347118334Speter      else
347218334Speter	result_type = TYPE_MAIN_VARIANT (type1);
347318334Speter    }
347418334Speter  else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
347518334Speter           && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
347618334Speter    {
347718334Speter      result_type = common_type (type1, type2);
347818334Speter    }
347918334Speter  else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
348018334Speter    {
348118334Speter      if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
348218334Speter	pedwarn ("ANSI C forbids conditional expr with only one void side");
348318334Speter      result_type = void_type_node;
348418334Speter    }
348518334Speter  else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
348618334Speter    {
348718334Speter      if (comp_target_types (type1, type2))
348818334Speter	result_type = common_type (type1, type2);
348918334Speter      else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
349018334Speter	       && TREE_CODE (orig_op1) != NOP_EXPR)
349118334Speter	result_type = qualify_type (type2, type1);
349218334Speter      else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node
349318334Speter	       && TREE_CODE (orig_op2) != NOP_EXPR)
349418334Speter	result_type = qualify_type (type1, type2);
349518334Speter      else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node)
349618334Speter	{
349718334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
349818334Speter	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
349918334Speter	  result_type = qualify_type (type1, type2);
350018334Speter	}
350118334Speter      else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node)
350218334Speter	{
350318334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
350418334Speter	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
350518334Speter	  result_type = qualify_type (type2, type1);
350618334Speter	}
350718334Speter      else
350818334Speter	{
350918334Speter	  pedwarn ("pointer type mismatch in conditional expression");
351018334Speter	  result_type = build_pointer_type (void_type_node);
351118334Speter	}
351218334Speter    }
351318334Speter  else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
351418334Speter    {
351518334Speter      if (! integer_zerop (op2))
351618334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
351718334Speter      else
351818334Speter	{
351918334Speter	  op2 = null_pointer_node;
352018334Speter#if 0  /* The spec seems to say this is permitted.  */
352118334Speter	  if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE)
352218334Speter	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
352318334Speter#endif
352418334Speter	}
352518334Speter      result_type = type1;
352618334Speter    }
352718334Speter  else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
352818334Speter    {
352918334Speter      if (!integer_zerop (op1))
353018334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
353118334Speter      else
353218334Speter	{
353318334Speter	  op1 = null_pointer_node;
353418334Speter#if 0  /* The spec seems to say this is permitted.  */
353518334Speter	  if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
353618334Speter	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
353718334Speter#endif
353818334Speter	}
353918334Speter      result_type = type2;
354018334Speter    }
354118334Speter
354218334Speter  if (!result_type)
354318334Speter    {
354418334Speter      if (flag_cond_mismatch)
354518334Speter	result_type = void_type_node;
354618334Speter      else
354718334Speter	{
354818334Speter	  error ("type mismatch in conditional expression");
354918334Speter	  return error_mark_node;
355018334Speter	}
355118334Speter    }
355218334Speter
355318334Speter  /* Merge const and volatile flags of the incoming types.  */
355418334Speter  result_type
355518334Speter    = build_type_variant (result_type,
355618334Speter			  TREE_READONLY (op1) || TREE_READONLY (op2),
355718334Speter			  TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
355818334Speter
355918334Speter  if (result_type != TREE_TYPE (op1))
356018334Speter    op1 = convert_and_check (result_type, op1);
356118334Speter  if (result_type != TREE_TYPE (op2))
356218334Speter    op2 = convert_and_check (result_type, op2);
356318334Speter
356418334Speter#if 0
356518334Speter  if (code1 == RECORD_TYPE || code1 == UNION_TYPE)
356618334Speter    {
356718334Speter      result_type = TREE_TYPE (op1);
356818334Speter      if (TREE_CONSTANT (ifexp))
356918334Speter	return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
357018334Speter
357118334Speter      if (TYPE_MODE (result_type) == BLKmode)
357218334Speter	{
357318334Speter	  register tree tempvar
357418334Speter	    = build_decl (VAR_DECL, NULL_TREE, result_type);
357518334Speter	  register tree xop1 = build_modify_expr (tempvar, op1);
357618334Speter	  register tree xop2 = build_modify_expr (tempvar, op2);
357718334Speter	  register tree result = fold (build (COND_EXPR, result_type,
357818334Speter					      ifexp, xop1, xop2));
357918334Speter
358018334Speter	  layout_decl (tempvar, TYPE_ALIGN (result_type));
358118334Speter	  /* No way to handle variable-sized objects here.
358218334Speter	     I fear that the entire handling of BLKmode conditional exprs
358318334Speter	     needs to be redone.  */
358418334Speter	  if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST)
358518334Speter	    abort ();
358618334Speter	  DECL_RTL (tempvar)
358718334Speter	    = assign_stack_local (DECL_MODE (tempvar),
358818334Speter				  (TREE_INT_CST_LOW (DECL_SIZE (tempvar))
358918334Speter				   + BITS_PER_UNIT - 1)
359018334Speter				  / BITS_PER_UNIT,
359118334Speter				  0);
359218334Speter
359318334Speter	  TREE_SIDE_EFFECTS (result)
359418334Speter	    = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1)
359518334Speter	      | TREE_SIDE_EFFECTS (op2);
359618334Speter	  return build (COMPOUND_EXPR, result_type, result, tempvar);
359718334Speter	}
359818334Speter    }
359918334Speter#endif /* 0 */
360018334Speter
360118334Speter  if (TREE_CODE (ifexp) == INTEGER_CST)
360218334Speter    return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
360318334Speter
360418334Speter  return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
360518334Speter}
360618334Speter
360718334Speter/* Given a list of expressions, return a compound expression
360818334Speter   that performs them all and returns the value of the last of them.  */
360918334Speter
361018334Spetertree
361118334Speterbuild_compound_expr (list)
361218334Speter     tree list;
361318334Speter{
361418334Speter  return internal_build_compound_expr (list, TRUE);
361518334Speter}
361618334Speter
361718334Speterstatic tree
361818334Speterinternal_build_compound_expr (list, first_p)
361918334Speter     tree list;
362018334Speter     int first_p;
362118334Speter{
362218334Speter  register tree rest;
362318334Speter
362418334Speter  if (TREE_CHAIN (list) == 0)
362518334Speter    {
362618334Speter#if 0 /* If something inside inhibited lvalueness, we should not override.  */
362718334Speter      /* Consider (x, y+0), which is not an lvalue since y+0 is not.  */
362818334Speter
362918334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
363018334Speter      if (TREE_CODE (list) == NON_LVALUE_EXPR)
363118334Speter	list = TREE_OPERAND (list, 0);
363218334Speter#endif
363318334Speter
363418334Speter      /* Don't let (0, 0) be null pointer constant.  */
363518334Speter      if (!first_p && integer_zerop (TREE_VALUE (list)))
363618334Speter	return non_lvalue (TREE_VALUE (list));
363718334Speter      return TREE_VALUE (list);
363818334Speter    }
363918334Speter
364018334Speter  if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0)
364118334Speter    {
364218334Speter      /* Convert arrays to pointers when there really is a comma operator.  */
364318334Speter      if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE)
364418334Speter	TREE_VALUE (TREE_CHAIN (list))
364518334Speter	  = default_conversion (TREE_VALUE (TREE_CHAIN (list)));
364618334Speter    }
364718334Speter
364818334Speter  rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
364918334Speter
365018334Speter  if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
365118334Speter    {
365218334Speter      /* The left-hand operand of a comma expression is like an expression
365318334Speter         statement: with -W or -Wunused, we should warn if it doesn't have
365418334Speter	 any side-effects, unless it was explicitly cast to (void).  */
365518334Speter      if ((extra_warnings || warn_unused)
365618334Speter           && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
365718334Speter                && TREE_TYPE (TREE_VALUE (list)) == void_type_node))
365818334Speter        warning ("left-hand operand of comma expression has no effect");
365918334Speter
366018334Speter      /* When pedantic, a compound expression can be neither an lvalue
366118334Speter         nor an integer constant expression.  */
366218334Speter      if (! pedantic)
366318334Speter        return rest;
366418334Speter    }
366518334Speter
366618334Speter  /* With -Wunused, we should also warn if the left-hand operand does have
366718334Speter     side-effects, but computes a value which is not used.  For example, in
366818334Speter     `foo() + bar(), baz()' the result of the `+' operator is not used,
366918334Speter     so we should issue a warning.  */
367018334Speter  else if (warn_unused)
367118334Speter    warn_if_unused_value (TREE_VALUE (list));
367218334Speter
367318334Speter  return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
367418334Speter}
367518334Speter
367618334Speter/* Build an expression representing a cast to type TYPE of expression EXPR.  */
367718334Speter
367818334Spetertree
367918334Speterbuild_c_cast (type, expr)
368018334Speter     register tree type;
368118334Speter     tree expr;
368218334Speter{
368318334Speter  register tree value = expr;
368418334Speter
368518334Speter  if (type == error_mark_node || expr == error_mark_node)
368618334Speter    return error_mark_node;
368718334Speter  type = TYPE_MAIN_VARIANT (type);
368818334Speter
368918334Speter#if 0
369018334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
369118334Speter  if (TREE_CODE (value) == NON_LVALUE_EXPR)
369218334Speter    value = TREE_OPERAND (value, 0);
369318334Speter#endif
369418334Speter
369518334Speter  if (TREE_CODE (type) == ARRAY_TYPE)
369618334Speter    {
369718334Speter      error ("cast specifies array type");
369818334Speter      return error_mark_node;
369918334Speter    }
370018334Speter
370118334Speter  if (TREE_CODE (type) == FUNCTION_TYPE)
370218334Speter    {
370318334Speter      error ("cast specifies function type");
370418334Speter      return error_mark_node;
370518334Speter    }
370618334Speter
370718334Speter  if (type == TREE_TYPE (value))
370818334Speter    {
370918334Speter      if (pedantic)
371018334Speter	{
371118334Speter	  if (TREE_CODE (type) == RECORD_TYPE
371218334Speter	      || TREE_CODE (type) == UNION_TYPE)
371318334Speter	    pedwarn ("ANSI C forbids casting nonscalar to the same type");
371418334Speter	}
371518334Speter    }
371618334Speter  else if (TREE_CODE (type) == UNION_TYPE)
371718334Speter    {
371818334Speter      tree field;
371918334Speter      if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
372018334Speter	  || TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE)
372118334Speter	value = default_conversion (value);
372218334Speter
372318334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
372418334Speter	if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
372518334Speter		       TYPE_MAIN_VARIANT (TREE_TYPE (value))))
372618334Speter	  break;
372718334Speter
372818334Speter      if (field)
372918334Speter	{
373052284Sobrien	  const char *name;
373118334Speter	  tree t;
373218334Speter
373318334Speter	  if (pedantic)
373418334Speter	    pedwarn ("ANSI C forbids casts to union type");
373518334Speter	  if (TYPE_NAME (type) != 0)
373618334Speter	    {
373718334Speter	      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
373818334Speter		name = IDENTIFIER_POINTER (TYPE_NAME (type));
373918334Speter	      else
374018334Speter		name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
374118334Speter	    }
374218334Speter	  else
374318334Speter	    name = "";
374418334Speter	  t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
374518334Speter					build_tree_list (field, value)),
374618334Speter			   0, 0);
374718334Speter	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
374818334Speter	  return t;
374918334Speter	}
375018334Speter      error ("cast to union type from type not present in union");
375118334Speter      return error_mark_node;
375218334Speter    }
375318334Speter  else
375418334Speter    {
375518334Speter      tree otype, ovalue;
375618334Speter
375718334Speter      /* If casting to void, avoid the error that would come
375818334Speter	 from default_conversion in the case of a non-lvalue array.  */
375918334Speter      if (type == void_type_node)
376018334Speter	return build1 (CONVERT_EXPR, type, value);
376118334Speter
376218334Speter      /* Convert functions and arrays to pointers,
376318334Speter	 but don't convert any other types.  */
376418334Speter      if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
376518334Speter	  || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE)
376618334Speter	value = default_conversion (value);
376718334Speter      otype = TREE_TYPE (value);
376818334Speter
376918334Speter      /* Optionally warn about potentially worrisome casts.  */
377018334Speter
377118334Speter      if (warn_cast_qual
377218334Speter	  && TREE_CODE (type) == POINTER_TYPE
377318334Speter	  && TREE_CODE (otype) == POINTER_TYPE)
377418334Speter	{
377550397Sobrien	  /* Go to the innermost object being pointed to.  */
377650397Sobrien	  tree in_type = type;
377750397Sobrien	  tree in_otype = otype;
377850397Sobrien
377950397Sobrien	  while (TREE_CODE (in_type) == POINTER_TYPE)
378050397Sobrien	    in_type = TREE_TYPE (in_type);
378150397Sobrien	  while (TREE_CODE (in_otype) == POINTER_TYPE)
378250397Sobrien	    in_otype = TREE_TYPE (in_otype);
378352284Sobrien
378452284Sobrien	  if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type))
378552284Sobrien	    /* There are qualifiers present in IN_OTYPE that are not
378652284Sobrien	       present in IN_TYPE.  */
378752284Sobrien	    pedwarn ("cast discards qualifiers from pointer target type");
378818334Speter	}
378918334Speter
379018334Speter      /* Warn about possible alignment problems.  */
379118334Speter      if (STRICT_ALIGNMENT && warn_cast_align
379218334Speter	  && TREE_CODE (type) == POINTER_TYPE
379318334Speter	  && TREE_CODE (otype) == POINTER_TYPE
379418334Speter	  && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
379518334Speter	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
379650397Sobrien	  /* Don't warn about opaque types, where the actual alignment
379750397Sobrien	     restriction is unknown.  */
379850397Sobrien	  && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
379950397Sobrien		|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
380050397Sobrien	       && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
380118334Speter	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
380218334Speter	warning ("cast increases required alignment of target type");
380318334Speter
380418334Speter      if (TREE_CODE (type) == INTEGER_TYPE
380518334Speter	  && TREE_CODE (otype) == POINTER_TYPE
380618334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
380718334Speter	  && !TREE_CONSTANT (value))
380818334Speter	warning ("cast from pointer to integer of different size");
380918334Speter
381018334Speter      if (warn_bad_function_cast
381118334Speter	  && TREE_CODE (value) == CALL_EXPR
381218334Speter	  && TREE_CODE (type) != TREE_CODE (otype))
381318334Speter	warning ("cast does not match function type");
381418334Speter
381518334Speter      if (TREE_CODE (type) == POINTER_TYPE
381618334Speter	  && TREE_CODE (otype) == INTEGER_TYPE
381718334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
381818334Speter#if 0
381918334Speter	  /* Don't warn about converting 0 to pointer,
382018334Speter	     provided the 0 was explicit--not cast or made by folding.  */
382118334Speter	  && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))
382218334Speter#endif
382318334Speter	  /* Don't warn about converting any constant.  */
382418334Speter	  && !TREE_CONSTANT (value))
382518334Speter	warning ("cast to pointer from integer of different size");
382618334Speter
382718334Speter      ovalue = value;
382818334Speter      value = convert (type, value);
382918334Speter
383018334Speter      /* Ignore any integer overflow caused by the cast.  */
383118334Speter      if (TREE_CODE (value) == INTEGER_CST)
383218334Speter	{
383318334Speter	  TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
383418334Speter	  TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
383518334Speter	}
383618334Speter    }
383718334Speter
383818334Speter  /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant.  */
383918334Speter  if (pedantic && TREE_CODE (value) == INTEGER_CST
384018334Speter      && TREE_CODE (expr) == INTEGER_CST
384118334Speter      && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
384218334Speter    value = non_lvalue (value);
384318334Speter
384418334Speter  /* If pedantic, don't let a cast be an lvalue.  */
384518334Speter  if (value == expr && pedantic)
384618334Speter    value = non_lvalue (value);
384718334Speter
384818334Speter  return value;
384918334Speter}
385018334Speter
385118334Speter/* Build an assignment expression of lvalue LHS from value RHS.
385218334Speter   MODIFYCODE is the code for a binary operator that we use
385318334Speter   to combine the old value of LHS with RHS to get the new value.
385418334Speter   Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.  */
385518334Speter
385618334Spetertree
385718334Speterbuild_modify_expr (lhs, modifycode, rhs)
385818334Speter     tree lhs, rhs;
385918334Speter     enum tree_code modifycode;
386018334Speter{
386118334Speter  register tree result;
386218334Speter  tree newrhs;
386318334Speter  tree lhstype = TREE_TYPE (lhs);
386418334Speter  tree olhstype = lhstype;
386518334Speter
386618334Speter  /* Types that aren't fully specified cannot be used in assignments.  */
386718334Speter  lhs = require_complete_type (lhs);
386818334Speter
386918334Speter  /* Avoid duplicate error messages from operands that had errors.  */
387018334Speter  if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
387118334Speter    return error_mark_node;
387218334Speter
387318334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
387418334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
387518334Speter     whose value is 0 to count as a null pointer constant.  */
387618334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
387718334Speter    rhs = TREE_OPERAND (rhs, 0);
387818334Speter
387918334Speter  newrhs = rhs;
388018334Speter
388118334Speter  /* Handle control structure constructs used as "lvalues".  */
388218334Speter
388318334Speter  switch (TREE_CODE (lhs))
388418334Speter    {
388518334Speter      /* Handle (a, b) used as an "lvalue".  */
388618334Speter    case COMPOUND_EXPR:
388718334Speter      pedantic_lvalue_warning (COMPOUND_EXPR);
388818334Speter      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
388918334Speter				  modifycode, rhs);
389018334Speter      if (TREE_CODE (newrhs) == ERROR_MARK)
389118334Speter	return error_mark_node;
389218334Speter      return build (COMPOUND_EXPR, lhstype,
389318334Speter		    TREE_OPERAND (lhs, 0), newrhs);
389418334Speter
389518334Speter      /* Handle (a ? b : c) used as an "lvalue".  */
389618334Speter    case COND_EXPR:
389718334Speter      pedantic_lvalue_warning (COND_EXPR);
389818334Speter      rhs = save_expr (rhs);
389918334Speter      {
390018334Speter	/* Produce (a ? (b = rhs) : (c = rhs))
390118334Speter	   except that the RHS goes through a save-expr
390218334Speter	   so the code to compute it is only emitted once.  */
390318334Speter	tree cond
390418334Speter	  = build_conditional_expr (TREE_OPERAND (lhs, 0),
390518334Speter				    build_modify_expr (TREE_OPERAND (lhs, 1),
390618334Speter						       modifycode, rhs),
390718334Speter				    build_modify_expr (TREE_OPERAND (lhs, 2),
390818334Speter						       modifycode, rhs));
390918334Speter	if (TREE_CODE (cond) == ERROR_MARK)
391018334Speter	  return cond;
391118334Speter	/* Make sure the code to compute the rhs comes out
391218334Speter	   before the split.  */
391318334Speter	return build (COMPOUND_EXPR, TREE_TYPE (lhs),
391418334Speter		      /* But cast it to void to avoid an "unused" error.  */
391518334Speter		      convert (void_type_node, rhs), cond);
391618334Speter      }
391750397Sobrien    default:
391850397Sobrien      break;
391918334Speter    }
392018334Speter
392118334Speter  /* If a binary op has been requested, combine the old LHS value with the RHS
392218334Speter     producing the value we should actually store into the LHS.  */
392318334Speter
392418334Speter  if (modifycode != NOP_EXPR)
392518334Speter    {
392618334Speter      lhs = stabilize_reference (lhs);
392718334Speter      newrhs = build_binary_op (modifycode, lhs, rhs, 1);
392818334Speter    }
392918334Speter
393018334Speter  /* Handle a cast used as an "lvalue".
393118334Speter     We have already performed any binary operator using the value as cast.
393218334Speter     Now convert the result to the cast type of the lhs,
393318334Speter     and then true type of the lhs and store it there;
393418334Speter     then convert result back to the cast type to be the value
393518334Speter     of the assignment.  */
393618334Speter
393718334Speter  switch (TREE_CODE (lhs))
393818334Speter    {
393918334Speter    case NOP_EXPR:
394018334Speter    case CONVERT_EXPR:
394118334Speter    case FLOAT_EXPR:
394218334Speter    case FIX_TRUNC_EXPR:
394318334Speter    case FIX_FLOOR_EXPR:
394418334Speter    case FIX_ROUND_EXPR:
394518334Speter    case FIX_CEIL_EXPR:
394618334Speter      if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
394718334Speter	  || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE)
394818334Speter	newrhs = default_conversion (newrhs);
394918334Speter      {
395018334Speter	tree inner_lhs = TREE_OPERAND (lhs, 0);
395118334Speter	tree result;
395218334Speter	result = build_modify_expr (inner_lhs, NOP_EXPR,
395318334Speter				    convert (TREE_TYPE (inner_lhs),
395418334Speter					     convert (lhstype, newrhs)));
395518334Speter	if (TREE_CODE (result) == ERROR_MARK)
395618334Speter	  return result;
395718334Speter	pedantic_lvalue_warning (CONVERT_EXPR);
395818334Speter	return convert (TREE_TYPE (lhs), result);
395918334Speter      }
396050397Sobrien
396150397Sobrien    default:
396250397Sobrien      break;
396318334Speter    }
396418334Speter
396518334Speter  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
396618334Speter     Reject anything strange now.  */
396718334Speter
396852284Sobrien  if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
396918334Speter    return error_mark_node;
397018334Speter
397118334Speter  /* Warn about storing in something that is `const'.  */
397218334Speter
397318334Speter  if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
397418334Speter      || ((TREE_CODE (lhstype) == RECORD_TYPE
397518334Speter	   || TREE_CODE (lhstype) == UNION_TYPE)
397618334Speter	  && C_TYPE_FIELDS_READONLY (lhstype)))
397718334Speter    readonly_warning (lhs, "assignment");
397818334Speter
397918334Speter  /* If storing into a structure or union member,
398018334Speter     it has probably been given type `int'.
398118334Speter     Compute the type that would go with
398218334Speter     the actual amount of storage the member occupies.  */
398318334Speter
398418334Speter  if (TREE_CODE (lhs) == COMPONENT_REF
398518334Speter      && (TREE_CODE (lhstype) == INTEGER_TYPE
398618334Speter	  || TREE_CODE (lhstype) == REAL_TYPE
398718334Speter	  || TREE_CODE (lhstype) == ENUMERAL_TYPE))
398818334Speter    lhstype = TREE_TYPE (get_unwidened (lhs, 0));
398918334Speter
399018334Speter  /* If storing in a field that is in actuality a short or narrower than one,
399118334Speter     we must store in the field in its actual type.  */
399218334Speter
399318334Speter  if (lhstype != TREE_TYPE (lhs))
399418334Speter    {
399518334Speter      lhs = copy_node (lhs);
399618334Speter      TREE_TYPE (lhs) = lhstype;
399718334Speter    }
399818334Speter
399918334Speter  /* Convert new value to destination type.  */
400018334Speter
400152284Sobrien  newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
400218334Speter				   NULL_TREE, NULL_TREE, 0);
400318334Speter  if (TREE_CODE (newrhs) == ERROR_MARK)
400418334Speter    return error_mark_node;
400518334Speter
400618334Speter  result = build (MODIFY_EXPR, lhstype, lhs, newrhs);
400718334Speter  TREE_SIDE_EFFECTS (result) = 1;
400818334Speter
400918334Speter  /* If we got the LHS in a different type for storing in,
401018334Speter     convert the result back to the nominal type of LHS
401118334Speter     so that the value we return always has the same type
401218334Speter     as the LHS argument.  */
401318334Speter
401418334Speter  if (olhstype == TREE_TYPE (result))
401518334Speter    return result;
401652284Sobrien  return convert_for_assignment (olhstype, result, _("assignment"),
401718334Speter				 NULL_TREE, NULL_TREE, 0);
401818334Speter}
401918334Speter
402018334Speter/* Convert value RHS to type TYPE as preparation for an assignment
402118334Speter   to an lvalue of type TYPE.
402218334Speter   The real work of conversion is done by `convert'.
402318334Speter   The purpose of this function is to generate error messages
402418334Speter   for assignments that are not allowed in C.
402518334Speter   ERRTYPE is a string to use in error messages:
402618334Speter   "assignment", "return", etc.  If it is null, this is parameter passing
402752284Sobrien   for a function call (and different error messages are output).
402818334Speter
402918334Speter   FUNNAME is the name of the function being called,
403018334Speter   as an IDENTIFIER_NODE, or null.
403118334Speter   PARMNUM is the number of the argument, for printing in error messages.  */
403218334Speter
403318334Speterstatic tree
403418334Speterconvert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
403518334Speter     tree type, rhs;
403652284Sobrien     const char *errtype;
403718334Speter     tree fundecl, funname;
403818334Speter     int parmnum;
403918334Speter{
404018334Speter  register enum tree_code codel = TREE_CODE (type);
404118334Speter  register tree rhstype;
404218334Speter  register enum tree_code coder;
404318334Speter
404418334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
404518334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
404618334Speter     whose value is 0 to count as a null pointer constant.  */
404718334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
404818334Speter    rhs = TREE_OPERAND (rhs, 0);
404918334Speter
405018334Speter  if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
405118334Speter      || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE)
405218334Speter    rhs = default_conversion (rhs);
405318334Speter  else if (optimize && TREE_CODE (rhs) == VAR_DECL)
405418334Speter    rhs = decl_constant_value (rhs);
405518334Speter
405618334Speter  rhstype = TREE_TYPE (rhs);
405718334Speter  coder = TREE_CODE (rhstype);
405818334Speter
405918334Speter  if (coder == ERROR_MARK)
406018334Speter    return error_mark_node;
406118334Speter
406218334Speter  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
406318334Speter    {
406418334Speter      overflow_warning (rhs);
406518334Speter      /* Check for Objective-C protocols.  This will issue a warning if
406618334Speter	 there are protocol violations.  No need to use the return value.  */
406718334Speter      maybe_objc_comptypes (type, rhstype, 0);
406818334Speter      return rhs;
406918334Speter    }
407018334Speter
407118334Speter  if (coder == VOID_TYPE)
407218334Speter    {
407318334Speter      error ("void value not ignored as it ought to be");
407418334Speter      return error_mark_node;
407518334Speter    }
407618334Speter  /* Arithmetic types all interconvert, and enum is treated like int.  */
407718334Speter  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
407818334Speter       || codel == COMPLEX_TYPE)
407918334Speter      && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
408018334Speter	  || coder == COMPLEX_TYPE))
408118334Speter    return convert_and_check (type, rhs);
408218334Speter
408350397Sobrien  /* Conversion to a transparent union from its member types.
408450397Sobrien     This applies only to function arguments.  */
408550397Sobrien  else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype)
408618334Speter    {
408718334Speter      tree memb_types;
408850397Sobrien      tree marginal_memb_type = 0;
408918334Speter
409018334Speter      for (memb_types = TYPE_FIELDS (type); memb_types;
409118334Speter	   memb_types = TREE_CHAIN (memb_types))
409218334Speter	{
409350397Sobrien	  tree memb_type = TREE_TYPE (memb_types);
409418334Speter
409550397Sobrien	  if (comptypes (TYPE_MAIN_VARIANT (memb_type),
409650397Sobrien			 TYPE_MAIN_VARIANT (rhstype)))
409750397Sobrien	    break;
409850397Sobrien
409950397Sobrien	  if (TREE_CODE (memb_type) != POINTER_TYPE)
410050397Sobrien	    continue;
410150397Sobrien
410250397Sobrien	  if (coder == POINTER_TYPE)
410318334Speter	    {
410418334Speter	      register tree ttl = TREE_TYPE (memb_type);
410518334Speter	      register tree ttr = TREE_TYPE (rhstype);
410618334Speter
410718334Speter	      /* Any non-function converts to a [const][volatile] void *
410818334Speter		 and vice versa; otherwise, targets must be the same.
410918334Speter		 Meanwhile, the lhs target must have all the qualifiers of
411018334Speter		 the rhs.  */
411118334Speter	      if (TYPE_MAIN_VARIANT (ttl) == void_type_node
411218334Speter		  || TYPE_MAIN_VARIANT (ttr) == void_type_node
411318334Speter		  || comp_target_types (memb_type, rhstype))
411418334Speter		{
411550397Sobrien		  /* If this type won't generate any warnings, use it.  */
411652284Sobrien		  if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
411752284Sobrien		      || ((TREE_CODE (ttr) == FUNCTION_TYPE
411852284Sobrien			   && TREE_CODE (ttl) == FUNCTION_TYPE)
411952284Sobrien			  ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
412052284Sobrien			     == TYPE_QUALS (ttr))
412152284Sobrien			  : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
412252284Sobrien			     == TYPE_QUALS (ttl))))
412350397Sobrien		    break;
412418334Speter
412550397Sobrien		  /* Keep looking for a better type, but remember this one.  */
412650397Sobrien		  if (! marginal_memb_type)
412750397Sobrien		    marginal_memb_type = memb_type;
412818334Speter		}
412918334Speter	    }
413018334Speter
413118334Speter	  /* Can convert integer zero to any pointer type.  */
413250397Sobrien	  if (integer_zerop (rhs)
413350397Sobrien	      || (TREE_CODE (rhs) == NOP_EXPR
413450397Sobrien		  && integer_zerop (TREE_OPERAND (rhs, 0))))
413550397Sobrien	    {
413650397Sobrien	      rhs = null_pointer_node;
413750397Sobrien	      break;
413850397Sobrien	    }
413918334Speter	}
414050397Sobrien
414150397Sobrien      if (memb_types || marginal_memb_type)
414250397Sobrien	{
414350397Sobrien	  if (! memb_types)
414450397Sobrien	    {
414550397Sobrien	      /* We have only a marginally acceptable member type;
414650397Sobrien		 it needs a warning.  */
414750397Sobrien	      register tree ttl = TREE_TYPE (marginal_memb_type);
414850397Sobrien	      register tree ttr = TREE_TYPE (rhstype);
414950397Sobrien
415050397Sobrien	      /* Const and volatile mean something different for function
415150397Sobrien		 types, so the usual warnings are not appropriate.  */
415250397Sobrien	      if (TREE_CODE (ttr) == FUNCTION_TYPE
415350397Sobrien		  && TREE_CODE (ttl) == FUNCTION_TYPE)
415450397Sobrien		{
415550397Sobrien		  /* Because const and volatile on functions are
415650397Sobrien		     restrictions that say the function will not do
415750397Sobrien		     certain things, it is okay to use a const or volatile
415850397Sobrien		     function where an ordinary one is wanted, but not
415950397Sobrien		     vice-versa.  */
416052284Sobrien		  if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
416152284Sobrien		    warn_for_assignment ("%s makes qualified function pointer from unqualified",
416252284Sobrien					 errtype, funname, parmnum);
416350397Sobrien		}
416452284Sobrien	      else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
416552284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
416652284Sobrien				     errtype, funname,
416752284Sobrien				     parmnum);
416850397Sobrien	    }
416950397Sobrien
417050397Sobrien	  if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
417150397Sobrien	    pedwarn ("ANSI C prohibits argument conversion to union type");
417250397Sobrien
417350397Sobrien	  return build1 (NOP_EXPR, type, rhs);
417450397Sobrien	}
417518334Speter    }
417618334Speter
417718334Speter  /* Conversions among pointers */
417818334Speter  else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
417918334Speter    {
418018334Speter      register tree ttl = TREE_TYPE (type);
418118334Speter      register tree ttr = TREE_TYPE (rhstype);
418218334Speter
418318334Speter      /* Any non-function converts to a [const][volatile] void *
418418334Speter	 and vice versa; otherwise, targets must be the same.
418518334Speter	 Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
418618334Speter      if (TYPE_MAIN_VARIANT (ttl) == void_type_node
418718334Speter	  || TYPE_MAIN_VARIANT (ttr) == void_type_node
418818334Speter	  || comp_target_types (type, rhstype)
418918334Speter	  || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
419018334Speter	      == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
419118334Speter	{
419218334Speter	  if (pedantic
419318334Speter	      && ((TYPE_MAIN_VARIANT (ttl) == void_type_node
419418334Speter		   && TREE_CODE (ttr) == FUNCTION_TYPE)
419518334Speter		  ||
419618334Speter		  (TYPE_MAIN_VARIANT (ttr) == void_type_node
419718334Speter		   /* Check TREE_CODE to catch cases like (void *) (char *) 0
419818334Speter		      which are not ANSI null ptr constants.  */
419918334Speter		   && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
420018334Speter		   && TREE_CODE (ttl) == FUNCTION_TYPE)))
420118334Speter	    warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
420252284Sobrien				 errtype, funname, parmnum);
420318334Speter	  /* Const and volatile mean something different for function types,
420418334Speter	     so the usual warnings are not appropriate.  */
420518334Speter	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
420618334Speter		   && TREE_CODE (ttl) != FUNCTION_TYPE)
420718334Speter	    {
420852284Sobrien	      if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
420952284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
421052284Sobrien				     errtype, funname, parmnum);
421118334Speter	      /* If this is not a case of ignoring a mismatch in signedness,
421218334Speter		 no warning.  */
421318334Speter	      else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
421418334Speter		       || TYPE_MAIN_VARIANT (ttr) == void_type_node
421518334Speter		       || comp_target_types (type, rhstype))
421618334Speter		;
421718334Speter	      /* If there is a mismatch, do warn.  */
421818334Speter	      else if (pedantic)
421918334Speter		warn_for_assignment ("pointer targets in %s differ in signedness",
422052284Sobrien				     errtype, funname, parmnum);
422118334Speter	    }
422218334Speter	  else if (TREE_CODE (ttl) == FUNCTION_TYPE
422318334Speter		   && TREE_CODE (ttr) == FUNCTION_TYPE)
422418334Speter	    {
422518334Speter	      /* Because const and volatile on functions are restrictions
422618334Speter		 that say the function will not do certain things,
422718334Speter		 it is okay to use a const or volatile function
422818334Speter		 where an ordinary one is wanted, but not vice-versa.  */
422952284Sobrien	      if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
423052284Sobrien		warn_for_assignment ("%s makes qualified function pointer from unqualified",
423152284Sobrien				     errtype, funname, parmnum);
423218334Speter	    }
423318334Speter	}
423418334Speter      else
423518334Speter	warn_for_assignment ("%s from incompatible pointer type",
423652284Sobrien			     errtype, funname, parmnum);
423718334Speter      return convert (type, rhs);
423818334Speter    }
423918334Speter  else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
424018334Speter    {
424118334Speter      /* An explicit constant 0 can convert to a pointer,
424218334Speter	 or one that results from arithmetic, even including
424318334Speter	 a cast to integer type.  */
424418334Speter      if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))
424518334Speter	  &&
424618334Speter	  ! (TREE_CODE (rhs) == NOP_EXPR
424718334Speter	     && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
424818334Speter	     && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
424918334Speter	     && integer_zerop (TREE_OPERAND (rhs, 0))))
425018334Speter	{
425118334Speter	  warn_for_assignment ("%s makes pointer from integer without a cast",
425252284Sobrien			       errtype, funname, parmnum);
425318334Speter	  return convert (type, rhs);
425418334Speter	}
425518334Speter      return null_pointer_node;
425618334Speter    }
425718334Speter  else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
425818334Speter    {
425918334Speter      warn_for_assignment ("%s makes integer from pointer without a cast",
426052284Sobrien			   errtype, funname, parmnum);
426118334Speter      return convert (type, rhs);
426218334Speter    }
426318334Speter
426418334Speter  if (!errtype)
426518334Speter    {
426618334Speter      if (funname)
426718334Speter 	{
426818334Speter 	  tree selector = maybe_building_objc_message_expr ();
426918334Speter
427018334Speter 	  if (selector && parmnum > 2)
427118334Speter 	    error ("incompatible type for argument %d of `%s'",
427218334Speter		   parmnum - 2, IDENTIFIER_POINTER (selector));
427318334Speter 	  else
427418334Speter	    error ("incompatible type for argument %d of `%s'",
427518334Speter		   parmnum, IDENTIFIER_POINTER (funname));
427618334Speter	}
427718334Speter      else
427818334Speter	error ("incompatible type for argument %d of indirect function call",
427918334Speter	       parmnum);
428018334Speter    }
428118334Speter  else
428252284Sobrien    error ("incompatible types in %s", errtype);
428318334Speter
428418334Speter  return error_mark_node;
428518334Speter}
428618334Speter
428752284Sobrien/* Print a warning using MSGID.
428818334Speter   It gets OPNAME as its one parameter.
428918334Speter   If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
429018334Speter   FUNCTION and ARGNUM are handled specially if we are building an
429118334Speter   Objective-C selector.  */
429218334Speter
429318334Speterstatic void
429452284Sobrienwarn_for_assignment (msgid, opname, function, argnum)
429552284Sobrien     const char *msgid;
429652284Sobrien     const char *opname;
429718334Speter     tree function;
429818334Speter     int argnum;
429918334Speter{
430018334Speter  if (opname == 0)
430118334Speter    {
430218334Speter      tree selector = maybe_building_objc_message_expr ();
430352284Sobrien      char * new_opname;
430418334Speter
430518334Speter      if (selector && argnum > 2)
430618334Speter	{
430718334Speter	  function = selector;
430818334Speter	  argnum -= 2;
430918334Speter	}
431018334Speter      if (function)
431118334Speter	{
431218334Speter	  /* Function name is known; supply it.  */
431352284Sobrien	  const char *argstring = _("passing arg %d of `%s'");
431452284Sobrien	  new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
431552284Sobrien					+ strlen (argstring) + 1 + 25
431652284Sobrien					/*%d*/ + 1);
431752284Sobrien	  sprintf (new_opname, argstring, argnum,
431852284Sobrien		   IDENTIFIER_POINTER (function));
431918334Speter	}
432018334Speter      else
432118334Speter	{
432252284Sobrien	  /* Function name unknown (call through ptr); just give arg number.*/
432352284Sobrien	  const char *argnofun = _("passing arg %d of pointer to function");
432452284Sobrien	  new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
432552284Sobrien	  sprintf (new_opname, argnofun, argnum);
432618334Speter	}
432752284Sobrien      opname = new_opname;
432818334Speter    }
432952284Sobrien  pedwarn (msgid, opname);
433018334Speter}
433118334Speter
433218334Speter/* Return nonzero if VALUE is a valid constant-valued expression
433318334Speter   for use in initializing a static variable; one that can be an
433418334Speter   element of a "constant" initializer.
433518334Speter
433618334Speter   Return null_pointer_node if the value is absolute;
433718334Speter   if it is relocatable, return the variable that determines the relocation.
433818334Speter   We assume that VALUE has been folded as much as possible;
433918334Speter   therefore, we do not need to check for such things as
434018334Speter   arithmetic-combinations of integers.  */
434118334Speter
434218334Spetertree
434318334Speterinitializer_constant_valid_p (value, endtype)
434418334Speter     tree value;
434518334Speter     tree endtype;
434618334Speter{
434718334Speter  switch (TREE_CODE (value))
434818334Speter    {
434918334Speter    case CONSTRUCTOR:
435018334Speter      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
435118334Speter	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
435250397Sobrien	  && TREE_CONSTANT (value)
435350397Sobrien	  && CONSTRUCTOR_ELTS (value))
435418334Speter	return
435518334Speter	  initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
435618334Speter					endtype);
435718334Speter
435818334Speter      return TREE_STATIC (value) ? null_pointer_node : 0;
435918334Speter
436018334Speter    case INTEGER_CST:
436118334Speter    case REAL_CST:
436218334Speter    case STRING_CST:
436318334Speter    case COMPLEX_CST:
436418334Speter      return null_pointer_node;
436518334Speter
436618334Speter    case ADDR_EXPR:
436718334Speter      return TREE_OPERAND (value, 0);
436818334Speter
436918334Speter    case NON_LVALUE_EXPR:
437018334Speter      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
437118334Speter
437218334Speter    case CONVERT_EXPR:
437318334Speter    case NOP_EXPR:
437418334Speter      /* Allow conversions between pointer types.  */
437518334Speter      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
437618334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
437718334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
437818334Speter
437918334Speter      /* Allow conversions between real types.  */
438018334Speter      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
438118334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
438218334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
438318334Speter
438418334Speter      /* Allow length-preserving conversions between integer types.  */
438518334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
438618334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
438718334Speter	  && (TYPE_PRECISION (TREE_TYPE (value))
438818334Speter	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
438918334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
439018334Speter
439118334Speter      /* Allow conversions between other integer types only if
439218334Speter	 explicit value.  */
439318334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
439418334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
439518334Speter	{
439618334Speter	  tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
439718334Speter						     endtype);
439818334Speter	  if (inner == null_pointer_node)
439918334Speter	    return null_pointer_node;
440018334Speter	  return 0;
440118334Speter	}
440218334Speter
440318334Speter      /* Allow (int) &foo provided int is as wide as a pointer.  */
440418334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
440518334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
440618334Speter	  && (TYPE_PRECISION (TREE_TYPE (value))
440718334Speter	      >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
440818334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
440918334Speter					     endtype);
441018334Speter
441152284Sobrien      /* Likewise conversions from int to pointers, but also allow
441252284Sobrien	 conversions from 0.  */
441318334Speter      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
441452284Sobrien	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
441552284Sobrien	{
441652284Sobrien	  if (integer_zerop (TREE_OPERAND (value, 0)))
441752284Sobrien	    return null_pointer_node;
441852284Sobrien	  else if (TYPE_PRECISION (TREE_TYPE (value))
441952284Sobrien		   <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
442052284Sobrien	    return initializer_constant_valid_p (TREE_OPERAND (value, 0),
442152284Sobrien						 endtype);
442252284Sobrien	}
442318334Speter
442418334Speter      /* Allow conversions to union types if the value inside is okay.  */
442518334Speter      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
442618334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
442718334Speter					     endtype);
442818334Speter      return 0;
442918334Speter
443018334Speter    case PLUS_EXPR:
443118334Speter      if (TREE_CODE (endtype) == INTEGER_TYPE
443218334Speter	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
443318334Speter	return 0;
443418334Speter      {
443518334Speter	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
443618334Speter						    endtype);
443718334Speter	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
443818334Speter						    endtype);
443918334Speter	/* If either term is absolute, use the other terms relocation.  */
444018334Speter	if (valid0 == null_pointer_node)
444118334Speter	  return valid1;
444218334Speter	if (valid1 == null_pointer_node)
444318334Speter	  return valid0;
444418334Speter	return 0;
444518334Speter      }
444618334Speter
444718334Speter    case MINUS_EXPR:
444818334Speter      if (TREE_CODE (endtype) == INTEGER_TYPE
444918334Speter	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
445018334Speter	return 0;
445118334Speter      {
445218334Speter	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
445318334Speter						    endtype);
445418334Speter	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
445518334Speter						    endtype);
445618334Speter	/* Win if second argument is absolute.  */
445718334Speter	if (valid1 == null_pointer_node)
445818334Speter	  return valid0;
445918334Speter	/* Win if both arguments have the same relocation.
446018334Speter	   Then the value is absolute.  */
446118334Speter	if (valid0 == valid1)
446218334Speter	  return null_pointer_node;
446318334Speter	return 0;
446418334Speter      }
446550397Sobrien
446650397Sobrien    default:
446750397Sobrien      return 0;
446818334Speter    }
446918334Speter}
447018334Speter
447118334Speter/* If VALUE is a compound expr all of whose expressions are constant, then
447218334Speter   return its value.  Otherwise, return error_mark_node.
447318334Speter
447418334Speter   This is for handling COMPOUND_EXPRs as initializer elements
447518334Speter   which is allowed with a warning when -pedantic is specified.  */
447618334Speter
447718334Speterstatic tree
447818334Spetervalid_compound_expr_initializer (value, endtype)
447918334Speter     tree value;
448018334Speter     tree endtype;
448118334Speter{
448218334Speter  if (TREE_CODE (value) == COMPOUND_EXPR)
448318334Speter    {
448418334Speter      if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype)
448518334Speter	  == error_mark_node)
448618334Speter	return error_mark_node;
448718334Speter      return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
448818334Speter					      endtype);
448918334Speter    }
449018334Speter  else if (! TREE_CONSTANT (value)
449118334Speter	   && ! initializer_constant_valid_p (value, endtype))
449218334Speter    return error_mark_node;
449318334Speter  else
449418334Speter    return value;
449518334Speter}
449618334Speter
449718334Speter/* Perform appropriate conversions on the initial value of a variable,
449818334Speter   store it in the declaration DECL,
449918334Speter   and print any error messages that are appropriate.
450018334Speter   If the init is invalid, store an ERROR_MARK.  */
450118334Speter
450218334Spetervoid
450318334Speterstore_init_value (decl, init)
450418334Speter     tree decl, init;
450518334Speter{
450618334Speter  register tree value, type;
450718334Speter
450818334Speter  /* If variable's type was invalidly declared, just ignore it.  */
450918334Speter
451018334Speter  type = TREE_TYPE (decl);
451118334Speter  if (TREE_CODE (type) == ERROR_MARK)
451218334Speter    return;
451318334Speter
451418334Speter  /* Digest the specified initializer into an expression.  */
451518334Speter
451618334Speter  value = digest_init (type, init, TREE_STATIC (decl),
451718334Speter		       TREE_STATIC (decl) || pedantic);
451818334Speter
451918334Speter  /* Store the expression if valid; else report error.  */
452018334Speter
452118334Speter#if 0
452218334Speter  /* Note that this is the only place we can detect the error
452318334Speter     in a case such as   struct foo bar = (struct foo) { x, y };
452418334Speter     where there is one initial value which is a constructor expression.  */
452518334Speter  if (value == error_mark_node)
452618334Speter    ;
452718334Speter  else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value))
452818334Speter    {
452918334Speter      error ("initializer for static variable is not constant");
453018334Speter      value = error_mark_node;
453118334Speter    }
453218334Speter  else if (TREE_STATIC (decl)
453318334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
453418334Speter    {
453518334Speter      error ("initializer for static variable uses complicated arithmetic");
453618334Speter      value = error_mark_node;
453718334Speter    }
453818334Speter  else
453918334Speter    {
454018334Speter      if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
454118334Speter	{
454218334Speter	  if (! TREE_CONSTANT (value))
454318334Speter	    pedwarn ("aggregate initializer is not constant");
454418334Speter	  else if (! TREE_STATIC (value))
454518334Speter	    pedwarn ("aggregate initializer uses complicated arithmetic");
454618334Speter	}
454718334Speter    }
454818334Speter#endif
454918334Speter
455018334Speter  DECL_INITIAL (decl) = value;
455118334Speter
455218334Speter  /* ANSI wants warnings about out-of-range constant initializers.  */
455318334Speter  STRIP_TYPE_NOPS (value);
455418334Speter  constant_expression_warning (value);
455518334Speter}
455618334Speter
455718334Speter/* Methods for storing and printing names for error messages.  */
455818334Speter
455918334Speter/* Implement a spelling stack that allows components of a name to be pushed
456018334Speter   and popped.  Each element on the stack is this structure.  */
456118334Speter
456218334Speterstruct spelling
456318334Speter{
456418334Speter  int kind;
456518334Speter  union
456618334Speter    {
456718334Speter      int i;
456852284Sobrien      const char *s;
456918334Speter    } u;
457018334Speter};
457118334Speter
457218334Speter#define SPELLING_STRING 1
457318334Speter#define SPELLING_MEMBER 2
457418334Speter#define SPELLING_BOUNDS 3
457518334Speter
457618334Speterstatic struct spelling *spelling;	/* Next stack element (unused).  */
457718334Speterstatic struct spelling *spelling_base;	/* Spelling stack base.  */
457818334Speterstatic int spelling_size;		/* Size of the spelling stack.  */
457918334Speter
458018334Speter/* Macros to save and restore the spelling stack around push_... functions.
458118334Speter   Alternative to SAVE_SPELLING_STACK.  */
458218334Speter
458318334Speter#define SPELLING_DEPTH() (spelling - spelling_base)
458418334Speter#define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth)
458518334Speter
458618334Speter/* Save and restore the spelling stack around arbitrary C code.  */
458718334Speter
458818334Speter#define SAVE_SPELLING_DEPTH(code)		\
458918334Speter{						\
459018334Speter  int __depth = SPELLING_DEPTH ();		\
459118334Speter  code;						\
459218334Speter  RESTORE_SPELLING_DEPTH (__depth);		\
459318334Speter}
459418334Speter
459518334Speter/* Push an element on the spelling stack with type KIND and assign VALUE
459618334Speter   to MEMBER.  */
459718334Speter
459818334Speter#define PUSH_SPELLING(KIND, VALUE, MEMBER)				\
459918334Speter{									\
460018334Speter  int depth = SPELLING_DEPTH ();					\
460118334Speter									\
460218334Speter  if (depth >= spelling_size)						\
460318334Speter    {									\
460418334Speter      spelling_size += 10;						\
460518334Speter      if (spelling_base == 0)						\
460618334Speter	spelling_base							\
460718334Speter	  = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling));	\
460818334Speter      else								\
460918334Speter        spelling_base							\
461018334Speter	  = (struct spelling *) xrealloc (spelling_base,		\
461118334Speter					  spelling_size * sizeof (struct spelling));	\
461218334Speter      RESTORE_SPELLING_DEPTH (depth);					\
461318334Speter    }									\
461418334Speter									\
461518334Speter  spelling->kind = (KIND);						\
461618334Speter  spelling->MEMBER = (VALUE);						\
461718334Speter  spelling++;								\
461818334Speter}
461918334Speter
462018334Speter/* Push STRING on the stack.  Printed literally.  */
462118334Speter
462218334Speterstatic void
462318334Speterpush_string (string)
462452284Sobrien     const char *string;
462518334Speter{
462618334Speter  PUSH_SPELLING (SPELLING_STRING, string, u.s);
462718334Speter}
462818334Speter
462918334Speter/* Push a member name on the stack.  Printed as '.' STRING.  */
463018334Speter
463118334Speterstatic void
463218334Speterpush_member_name (decl)
463318334Speter     tree decl;
463418334Speter
463518334Speter{
463652284Sobrien  const char *string
463718334Speter    = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
463818334Speter  PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
463918334Speter}
464018334Speter
464118334Speter/* Push an array bounds on the stack.  Printed as [BOUNDS].  */
464218334Speter
464318334Speterstatic void
464418334Speterpush_array_bounds (bounds)
464518334Speter     int bounds;
464618334Speter{
464718334Speter  PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
464818334Speter}
464918334Speter
465018334Speter/* Compute the maximum size in bytes of the printed spelling.  */
465118334Speter
465218334Speterstatic int
465318334Speterspelling_length ()
465418334Speter{
465518334Speter  register int size = 0;
465618334Speter  register struct spelling *p;
465718334Speter
465818334Speter  for (p = spelling_base; p < spelling; p++)
465918334Speter    {
466018334Speter      if (p->kind == SPELLING_BOUNDS)
466118334Speter	size += 25;
466218334Speter      else
466318334Speter	size += strlen (p->u.s) + 1;
466418334Speter    }
466518334Speter
466618334Speter  return size;
466718334Speter}
466818334Speter
466918334Speter/* Print the spelling to BUFFER and return it.  */
467018334Speter
467118334Speterstatic char *
467218334Speterprint_spelling (buffer)
467318334Speter     register char *buffer;
467418334Speter{
467518334Speter  register char *d = buffer;
467618334Speter  register struct spelling *p;
467718334Speter
467818334Speter  for (p = spelling_base; p < spelling; p++)
467918334Speter    if (p->kind == SPELLING_BOUNDS)
468018334Speter      {
468118334Speter	sprintf (d, "[%d]", p->u.i);
468218334Speter	d += strlen (d);
468318334Speter      }
468418334Speter    else
468518334Speter      {
468652284Sobrien	register const char *s;
468718334Speter	if (p->kind == SPELLING_MEMBER)
468818334Speter	  *d++ = '.';
468950397Sobrien	for (s = p->u.s; (*d = *s++); d++)
469018334Speter	  ;
469118334Speter      }
469218334Speter  *d++ = '\0';
469318334Speter  return buffer;
469418334Speter}
469518334Speter
469618334Speter/* Issue an error message for a bad initializer component.
469752284Sobrien   MSGID identifies the message.
469852284Sobrien   The component name is taken from the spelling stack.  */
469918334Speter
470018334Spetervoid
470152284Sobrienerror_init (msgid)
470252284Sobrien     const char *msgid;
470318334Speter{
470452284Sobrien  char *ofwhat;
470518334Speter
470652284Sobrien  error (msgid);
470752284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
470818334Speter  if (*ofwhat)
470952284Sobrien    error ("(near initialization for `%s')", ofwhat);
471018334Speter}
471118334Speter
471218334Speter/* Issue a pedantic warning for a bad initializer component.
471352284Sobrien   MSGID identifies the message.
471452284Sobrien   The component name is taken from the spelling stack.  */
471518334Speter
471618334Spetervoid
471752284Sobrienpedwarn_init (msgid)
471852284Sobrien     const char *msgid;
471918334Speter{
472052284Sobrien  char *ofwhat;
472118334Speter
472252284Sobrien  pedwarn (msgid);
472352284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
472418334Speter  if (*ofwhat)
472552284Sobrien    pedwarn ("(near initialization for `%s')", ofwhat);
472618334Speter}
472718334Speter
472818334Speter/* Issue a warning for a bad initializer component.
472952284Sobrien   MSGID identifies the message.
473052284Sobrien   The component name is taken from the spelling stack.  */
473118334Speter
473218334Speterstatic void
473352284Sobrienwarning_init (msgid)
473452284Sobrien     const char *msgid;
473518334Speter{
473652284Sobrien  char *ofwhat;
473718334Speter
473852284Sobrien  warning (msgid);
473952284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
474018334Speter  if (*ofwhat)
474152284Sobrien    warning ("(near initialization for `%s')", ofwhat);
474218334Speter}
474318334Speter
474418334Speter/* Digest the parser output INIT as an initializer for type TYPE.
474518334Speter   Return a C expression of type TYPE to represent the initial value.
474618334Speter
474718334Speter   The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors
474818334Speter   if non-constant initializers or elements are seen.  CONSTRUCTOR_CONSTANT
474918334Speter   applies only to elements of constructors.  */
475018334Speter
475118334Speterstatic tree
475218334Speterdigest_init (type, init, require_constant, constructor_constant)
475318334Speter     tree type, init;
475418334Speter     int require_constant, constructor_constant;
475518334Speter{
475618334Speter  enum tree_code code = TREE_CODE (type);
475718334Speter  tree inside_init = init;
475818334Speter
475918334Speter  if (init == error_mark_node)
476018334Speter    return init;
476118334Speter
476218334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
476318334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
476418334Speter     whose value is 0 to count as a null pointer constant.  */
476518334Speter  if (TREE_CODE (init) == NON_LVALUE_EXPR)
476618334Speter    inside_init = TREE_OPERAND (init, 0);
476718334Speter
476818334Speter  /* Initialization of an array of chars from a string constant
476918334Speter     optionally enclosed in braces.  */
477018334Speter
477118334Speter  if (code == ARRAY_TYPE)
477218334Speter    {
477318334Speter      tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
477418334Speter      if ((typ1 == char_type_node
477518334Speter	   || typ1 == signed_char_type_node
477618334Speter	   || typ1 == unsigned_char_type_node
477718334Speter	   || typ1 == unsigned_wchar_type_node
477818334Speter	   || typ1 == signed_wchar_type_node)
477918334Speter	  && ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
478018334Speter	{
478118334Speter	  if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
478218334Speter			 TYPE_MAIN_VARIANT (type)))
478318334Speter	    return inside_init;
478418334Speter
478518334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
478618334Speter	       != char_type_node)
478718334Speter	      && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
478818334Speter	    {
478952284Sobrien	      error_init ("char-array initialized from wide string");
479018334Speter	      return error_mark_node;
479118334Speter	    }
479218334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
479318334Speter	       == char_type_node)
479418334Speter	      && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
479518334Speter	    {
479652284Sobrien	      error_init ("int-array initialized from non-wide string");
479718334Speter	      return error_mark_node;
479818334Speter	    }
479918334Speter
480018334Speter	  TREE_TYPE (inside_init) = type;
480118334Speter	  if (TYPE_DOMAIN (type) != 0
480218334Speter	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
480318334Speter	    {
480418334Speter	      register int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
480518334Speter	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
480618334Speter	      /* Subtract 1 (or sizeof (wchar_t))
480718334Speter		 because it's ok to ignore the terminating null char
480818334Speter		 that is counted in the length of the constant.  */
480918334Speter	      if (size < TREE_STRING_LENGTH (inside_init)
481018334Speter		  - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)
481118334Speter		     ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT
481218334Speter		     : 1))
481352284Sobrien		pedwarn_init ("initializer-string for array of chars is too long");
481418334Speter	    }
481518334Speter	  return inside_init;
481618334Speter	}
481718334Speter    }
481818334Speter
481918334Speter  /* Any type can be initialized
482018334Speter     from an expression of the same type, optionally with braces.  */
482118334Speter
482218334Speter  if (inside_init && TREE_TYPE (inside_init) != 0
482318334Speter      && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
482418334Speter		     TYPE_MAIN_VARIANT (type))
482518334Speter	  || (code == ARRAY_TYPE
482618334Speter	      && comptypes (TREE_TYPE (inside_init), type))
482718334Speter	  || (code == POINTER_TYPE
482818334Speter	      && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
482918334Speter		  || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
483018334Speter	      && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
483118334Speter			    TREE_TYPE (type)))))
483218334Speter    {
483318334Speter      if (code == POINTER_TYPE
483418334Speter	  && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
483518334Speter	      || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE))
483618334Speter	inside_init = default_conversion (inside_init);
483718334Speter      else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
483818334Speter	       && TREE_CODE (inside_init) != CONSTRUCTOR)
483918334Speter	{
484052284Sobrien	  error_init ("array initialized from non-constant array expression");
484118334Speter	  return error_mark_node;
484218334Speter	}
484318334Speter
484418334Speter      if (optimize && TREE_CODE (inside_init) == VAR_DECL)
484518334Speter	inside_init = decl_constant_value (inside_init);
484618334Speter
484718334Speter      /* Compound expressions can only occur here if -pedantic or
484818334Speter	 -pedantic-errors is specified.  In the later case, we always want
484918334Speter	 an error.  In the former case, we simply want a warning.  */
485018334Speter      if (require_constant && pedantic
485118334Speter	  && TREE_CODE (inside_init) == COMPOUND_EXPR)
485218334Speter	{
485318334Speter	  inside_init
485418334Speter	    = valid_compound_expr_initializer (inside_init,
485518334Speter					       TREE_TYPE (inside_init));
485618334Speter	  if (inside_init == error_mark_node)
485752284Sobrien	    error_init ("initializer element is not constant");
485818334Speter	  else
485952284Sobrien	    pedwarn_init ("initializer element is not constant");
486018334Speter	  if (flag_pedantic_errors)
486118334Speter	    inside_init = error_mark_node;
486218334Speter	}
486318334Speter      else if (require_constant && ! TREE_CONSTANT (inside_init))
486418334Speter	{
486552284Sobrien	  error_init ("initializer element is not constant");
486618334Speter	  inside_init = error_mark_node;
486718334Speter	}
486818334Speter      else if (require_constant
486918334Speter	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
487018334Speter	{
487152284Sobrien	  error_init ("initializer element is not computable at load time");
487218334Speter	  inside_init = error_mark_node;
487318334Speter	}
487418334Speter
487518334Speter      return inside_init;
487618334Speter    }
487718334Speter
487818334Speter  /* Handle scalar types, including conversions.  */
487918334Speter
488018334Speter  if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
488118334Speter      || code == ENUMERAL_TYPE || code == COMPLEX_TYPE)
488218334Speter    {
488318334Speter      /* Note that convert_for_assignment calls default_conversion
488418334Speter	 for arrays and functions.  We must not call it in the
488518334Speter	 case where inside_init is a null pointer constant.  */
488618334Speter      inside_init
488752284Sobrien	= convert_for_assignment (type, init, _("initialization"),
488818334Speter				  NULL_TREE, NULL_TREE, 0);
488918334Speter
489018334Speter      if (require_constant && ! TREE_CONSTANT (inside_init))
489118334Speter	{
489252284Sobrien	  error_init ("initializer element is not constant");
489318334Speter	  inside_init = error_mark_node;
489418334Speter	}
489518334Speter      else if (require_constant
489618334Speter	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
489718334Speter	{
489852284Sobrien	  error_init ("initializer element is not computable at load time");
489918334Speter	  inside_init = error_mark_node;
490018334Speter	}
490118334Speter
490218334Speter      return inside_init;
490318334Speter    }
490418334Speter
490518334Speter  /* Come here only for records and arrays.  */
490618334Speter
490718334Speter  if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
490818334Speter    {
490952284Sobrien      error_init ("variable-sized object may not be initialized");
491018334Speter      return error_mark_node;
491118334Speter    }
491218334Speter
491318334Speter  /* Traditionally, you can write  struct foo x = 0;
491418334Speter     and it initializes the first element of x to 0.  */
491518334Speter  if (flag_traditional)
491618334Speter    {
491718334Speter      tree top = 0, prev = 0, otype = type;
491818334Speter      while (TREE_CODE (type) == RECORD_TYPE
491918334Speter	     || TREE_CODE (type) == ARRAY_TYPE
492018334Speter	     || TREE_CODE (type) == QUAL_UNION_TYPE
492118334Speter	     || TREE_CODE (type) == UNION_TYPE)
492218334Speter	{
492318334Speter	  tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
492418334Speter	  if (prev == 0)
492518334Speter	    top = temp;
492618334Speter	  else
492718334Speter	    TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp);
492818334Speter	  prev = temp;
492918334Speter	  if (TREE_CODE (type) == ARRAY_TYPE)
493018334Speter	    type = TREE_TYPE (type);
493118334Speter	  else if (TYPE_FIELDS (type))
493218334Speter	    type = TREE_TYPE (TYPE_FIELDS (type));
493318334Speter	  else
493418334Speter	    {
493552284Sobrien	      error_init ("invalid initializer");
493618334Speter	      return error_mark_node;
493718334Speter	    }
493818334Speter	}
493918334Speter
494018334Speter      if (otype != type)
494118334Speter	{
494218334Speter	  TREE_OPERAND (prev, 1)
494318334Speter	    = build_tree_list (NULL_TREE,
494418334Speter			       digest_init (type, init, require_constant,
494518334Speter					    constructor_constant));
494618334Speter	  return top;
494718334Speter	}
494818334Speter      else
494918334Speter	return error_mark_node;
495018334Speter    }
495152284Sobrien  error_init ("invalid initializer");
495218334Speter  return error_mark_node;
495318334Speter}
495418334Speter
495518334Speter/* Handle initializers that use braces.  */
495618334Speter
495718334Speter/* Type of object we are accumulating a constructor for.
495818334Speter   This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE.  */
495918334Speterstatic tree constructor_type;
496018334Speter
496118334Speter/* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields
496218334Speter   left to fill.  */
496318334Speterstatic tree constructor_fields;
496418334Speter
496518334Speter/* For an ARRAY_TYPE, this is the specified index
496618334Speter   at which to store the next element we get.
496718334Speter   This is a special INTEGER_CST node that we modify in place.  */
496818334Speterstatic tree constructor_index;
496918334Speter
497018334Speter/* For an ARRAY_TYPE, this is the end index of the range
497118334Speter   to initialize with the next element, or NULL in the ordinary case
497218334Speter   where the element is used just once.  */
497318334Speterstatic tree constructor_range_end;
497418334Speter
497518334Speter/* For an ARRAY_TYPE, this is the maximum index.  */
497618334Speterstatic tree constructor_max_index;
497718334Speter
497818334Speter/* For a RECORD_TYPE, this is the first field not yet written out.  */
497918334Speterstatic tree constructor_unfilled_fields;
498018334Speter
498118334Speter/* For an ARRAY_TYPE, this is the index of the first element
498218334Speter   not yet written out.
498318334Speter   This is a special INTEGER_CST node that we modify in place.  */
498418334Speterstatic tree constructor_unfilled_index;
498518334Speter
498618334Speter/* In a RECORD_TYPE, the byte index of the next consecutive field.
498718334Speter   This is so we can generate gaps between fields, when appropriate.
498818334Speter   This is a special INTEGER_CST node that we modify in place.  */
498918334Speterstatic tree constructor_bit_index;
499018334Speter
499118334Speter/* If we are saving up the elements rather than allocating them,
499218334Speter   this is the list of elements so far (in reverse order,
499318334Speter   most recent first).  */
499418334Speterstatic tree constructor_elements;
499518334Speter
499618334Speter/* 1 if so far this constructor's elements are all compile-time constants.  */
499718334Speterstatic int constructor_constant;
499818334Speter
499918334Speter/* 1 if so far this constructor's elements are all valid address constants.  */
500018334Speterstatic int constructor_simple;
500118334Speter
500218334Speter/* 1 if this constructor is erroneous so far.  */
500318334Speterstatic int constructor_erroneous;
500418334Speter
500518334Speter/* 1 if have called defer_addressed_constants.  */
500618334Speterstatic int constructor_subconstants_deferred;
500718334Speter
500850397Sobrien/* Structure for managing pending initializer elements, organized as an
500950397Sobrien   AVL tree.  */
501050397Sobrien
501150397Sobrienstruct init_node
501250397Sobrien{
501350397Sobrien  struct init_node *left, *right;
501450397Sobrien  struct init_node *parent;
501550397Sobrien  int balance;
501650397Sobrien  tree purpose;
501750397Sobrien  tree value;
501850397Sobrien};
501950397Sobrien
502050397Sobrien/* Tree of pending elements at this constructor level.
502118334Speter   These are elements encountered out of order
502218334Speter   which belong at places we haven't reached yet in actually
502318334Speter   writing the output.  */
502450397Sobrienstatic struct init_node *constructor_pending_elts;
502518334Speter
502618334Speter/* The SPELLING_DEPTH of this constructor.  */
502718334Speterstatic int constructor_depth;
502818334Speter
502918334Speter/* 0 if implicitly pushing constructor levels is allowed.  */
503050397Sobrienint constructor_no_implicit = 0; /* 0 for C; 1 for some other languages.  */
503118334Speter
503218334Speterstatic int require_constant_value;
503318334Speterstatic int require_constant_elements;
503418334Speter
503518334Speter/* 1 if it is ok to output this constructor as we read it.
503618334Speter   0 means must accumulate a CONSTRUCTOR expression.  */
503718334Speterstatic int constructor_incremental;
503818334Speter
503918334Speter/* DECL node for which an initializer is being read.
504018334Speter   0 means we are reading a constructor expression
504118334Speter   such as (struct foo) {...}.  */
504218334Speterstatic tree constructor_decl;
504318334Speter
504418334Speter/* start_init saves the ASMSPEC arg here for really_start_incremental_init.  */
504518334Speterstatic char *constructor_asmspec;
504618334Speter
504718334Speter/* Nonzero if this is an initializer for a top-level decl.  */
504818334Speterstatic int constructor_top_level;
504918334Speter
505018334Speter
505118334Speter/* This stack has a level for each implicit or explicit level of
505218334Speter   structuring in the initializer, including the outermost one.  It
505318334Speter   saves the values of most of the variables above.  */
505418334Speter
505518334Speterstruct constructor_stack
505618334Speter{
505718334Speter  struct constructor_stack *next;
505818334Speter  tree type;
505918334Speter  tree fields;
506018334Speter  tree index;
506118334Speter  tree range_end;
506218334Speter  tree max_index;
506318334Speter  tree unfilled_index;
506418334Speter  tree unfilled_fields;
506518334Speter  tree bit_index;
506618334Speter  tree elements;
506718334Speter  int offset;
506850397Sobrien  struct init_node *pending_elts;
506918334Speter  int depth;
507018334Speter  /* If nonzero, this value should replace the entire
507118334Speter     constructor at this level.  */
507218334Speter  tree replacement_value;
507318334Speter  char constant;
507418334Speter  char simple;
507518334Speter  char implicit;
507618334Speter  char incremental;
507718334Speter  char erroneous;
507818334Speter  char outer;
507918334Speter};
508018334Speter
508118334Speterstruct constructor_stack *constructor_stack;
508218334Speter
508318334Speter/* This stack records separate initializers that are nested.
508418334Speter   Nested initializers can't happen in ANSI C, but GNU C allows them
508518334Speter   in cases like { ... (struct foo) { ... } ... }.  */
508618334Speter
508718334Speterstruct initializer_stack
508818334Speter{
508918334Speter  struct initializer_stack *next;
509018334Speter  tree decl;
509118334Speter  char *asmspec;
509218334Speter  struct constructor_stack *constructor_stack;
509318334Speter  tree elements;
509418334Speter  struct spelling *spelling;
509518334Speter  struct spelling *spelling_base;
509618334Speter  int spelling_size;
509718334Speter  char top_level;
509818334Speter  char incremental;
509918334Speter  char require_constant_value;
510018334Speter  char require_constant_elements;
510118334Speter  char deferred;
510218334Speter};
510318334Speter
510418334Speterstruct initializer_stack *initializer_stack;
510518334Speter
510618334Speter/* Prepare to parse and output the initializer for variable DECL.  */
510718334Speter
510818334Spetervoid
510918334Speterstart_init (decl, asmspec_tree, top_level)
511018334Speter     tree decl;
511118334Speter     tree asmspec_tree;
511218334Speter     int top_level;
511318334Speter{
511452284Sobrien  const char *locus;
511518334Speter  struct initializer_stack *p
511618334Speter    = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
511718334Speter  char *asmspec = 0;
511818334Speter
511918334Speter  if (asmspec_tree)
512018334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
512118334Speter
512218334Speter  p->decl = constructor_decl;
512318334Speter  p->asmspec = constructor_asmspec;
512418334Speter  p->incremental = constructor_incremental;
512518334Speter  p->require_constant_value = require_constant_value;
512618334Speter  p->require_constant_elements = require_constant_elements;
512718334Speter  p->constructor_stack = constructor_stack;
512818334Speter  p->elements = constructor_elements;
512918334Speter  p->spelling = spelling;
513018334Speter  p->spelling_base = spelling_base;
513118334Speter  p->spelling_size = spelling_size;
513218334Speter  p->deferred = constructor_subconstants_deferred;
513318334Speter  p->top_level = constructor_top_level;
513418334Speter  p->next = initializer_stack;
513518334Speter  initializer_stack = p;
513618334Speter
513718334Speter  constructor_decl = decl;
513818334Speter  constructor_incremental = top_level;
513918334Speter  constructor_asmspec = asmspec;
514018334Speter  constructor_subconstants_deferred = 0;
514118334Speter  constructor_top_level = top_level;
514218334Speter
514318334Speter  if (decl != 0)
514418334Speter    {
514518334Speter      require_constant_value = TREE_STATIC (decl);
514618334Speter      require_constant_elements
514718334Speter	= ((TREE_STATIC (decl) || pedantic)
514818334Speter	   /* For a scalar, you can always use any value to initialize,
514918334Speter	      even within braces.  */
515018334Speter	   && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
515118334Speter	       || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
515218334Speter	       || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
515318334Speter	       || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
515418334Speter      locus = IDENTIFIER_POINTER (DECL_NAME (decl));
515518334Speter      constructor_incremental |= TREE_STATIC (decl);
515618334Speter    }
515718334Speter  else
515818334Speter    {
515918334Speter      require_constant_value = 0;
516018334Speter      require_constant_elements = 0;
516118334Speter      locus = "(anonymous)";
516218334Speter    }
516318334Speter
516418334Speter  constructor_stack = 0;
516518334Speter
516618334Speter  missing_braces_mentioned = 0;
516718334Speter
516818334Speter  spelling_base = 0;
516918334Speter  spelling_size = 0;
517018334Speter  RESTORE_SPELLING_DEPTH (0);
517118334Speter
517218334Speter  if (locus)
517318334Speter    push_string (locus);
517418334Speter}
517518334Speter
517618334Spetervoid
517718334Speterfinish_init ()
517818334Speter{
517918334Speter  struct initializer_stack *p = initializer_stack;
518018334Speter
518118334Speter  /* Output subconstants (string constants, usually)
518218334Speter     that were referenced within this initializer and saved up.
518318334Speter     Must do this if and only if we called defer_addressed_constants.  */
518418334Speter  if (constructor_subconstants_deferred)
518518334Speter    output_deferred_addressed_constants ();
518618334Speter
518718334Speter  /* Free the whole constructor stack of this initializer.  */
518818334Speter  while (constructor_stack)
518918334Speter    {
519018334Speter      struct constructor_stack *q = constructor_stack;
519118334Speter      constructor_stack = q->next;
519218334Speter      free (q);
519318334Speter    }
519418334Speter
519518334Speter  /* Pop back to the data of the outer initializer (if any).  */
519618334Speter  constructor_decl = p->decl;
519718334Speter  constructor_asmspec = p->asmspec;
519818334Speter  constructor_incremental = p->incremental;
519918334Speter  require_constant_value = p->require_constant_value;
520018334Speter  require_constant_elements = p->require_constant_elements;
520118334Speter  constructor_stack = p->constructor_stack;
520218334Speter  constructor_elements = p->elements;
520318334Speter  spelling = p->spelling;
520418334Speter  spelling_base = p->spelling_base;
520518334Speter  spelling_size = p->spelling_size;
520618334Speter  constructor_subconstants_deferred = p->deferred;
520718334Speter  constructor_top_level = p->top_level;
520818334Speter  initializer_stack = p->next;
520918334Speter  free (p);
521018334Speter}
521118334Speter
521218334Speter/* Call here when we see the initializer is surrounded by braces.
521318334Speter   This is instead of a call to push_init_level;
521418334Speter   it is matched by a call to pop_init_level.
521518334Speter
521618334Speter   TYPE is the type to initialize, for a constructor expression.
521718334Speter   For an initializer for a decl, TYPE is zero.  */
521818334Speter
521918334Spetervoid
522018334Speterreally_start_incremental_init (type)
522118334Speter     tree type;
522218334Speter{
522318334Speter  struct constructor_stack *p
522418334Speter    = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
522518334Speter
522618334Speter  if (type == 0)
522718334Speter    type = TREE_TYPE (constructor_decl);
522818334Speter
522918334Speter  /* Turn off constructor_incremental if type is a struct with bitfields.
523018334Speter     Do this before the first push, so that the corrected value
523118334Speter     is available in finish_init.  */
523218334Speter  check_init_type_bitfields (type);
523318334Speter
523418334Speter  p->type = constructor_type;
523518334Speter  p->fields = constructor_fields;
523618334Speter  p->index = constructor_index;
523718334Speter  p->range_end = constructor_range_end;
523818334Speter  p->max_index = constructor_max_index;
523918334Speter  p->unfilled_index = constructor_unfilled_index;
524018334Speter  p->unfilled_fields = constructor_unfilled_fields;
524118334Speter  p->bit_index = constructor_bit_index;
524218334Speter  p->elements = constructor_elements;
524318334Speter  p->constant = constructor_constant;
524418334Speter  p->simple = constructor_simple;
524518334Speter  p->erroneous = constructor_erroneous;
524618334Speter  p->pending_elts = constructor_pending_elts;
524718334Speter  p->depth = constructor_depth;
524818334Speter  p->replacement_value = 0;
524918334Speter  p->implicit = 0;
525018334Speter  p->incremental = constructor_incremental;
525118334Speter  p->outer = 0;
525218334Speter  p->next = 0;
525318334Speter  constructor_stack = p;
525418334Speter
525518334Speter  constructor_constant = 1;
525618334Speter  constructor_simple = 1;
525718334Speter  constructor_depth = SPELLING_DEPTH ();
525818334Speter  constructor_elements = 0;
525918334Speter  constructor_pending_elts = 0;
526018334Speter  constructor_type = type;
526118334Speter
526218334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
526318334Speter      || TREE_CODE (constructor_type) == UNION_TYPE)
526418334Speter    {
526518334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
526618334Speter      /* Skip any nameless bit fields at the beginning.  */
526750397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
526818334Speter	     && DECL_NAME (constructor_fields) == 0)
526918334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
527018334Speter      constructor_unfilled_fields = constructor_fields;
527118334Speter      constructor_bit_index = copy_node (integer_zero_node);
527250397Sobrien      TREE_TYPE (constructor_bit_index) = sbitsizetype;
527318334Speter    }
527418334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
527518334Speter    {
527618334Speter      constructor_range_end = 0;
527718334Speter      if (TYPE_DOMAIN (constructor_type))
527818334Speter	{
527918334Speter	  constructor_max_index
528018334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
528118334Speter	  constructor_index
528218334Speter	    = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
528318334Speter	}
528418334Speter      else
528518334Speter	constructor_index = copy_node (integer_zero_node);
528618334Speter      constructor_unfilled_index = copy_node (constructor_index);
528718334Speter    }
528818334Speter  else
528918334Speter    {
529018334Speter      /* Handle the case of int x = {5}; */
529118334Speter      constructor_fields = constructor_type;
529218334Speter      constructor_unfilled_fields = constructor_type;
529318334Speter    }
529418334Speter
529518334Speter  if (constructor_incremental)
529618334Speter    {
529718334Speter      int momentary = suspend_momentary ();
529818334Speter      push_obstacks_nochange ();
529918334Speter      if (TREE_PERMANENT (constructor_decl))
530018334Speter	end_temporary_allocation ();
530118334Speter      make_decl_rtl (constructor_decl, constructor_asmspec,
530218334Speter		     constructor_top_level);
530318334Speter      assemble_variable (constructor_decl, constructor_top_level, 0, 1);
530418334Speter      pop_obstacks ();
530518334Speter      resume_momentary (momentary);
530618334Speter    }
530718334Speter
530818334Speter  if (constructor_incremental)
530918334Speter    {
531018334Speter      defer_addressed_constants ();
531118334Speter      constructor_subconstants_deferred = 1;
531218334Speter    }
531318334Speter}
531418334Speter
531518334Speter/* Push down into a subobject, for initialization.
531618334Speter   If this is for an explicit set of braces, IMPLICIT is 0.
531718334Speter   If it is because the next element belongs at a lower level,
531818334Speter   IMPLICIT is 1.  */
531918334Speter
532018334Spetervoid
532118334Speterpush_init_level (implicit)
532218334Speter     int implicit;
532318334Speter{
532418334Speter  struct constructor_stack *p;
532518334Speter
532618334Speter  /* If we've exhausted any levels that didn't have braces,
532718334Speter     pop them now.  */
532818334Speter  while (constructor_stack->implicit)
532918334Speter    {
533018334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
533118334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
533218334Speter	  && constructor_fields == 0)
533318334Speter	process_init_element (pop_init_level (1));
533418334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
533518334Speter	       && tree_int_cst_lt (constructor_max_index, constructor_index))
533618334Speter	process_init_element (pop_init_level (1));
533718334Speter      else
533818334Speter	break;
533918334Speter    }
534018334Speter
534150397Sobrien  /* Structure elements may require alignment.  Do this now if necessary
534250397Sobrien     for the subaggregate, and if it comes next in sequence.  Don't do
534350397Sobrien     this for subaggregates that will go on the pending list.  */
534418334Speter  if (constructor_incremental && constructor_type != 0
534550397Sobrien      && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields
534650397Sobrien      && constructor_fields == constructor_unfilled_fields)
534718334Speter    {
534818334Speter      /* Advance to offset of this element.  */
534918334Speter      if (! tree_int_cst_equal (constructor_bit_index,
535018334Speter				DECL_FIELD_BITPOS (constructor_fields)))
535118334Speter	{
535250397Sobrien	  /* By using unsigned arithmetic, the result will be correct even
535350397Sobrien	     in case of overflows, if BITS_PER_UNIT is a power of two.  */
535450397Sobrien	  unsigned next = (TREE_INT_CST_LOW
535550397Sobrien			   (DECL_FIELD_BITPOS (constructor_fields))
535650397Sobrien			   / (unsigned)BITS_PER_UNIT);
535750397Sobrien	  unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
535850397Sobrien			   / (unsigned)BITS_PER_UNIT);
535918334Speter
536050397Sobrien	  assemble_zeros ((next - here)
536150397Sobrien			  * (unsigned)BITS_PER_UNIT
536250397Sobrien			  / (unsigned)BITS_PER_UNIT);
536318334Speter	}
536450397Sobrien      /* Indicate that we have now filled the structure up to the current
536550397Sobrien	 field.  */
536650397Sobrien      constructor_unfilled_fields = constructor_fields;
536718334Speter    }
536818334Speter
536918334Speter  p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
537018334Speter  p->type = constructor_type;
537118334Speter  p->fields = constructor_fields;
537218334Speter  p->index = constructor_index;
537318334Speter  p->range_end = constructor_range_end;
537418334Speter  p->max_index = constructor_max_index;
537518334Speter  p->unfilled_index = constructor_unfilled_index;
537618334Speter  p->unfilled_fields = constructor_unfilled_fields;
537718334Speter  p->bit_index = constructor_bit_index;
537818334Speter  p->elements = constructor_elements;
537918334Speter  p->constant = constructor_constant;
538018334Speter  p->simple = constructor_simple;
538118334Speter  p->erroneous = constructor_erroneous;
538218334Speter  p->pending_elts = constructor_pending_elts;
538318334Speter  p->depth = constructor_depth;
538418334Speter  p->replacement_value = 0;
538518334Speter  p->implicit = implicit;
538618334Speter  p->incremental = constructor_incremental;
538718334Speter  p->outer = 0;
538818334Speter  p->next = constructor_stack;
538918334Speter  constructor_stack = p;
539018334Speter
539118334Speter  constructor_constant = 1;
539218334Speter  constructor_simple = 1;
539318334Speter  constructor_depth = SPELLING_DEPTH ();
539418334Speter  constructor_elements = 0;
539518334Speter  constructor_pending_elts = 0;
539618334Speter
539718334Speter  /* Don't die if an entire brace-pair level is superfluous
539818334Speter     in the containing level.  */
539918334Speter  if (constructor_type == 0)
540018334Speter    ;
540118334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
540218334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
540318334Speter    {
540418334Speter      /* Don't die if there are extra init elts at the end.  */
540518334Speter      if (constructor_fields == 0)
540618334Speter	constructor_type = 0;
540718334Speter      else
540818334Speter	{
540918334Speter	  constructor_type = TREE_TYPE (constructor_fields);
541018334Speter	  push_member_name (constructor_fields);
541118334Speter	  constructor_depth++;
541218334Speter	  if (constructor_fields != constructor_unfilled_fields)
541318334Speter	    constructor_incremental = 0;
541418334Speter	}
541518334Speter    }
541618334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
541718334Speter    {
541818334Speter      constructor_type = TREE_TYPE (constructor_type);
541918334Speter      push_array_bounds (TREE_INT_CST_LOW (constructor_index));
542018334Speter      constructor_depth++;
542118334Speter      if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index)
542218334Speter	  || constructor_range_end != 0)
542318334Speter	constructor_incremental = 0;
542418334Speter    }
542518334Speter
542618334Speter  if (constructor_type == 0)
542718334Speter    {
542852284Sobrien      error_init ("extra brace group at end of initializer");
542918334Speter      constructor_fields = 0;
543018334Speter      constructor_unfilled_fields = 0;
543118334Speter      return;
543218334Speter    }
543318334Speter
543418334Speter  /* Turn off constructor_incremental if type is a struct with bitfields.  */
543518334Speter  check_init_type_bitfields (constructor_type);
543618334Speter
543718334Speter  if (implicit && warn_missing_braces && !missing_braces_mentioned)
543818334Speter    {
543918334Speter      missing_braces_mentioned = 1;
544052284Sobrien      warning_init ("missing braces around initializer");
544118334Speter    }
544218334Speter
544318334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
544418334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
544518334Speter    {
544618334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
544718334Speter      /* Skip any nameless bit fields at the beginning.  */
544850397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
544918334Speter	     && DECL_NAME (constructor_fields) == 0)
545018334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
545118334Speter      constructor_unfilled_fields = constructor_fields;
545218334Speter      constructor_bit_index = copy_node (integer_zero_node);
545350397Sobrien      TREE_TYPE (constructor_bit_index) = sbitsizetype;
545418334Speter    }
545518334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
545618334Speter    {
545718334Speter      constructor_range_end = 0;
545818334Speter      if (TYPE_DOMAIN (constructor_type))
545918334Speter	{
546018334Speter	  constructor_max_index
546118334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
546218334Speter	  constructor_index
546318334Speter	    = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
546418334Speter	}
546518334Speter      else
546618334Speter	constructor_index = copy_node (integer_zero_node);
546718334Speter      constructor_unfilled_index = copy_node (constructor_index);
546818334Speter    }
546918334Speter  else
547018334Speter    {
547152284Sobrien      warning_init ("braces around scalar initializer");
547218334Speter      constructor_fields = constructor_type;
547318334Speter      constructor_unfilled_fields = constructor_type;
547418334Speter    }
547518334Speter}
547618334Speter
547718334Speter/* Don't read a struct incrementally if it has any bitfields,
547818334Speter   because the incremental reading code doesn't know how to
547918334Speter   handle bitfields yet.  */
548018334Speter
548118334Speterstatic void
548218334Spetercheck_init_type_bitfields (type)
548318334Speter     tree type;
548418334Speter{
548518334Speter  if (TREE_CODE (type) == RECORD_TYPE)
548618334Speter    {
548718334Speter      tree tail;
548818334Speter      for (tail = TYPE_FIELDS (type); tail;
548918334Speter	   tail = TREE_CHAIN (tail))
549018334Speter	{
549152284Sobrien	  if (DECL_C_BIT_FIELD (tail))
549218334Speter	    {
549318334Speter	      constructor_incremental = 0;
549418334Speter	      break;
549518334Speter	    }
549618334Speter
549718334Speter	  check_init_type_bitfields (TREE_TYPE (tail));
549818334Speter	}
549918334Speter    }
550018334Speter
550152284Sobrien  else if (TREE_CODE (type) == UNION_TYPE)
550252284Sobrien    {
550352284Sobrien      tree tail = TYPE_FIELDS (type);
550452284Sobrien      if (tail && DECL_C_BIT_FIELD (tail))
550552284Sobrien	/* We also use the nonincremental algorithm for initiliazation
550652284Sobrien	   of unions whose first member is a bitfield, becuase the
550752284Sobrien	   incremental algorithm has no code for dealing with
550852284Sobrien	   bitfields. */
550952284Sobrien	constructor_incremental = 0;
551052284Sobrien    }
551152284Sobrien
551218334Speter  else if (TREE_CODE (type) == ARRAY_TYPE)
551318334Speter    check_init_type_bitfields (TREE_TYPE (type));
551418334Speter}
551518334Speter
551618334Speter/* At the end of an implicit or explicit brace level,
551718334Speter   finish up that level of constructor.
551818334Speter   If we were outputting the elements as they are read, return 0
551918334Speter   from inner levels (process_init_element ignores that),
552018334Speter   but return error_mark_node from the outermost level
552118334Speter   (that's what we want to put in DECL_INITIAL).
552218334Speter   Otherwise, return a CONSTRUCTOR expression.  */
552318334Speter
552418334Spetertree
552518334Speterpop_init_level (implicit)
552618334Speter     int implicit;
552718334Speter{
552818334Speter  struct constructor_stack *p;
552918334Speter  int size = 0;
553018334Speter  tree constructor = 0;
553118334Speter
553218334Speter  if (implicit == 0)
553318334Speter    {
553418334Speter      /* When we come to an explicit close brace,
553518334Speter	 pop any inner levels that didn't have explicit braces.  */
553618334Speter      while (constructor_stack->implicit)
553718334Speter	process_init_element (pop_init_level (1));
553818334Speter    }
553918334Speter
554018334Speter  p = constructor_stack;
554118334Speter
554218334Speter  if (constructor_type != 0)
554318334Speter    size = int_size_in_bytes (constructor_type);
554418334Speter
554550397Sobrien  /* Warn when some struct elements are implicitly initialized to zero.  */
554650397Sobrien  if (extra_warnings
554750397Sobrien      && constructor_type
554850397Sobrien      && TREE_CODE (constructor_type) == RECORD_TYPE
554950397Sobrien      && constructor_unfilled_fields)
555050397Sobrien    {
555150397Sobrien      push_member_name (constructor_unfilled_fields);
555252284Sobrien      warning_init ("missing initializer");
555350397Sobrien      RESTORE_SPELLING_DEPTH (constructor_depth);
555450397Sobrien    }
555550397Sobrien
555618334Speter  /* Now output all pending elements.  */
555718334Speter  output_pending_init_elements (1);
555818334Speter
555918334Speter#if 0 /* c-parse.in warns about {}.  */
556018334Speter  /* In ANSI, each brace level must have at least one element.  */
556118334Speter  if (! implicit && pedantic
556218334Speter      && (TREE_CODE (constructor_type) == ARRAY_TYPE
556318334Speter	  ? integer_zerop (constructor_unfilled_index)
556418334Speter	  : constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
556552284Sobrien    pedwarn_init ("empty braces in initializer");
556618334Speter#endif
556718334Speter
556818334Speter  /* Pad out the end of the structure.  */
556918334Speter
557018334Speter  if (p->replacement_value)
557118334Speter    {
557218334Speter      /* If this closes a superfluous brace pair,
557318334Speter	 just pass out the element between them.  */
557418334Speter      constructor = p->replacement_value;
557518334Speter      /* If this is the top level thing within the initializer,
557618334Speter	 and it's for a variable, then since we already called
557718334Speter	 assemble_variable, we must output the value now.  */
557818334Speter      if (p->next == 0 && constructor_decl != 0
557918334Speter	  && constructor_incremental)
558018334Speter	{
558118334Speter	  constructor = digest_init (constructor_type, constructor,
558218334Speter				     require_constant_value,
558318334Speter				     require_constant_elements);
558418334Speter
558518334Speter	  /* If initializing an array of unknown size,
558618334Speter	     determine the size now.  */
558718334Speter	  if (TREE_CODE (constructor_type) == ARRAY_TYPE
558818334Speter	      && TYPE_DOMAIN (constructor_type) == 0)
558918334Speter	    {
559018334Speter	      int failure;
559118334Speter	      int momentary_p;
559218334Speter
559318334Speter	      push_obstacks_nochange ();
559418334Speter	      if (TREE_PERMANENT (constructor_type))
559518334Speter		end_temporary_allocation ();
559618334Speter
559718334Speter	      momentary_p = suspend_momentary ();
559818334Speter
559918334Speter	      /* We shouldn't have an incomplete array type within
560018334Speter		 some other type.  */
560118334Speter	      if (constructor_stack->next)
560218334Speter		abort ();
560318334Speter
560418334Speter	      failure
560518334Speter		= complete_array_type (constructor_type,
560618334Speter				       constructor, 0);
560718334Speter	      if (failure)
560818334Speter		abort ();
560918334Speter
561018334Speter	      size = int_size_in_bytes (constructor_type);
561118334Speter	      resume_momentary (momentary_p);
561218334Speter	      pop_obstacks ();
561318334Speter	    }
561418334Speter
561518334Speter	  output_constant (constructor, size);
561618334Speter	}
561718334Speter    }
561818334Speter  else if (constructor_type == 0)
561918334Speter    ;
562018334Speter  else if (TREE_CODE (constructor_type) != RECORD_TYPE
562118334Speter	   && TREE_CODE (constructor_type) != UNION_TYPE
562218334Speter	   && TREE_CODE (constructor_type) != ARRAY_TYPE
562318334Speter	   && ! constructor_incremental)
562418334Speter    {
562518334Speter      /* A nonincremental scalar initializer--just return
562618334Speter	 the element, after verifying there is just one.  */
562718334Speter      if (constructor_elements == 0)
562818334Speter	{
562952284Sobrien	  error_init ("empty scalar initializer");
563018334Speter	  constructor = error_mark_node;
563118334Speter	}
563218334Speter      else if (TREE_CHAIN (constructor_elements) != 0)
563318334Speter	{
563452284Sobrien	  error_init ("extra elements in scalar initializer");
563518334Speter	  constructor = TREE_VALUE (constructor_elements);
563618334Speter	}
563718334Speter      else
563818334Speter	constructor = TREE_VALUE (constructor_elements);
563918334Speter    }
564018334Speter  else if (! constructor_incremental)
564118334Speter    {
564218334Speter      if (constructor_erroneous)
564318334Speter	constructor = error_mark_node;
564418334Speter      else
564518334Speter	{
564618334Speter	  int momentary = suspend_momentary ();
564718334Speter
564818334Speter	  constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
564918334Speter			       nreverse (constructor_elements));
565018334Speter	  if (constructor_constant)
565118334Speter	    TREE_CONSTANT (constructor) = 1;
565218334Speter	  if (constructor_constant && constructor_simple)
565318334Speter	    TREE_STATIC (constructor) = 1;
565418334Speter
565518334Speter	  resume_momentary (momentary);
565618334Speter	}
565718334Speter    }
565818334Speter  else
565918334Speter    {
566018334Speter      tree filled;
566118334Speter      int momentary = suspend_momentary ();
566218334Speter
566318334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
566418334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
566518334Speter	{
566618334Speter	  /* Find the offset of the end of that field.  */
566718334Speter	  filled = size_binop (CEIL_DIV_EXPR,
566818334Speter			       constructor_bit_index,
566918334Speter			       size_int (BITS_PER_UNIT));
567018334Speter	}
567118334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
567218334Speter	{
567318334Speter	  /* If initializing an array of unknown size,
567418334Speter	     determine the size now.  */
567518334Speter	  if (TREE_CODE (constructor_type) == ARRAY_TYPE
567618334Speter	      && TYPE_DOMAIN (constructor_type) == 0)
567718334Speter	    {
567818334Speter	      tree maxindex
567918334Speter		= size_binop (MINUS_EXPR,
568018334Speter			      constructor_unfilled_index,
568118334Speter			      integer_one_node);
568218334Speter
568318334Speter	      push_obstacks_nochange ();
568418334Speter	      if (TREE_PERMANENT (constructor_type))
568518334Speter		end_temporary_allocation ();
568618334Speter	      maxindex = copy_node (maxindex);
568718334Speter	      TYPE_DOMAIN (constructor_type) = build_index_type (maxindex);
568818334Speter	      TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type);
568918334Speter
569018334Speter	      /* TYPE_MAX_VALUE is always one less than the number of elements
569118334Speter		 in the array, because we start counting at zero.  Therefore,
569218334Speter		 warn only if the value is less than zero.  */
569318334Speter	      if (pedantic
569418334Speter		  && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
569518334Speter		      < 0))
569618334Speter		error_with_decl (constructor_decl,
569718334Speter				 "zero or negative array size `%s'");
569818334Speter	      layout_type (constructor_type);
569918334Speter	      size = int_size_in_bytes (constructor_type);
570018334Speter	      pop_obstacks ();
570118334Speter	    }
570218334Speter
570318334Speter	  filled = size_binop (MULT_EXPR, constructor_unfilled_index,
570418334Speter			       size_in_bytes (TREE_TYPE (constructor_type)));
570518334Speter	}
570618334Speter      else
570718334Speter	filled = 0;
570818334Speter
570918334Speter      if (filled != 0)
571018334Speter	assemble_zeros (size - TREE_INT_CST_LOW (filled));
571118334Speter
571218334Speter      resume_momentary (momentary);
571318334Speter    }
571418334Speter
571518334Speter
571618334Speter  constructor_type = p->type;
571718334Speter  constructor_fields = p->fields;
571818334Speter  constructor_index = p->index;
571918334Speter  constructor_range_end = p->range_end;
572018334Speter  constructor_max_index = p->max_index;
572118334Speter  constructor_unfilled_index = p->unfilled_index;
572218334Speter  constructor_unfilled_fields = p->unfilled_fields;
572318334Speter  constructor_bit_index = p->bit_index;
572418334Speter  constructor_elements = p->elements;
572518334Speter  constructor_constant = p->constant;
572618334Speter  constructor_simple = p->simple;
572718334Speter  constructor_erroneous = p->erroneous;
572818334Speter  constructor_pending_elts = p->pending_elts;
572918334Speter  constructor_depth = p->depth;
573018334Speter  constructor_incremental = p->incremental;
573118334Speter  RESTORE_SPELLING_DEPTH (constructor_depth);
573218334Speter
573318334Speter  constructor_stack = p->next;
573418334Speter  free (p);
573518334Speter
573618334Speter  if (constructor == 0)
573718334Speter    {
573818334Speter      if (constructor_stack == 0)
573918334Speter	return error_mark_node;
574018334Speter      return NULL_TREE;
574118334Speter    }
574218334Speter  return constructor;
574318334Speter}
574418334Speter
574518334Speter/* Within an array initializer, specify the next index to be initialized.
574618334Speter   FIRST is that index.  If LAST is nonzero, then initialize a range
574718334Speter   of indices, running from FIRST through LAST.  */
574818334Speter
574918334Spetervoid
575018334Speterset_init_index (first, last)
575118334Speter     tree first, last;
575218334Speter{
575318334Speter  while ((TREE_CODE (first) == NOP_EXPR
575418334Speter	  || TREE_CODE (first) == CONVERT_EXPR
575518334Speter	  || TREE_CODE (first) == NON_LVALUE_EXPR)
575618334Speter	 && (TYPE_MODE (TREE_TYPE (first))
575718334Speter	     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0)))))
575818334Speter    (first) = TREE_OPERAND (first, 0);
575918334Speter  if (last)
576018334Speter    while ((TREE_CODE (last) == NOP_EXPR
576118334Speter	    || TREE_CODE (last) == CONVERT_EXPR
576218334Speter	    || TREE_CODE (last) == NON_LVALUE_EXPR)
576318334Speter	   && (TYPE_MODE (TREE_TYPE (last))
576418334Speter	       == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0)))))
576518334Speter      (last) = TREE_OPERAND (last, 0);
576618334Speter
576718334Speter  if (TREE_CODE (first) != INTEGER_CST)
576852284Sobrien    error_init ("nonconstant array index in initializer");
576918334Speter  else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
577052284Sobrien    error_init ("nonconstant array index in initializer");
577118336Speter  else if (! constructor_unfilled_index)
577252284Sobrien    error_init ("array index in non-array initializer");
577318334Speter  else if (tree_int_cst_lt (first, constructor_unfilled_index))
577452284Sobrien    error_init ("duplicate array index in initializer");
577518334Speter  else
577618334Speter    {
577750397Sobrien      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
577850397Sobrien      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
577918334Speter
578018334Speter      if (last != 0 && tree_int_cst_lt (last, first))
578152284Sobrien	error_init ("empty index range in initializer");
578218334Speter      else
578318334Speter	{
578418334Speter	  if (pedantic)
578518334Speter	    pedwarn ("ANSI C forbids specifying element to initialize");
578618334Speter	  constructor_range_end = last;
578718334Speter	}
578818334Speter    }
578918334Speter}
579018334Speter
579118334Speter/* Within a struct initializer, specify the next field to be initialized.  */
579218334Speter
579318334Spetervoid
579418334Speterset_init_label (fieldname)
579518334Speter     tree fieldname;
579618334Speter{
579718334Speter  tree tail;
579818334Speter  int passed = 0;
579918334Speter
580018334Speter  /* Don't die if an entire brace-pair level is superfluous
580118334Speter     in the containing level.  */
580218334Speter  if (constructor_type == 0)
580318334Speter    return;
580418334Speter
580518334Speter  for (tail = TYPE_FIELDS (constructor_type); tail;
580618334Speter       tail = TREE_CHAIN (tail))
580718334Speter    {
580818334Speter      if (tail == constructor_unfilled_fields)
580918334Speter	passed = 1;
581018334Speter      if (DECL_NAME (tail) == fieldname)
581118334Speter	break;
581218334Speter    }
581318334Speter
581418334Speter  if (tail == 0)
581518334Speter    error ("unknown field `%s' specified in initializer",
581618334Speter	   IDENTIFIER_POINTER (fieldname));
581718334Speter  else if (!passed)
581818334Speter    error ("field `%s' already initialized",
581918334Speter	   IDENTIFIER_POINTER (fieldname));
582018334Speter  else
582118334Speter    {
582218334Speter      constructor_fields = tail;
582318334Speter      if (pedantic)
582418334Speter	pedwarn ("ANSI C forbids specifying structure member to initialize");
582518334Speter    }
582618334Speter}
582718334Speter
582850397Sobrien/* Add a new initializer to the tree of pending initializers.  PURPOSE
582950397Sobrien   indentifies the initializer, either array index or field in a structure.
583050397Sobrien   VALUE is the value of that index or field.  */
583150397Sobrien
583250397Sobrienstatic void
583350397Sobrienadd_pending_init (purpose, value)
583450397Sobrien     tree purpose, value;
583550397Sobrien{
583650397Sobrien  struct init_node *p, **q, *r;
583750397Sobrien
583850397Sobrien  q = &constructor_pending_elts;
583950397Sobrien  p = 0;
584050397Sobrien
584150397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
584250397Sobrien    {
584350397Sobrien      while (*q != 0)
584450397Sobrien	{
584550397Sobrien	  p = *q;
584650397Sobrien	  if (tree_int_cst_lt (purpose, p->purpose))
584750397Sobrien	    q = &p->left;
584850397Sobrien	  else if (tree_int_cst_lt (p->purpose, purpose))
584950397Sobrien	    q = &p->right;
585050397Sobrien	  else
585150397Sobrien	    abort ();
585250397Sobrien	}
585350397Sobrien    }
585450397Sobrien  else
585550397Sobrien    {
585650397Sobrien      while (*q != NULL)
585750397Sobrien	{
585850397Sobrien	  p = *q;
585950397Sobrien	  if (tree_int_cst_lt (DECL_FIELD_BITPOS (purpose),
586050397Sobrien			       DECL_FIELD_BITPOS (p->purpose)))
586150397Sobrien	    q = &p->left;
586250397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (p->purpose),
586350397Sobrien				    DECL_FIELD_BITPOS (purpose)))
586450397Sobrien	    q = &p->right;
586550397Sobrien	  else
586650397Sobrien	    abort ();
586750397Sobrien	}
586850397Sobrien    }
586950397Sobrien
587050397Sobrien  r = (struct init_node *) oballoc (sizeof (struct init_node));
587150397Sobrien  r->purpose = purpose;
587250397Sobrien  r->value = value;
587350397Sobrien
587450397Sobrien  *q = r;
587550397Sobrien  r->parent = p;
587650397Sobrien  r->left = 0;
587750397Sobrien  r->right = 0;
587850397Sobrien  r->balance = 0;
587950397Sobrien
588050397Sobrien  while (p)
588150397Sobrien    {
588250397Sobrien      struct init_node *s;
588350397Sobrien
588450397Sobrien      if (r == p->left)
588550397Sobrien	{
588650397Sobrien	  if (p->balance == 0)
588750397Sobrien	    p->balance = -1;
588850397Sobrien	  else if (p->balance < 0)
588950397Sobrien	    {
589050397Sobrien	      if (r->balance < 0)
589150397Sobrien		{
589250397Sobrien		  /* L rotation. */
589350397Sobrien		  p->left = r->right;
589450397Sobrien		  if (p->left)
589550397Sobrien		    p->left->parent = p;
589650397Sobrien		  r->right = p;
589750397Sobrien
589850397Sobrien		  p->balance = 0;
589950397Sobrien		  r->balance = 0;
590050397Sobrien
590150397Sobrien		  s = p->parent;
590250397Sobrien		  p->parent = r;
590350397Sobrien		  r->parent = s;
590450397Sobrien		  if (s)
590550397Sobrien		    {
590650397Sobrien		      if (s->left == p)
590750397Sobrien			s->left = r;
590850397Sobrien		      else
590950397Sobrien			s->right = r;
591050397Sobrien		    }
591150397Sobrien		  else
591250397Sobrien		    constructor_pending_elts = r;
591350397Sobrien		}
591450397Sobrien	      else
591550397Sobrien		{
591650397Sobrien		  /* LR rotation. */
591750397Sobrien		  struct init_node *t = r->right;
591850397Sobrien
591950397Sobrien		  r->right = t->left;
592050397Sobrien		  if (r->right)
592150397Sobrien		    r->right->parent = r;
592250397Sobrien		  t->left = r;
592350397Sobrien
592450397Sobrien		  p->left = t->right;
592550397Sobrien		  if (p->left)
592650397Sobrien		    p->left->parent = p;
592750397Sobrien		  t->right = p;
592850397Sobrien
592950397Sobrien		  p->balance = t->balance < 0;
593050397Sobrien		  r->balance = -(t->balance > 0);
593150397Sobrien		  t->balance = 0;
593250397Sobrien
593350397Sobrien		  s = p->parent;
593450397Sobrien		  p->parent = t;
593550397Sobrien		  r->parent = t;
593650397Sobrien		  t->parent = s;
593750397Sobrien		  if (s)
593850397Sobrien		    {
593950397Sobrien		      if (s->left == p)
594050397Sobrien			s->left = t;
594150397Sobrien		      else
594250397Sobrien			s->right = t;
594350397Sobrien		    }
594450397Sobrien		  else
594550397Sobrien		    constructor_pending_elts = t;
594650397Sobrien		}
594750397Sobrien	      break;
594850397Sobrien	    }
594950397Sobrien	  else
595050397Sobrien	    {
595150397Sobrien	      /* p->balance == +1; growth of left side balances the node.  */
595250397Sobrien	      p->balance = 0;
595350397Sobrien	      break;
595450397Sobrien	    }
595550397Sobrien	}
595650397Sobrien      else /* r == p->right */
595750397Sobrien	{
595850397Sobrien	  if (p->balance == 0)
595950397Sobrien	    /* Growth propagation from right side.  */
596050397Sobrien	    p->balance++;
596150397Sobrien	  else if (p->balance > 0)
596250397Sobrien	    {
596350397Sobrien	      if (r->balance > 0)
596450397Sobrien		{
596550397Sobrien		  /* R rotation. */
596650397Sobrien		  p->right = r->left;
596750397Sobrien		  if (p->right)
596850397Sobrien		    p->right->parent = p;
596950397Sobrien		  r->left = p;
597050397Sobrien
597150397Sobrien		  p->balance = 0;
597250397Sobrien		  r->balance = 0;
597350397Sobrien
597450397Sobrien		  s = p->parent;
597550397Sobrien		  p->parent = r;
597650397Sobrien		  r->parent = s;
597750397Sobrien		  if (s)
597850397Sobrien		    {
597950397Sobrien		      if (s->left == p)
598050397Sobrien			s->left = r;
598150397Sobrien		      else
598250397Sobrien			s->right = r;
598350397Sobrien		    }
598450397Sobrien		  else
598550397Sobrien		    constructor_pending_elts = r;
598650397Sobrien		}
598750397Sobrien	      else /* r->balance == -1 */
598850397Sobrien		{
598950397Sobrien		  /* RL rotation */
599050397Sobrien		  struct init_node *t = r->left;
599150397Sobrien
599250397Sobrien		  r->left = t->right;
599350397Sobrien		  if (r->left)
599450397Sobrien		    r->left->parent = r;
599550397Sobrien		  t->right = r;
599650397Sobrien
599750397Sobrien		  p->right = t->left;
599850397Sobrien		  if (p->right)
599950397Sobrien		    p->right->parent = p;
600050397Sobrien		  t->left = p;
600150397Sobrien
600250397Sobrien		  r->balance = (t->balance < 0);
600350397Sobrien		  p->balance = -(t->balance > 0);
600450397Sobrien		  t->balance = 0;
600550397Sobrien
600650397Sobrien		  s = p->parent;
600750397Sobrien		  p->parent = t;
600850397Sobrien		  r->parent = t;
600950397Sobrien		  t->parent = s;
601050397Sobrien		  if (s)
601150397Sobrien		    {
601250397Sobrien		      if (s->left == p)
601350397Sobrien			s->left = t;
601450397Sobrien		      else
601550397Sobrien			s->right = t;
601650397Sobrien		    }
601750397Sobrien		  else
601850397Sobrien		    constructor_pending_elts = t;
601950397Sobrien		}
602050397Sobrien	      break;
602150397Sobrien	    }
602250397Sobrien	  else
602350397Sobrien	    {
602450397Sobrien	      /* p->balance == -1; growth of right side balances the node. */
602550397Sobrien	      p->balance = 0;
602650397Sobrien	      break;
602750397Sobrien	    }
602850397Sobrien	}
602950397Sobrien
603050397Sobrien      r = p;
603150397Sobrien      p = p->parent;
603250397Sobrien    }
603350397Sobrien}
603450397Sobrien
603550397Sobrien/* Return nonzero if FIELD is equal to the index of a pending initializer.  */
603650397Sobrien
603750397Sobrienstatic int
603850397Sobrienpending_init_member (field)
603950397Sobrien     tree field;
604050397Sobrien{
604150397Sobrien  struct init_node *p;
604250397Sobrien
604350397Sobrien  p = constructor_pending_elts;
604450397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
604550397Sobrien    {
604650397Sobrien      while (p)
604750397Sobrien	{
604850397Sobrien	  if (tree_int_cst_equal (field, p->purpose))
604950397Sobrien	    return 1;
605050397Sobrien	  else if (tree_int_cst_lt (field, p->purpose))
605150397Sobrien	    p = p->left;
605250397Sobrien	  else
605350397Sobrien	    p = p->right;
605450397Sobrien	}
605550397Sobrien    }
605650397Sobrien  else
605750397Sobrien    {
605850397Sobrien      while (p)
605950397Sobrien	{
606050397Sobrien	  if (field == p->purpose)
606150397Sobrien	    return 1;
606250397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (field),
606350397Sobrien				    DECL_FIELD_BITPOS (p->purpose)))
606450397Sobrien	    p = p->left;
606550397Sobrien	  else
606650397Sobrien	    p = p->right;
606750397Sobrien	}
606850397Sobrien    }
606950397Sobrien
607050397Sobrien  return 0;
607150397Sobrien}
607250397Sobrien
607318334Speter/* "Output" the next constructor element.
607418334Speter   At top level, really output it to assembler code now.
607518334Speter   Otherwise, collect it in a list from which we will make a CONSTRUCTOR.
607618334Speter   TYPE is the data type that the containing data type wants here.
607718334Speter   FIELD is the field (a FIELD_DECL) or the index that this element fills.
607818334Speter
607918334Speter   PENDING if non-nil means output pending elements that belong
608018334Speter   right after this element.  (PENDING is normally 1;
608118334Speter   it is 0 while outputting pending elements, to avoid recursion.)  */
608218334Speter
608318334Speterstatic void
608418334Speteroutput_init_element (value, type, field, pending)
608518334Speter     tree value, type, field;
608618334Speter     int pending;
608718334Speter{
608818334Speter  int duplicate = 0;
608918334Speter
609018334Speter  if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
609118334Speter      || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
609218334Speter	  && !(TREE_CODE (value) == STRING_CST
609318334Speter	       && TREE_CODE (type) == ARRAY_TYPE
609418334Speter	       && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
609518334Speter	  && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
609618334Speter			 TYPE_MAIN_VARIANT (type))))
609718334Speter    value = default_conversion (value);
609818334Speter
609918334Speter  if (value == error_mark_node)
610018334Speter    constructor_erroneous = 1;
610118334Speter  else if (!TREE_CONSTANT (value))
610218334Speter    constructor_constant = 0;
610318334Speter  else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0
610418334Speter	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
610518334Speter		|| TREE_CODE (constructor_type) == UNION_TYPE)
610650397Sobrien	       && DECL_C_BIT_FIELD (field)
610750397Sobrien	       && TREE_CODE (value) != INTEGER_CST))
610818334Speter    constructor_simple = 0;
610918334Speter
611018334Speter  if (require_constant_value && ! TREE_CONSTANT (value))
611118334Speter    {
611252284Sobrien      error_init ("initializer element is not constant");
611318334Speter      value = error_mark_node;
611418334Speter    }
611518334Speter  else if (require_constant_elements
611618334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
611718334Speter    {
611852284Sobrien      error_init ("initializer element is not computable at load time");
611918334Speter      value = error_mark_node;
612018334Speter    }
612118334Speter
612218334Speter  /* If this element duplicates one on constructor_pending_elts,
612318334Speter     print a message and ignore it.  Don't do this when we're
612418334Speter     processing elements taken off constructor_pending_elts,
612518334Speter     because we'd always get spurious errors.  */
612618334Speter  if (pending)
612718334Speter    {
612818334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
612950397Sobrien	  || TREE_CODE (constructor_type) == UNION_TYPE
613050397Sobrien	  || TREE_CODE (constructor_type) == ARRAY_TYPE)
613118334Speter	{
613250397Sobrien	  if (pending_init_member (field))
613318334Speter	    {
613452284Sobrien	      error_init ("duplicate initializer");
613518334Speter	      duplicate = 1;
613618334Speter	    }
613718334Speter	}
613818334Speter    }
613918334Speter
614018334Speter  /* If this element doesn't come next in sequence,
614118334Speter     put it on constructor_pending_elts.  */
614218334Speter  if (TREE_CODE (constructor_type) == ARRAY_TYPE
614318334Speter      && !tree_int_cst_equal (field, constructor_unfilled_index))
614418334Speter    {
614518334Speter      if (! duplicate)
614618334Speter	/* The copy_node is needed in case field is actually
614718334Speter	   constructor_index, which is modified in place.  */
614850397Sobrien	add_pending_init (copy_node (field),
614950397Sobrien			  digest_init (type, value, require_constant_value,
615050397Sobrien				       require_constant_elements));
615118334Speter    }
615218334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
615318334Speter	   && field != constructor_unfilled_fields)
615418334Speter    {
615518334Speter      /* We do this for records but not for unions.  In a union,
615618334Speter	 no matter which field is specified, it can be initialized
615718334Speter	 right away since it starts at the beginning of the union.  */
615818334Speter      if (!duplicate)
615950397Sobrien	add_pending_init (field,
616050397Sobrien			  digest_init (type, value, require_constant_value,
616150397Sobrien				       require_constant_elements));
616218334Speter    }
616318334Speter  else
616418334Speter    {
616518334Speter      /* Otherwise, output this element either to
616618334Speter	 constructor_elements or to the assembler file.  */
616718334Speter
616818334Speter      if (!duplicate)
616918334Speter	{
617018334Speter	  if (! constructor_incremental)
617118334Speter	    {
617218334Speter	      if (field && TREE_CODE (field) == INTEGER_CST)
617318334Speter		field = copy_node (field);
617418334Speter	      constructor_elements
617518334Speter		= tree_cons (field, digest_init (type, value,
617618334Speter						 require_constant_value,
617718334Speter						 require_constant_elements),
617818334Speter			     constructor_elements);
617918334Speter	    }
618018334Speter	  else
618118334Speter	    {
618218334Speter	      /* Structure elements may require alignment.
618318334Speter		 Do this, if necessary.  */
618418334Speter	      if (TREE_CODE (constructor_type) == RECORD_TYPE)
618518334Speter		{
618618334Speter		  /* Advance to offset of this element.  */
618718334Speter		  if (! tree_int_cst_equal (constructor_bit_index,
618818334Speter					    DECL_FIELD_BITPOS (field)))
618918334Speter		    {
619050397Sobrien		      /* By using unsigned arithmetic, the result will be
619150397Sobrien			 correct even in case of overflows, if BITS_PER_UNIT
619250397Sobrien			 is a power of two.  */
619350397Sobrien		      unsigned next = (TREE_INT_CST_LOW
619450397Sobrien				       (DECL_FIELD_BITPOS (field))
619550397Sobrien				       / (unsigned)BITS_PER_UNIT);
619650397Sobrien		      unsigned here = (TREE_INT_CST_LOW
619750397Sobrien				       (constructor_bit_index)
619850397Sobrien				       / (unsigned)BITS_PER_UNIT);
619918334Speter
620050397Sobrien		      assemble_zeros ((next - here)
620150397Sobrien				      * (unsigned)BITS_PER_UNIT
620250397Sobrien				      / (unsigned)BITS_PER_UNIT);
620318334Speter		    }
620418334Speter		}
620518334Speter	      output_constant (digest_init (type, value,
620618334Speter					    require_constant_value,
620718334Speter					    require_constant_elements),
620818334Speter			       int_size_in_bytes (type));
620918334Speter
621018334Speter	      /* For a record or union,
621118334Speter		 keep track of end position of last field.  */
621218334Speter	      if (TREE_CODE (constructor_type) == RECORD_TYPE
621318334Speter		  || TREE_CODE (constructor_type) == UNION_TYPE)
621418334Speter		{
621518334Speter		  tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field),
621618334Speter					  DECL_SIZE (field));
621718334Speter		  TREE_INT_CST_LOW (constructor_bit_index)
621818334Speter		    = TREE_INT_CST_LOW (temp);
621918334Speter		  TREE_INT_CST_HIGH (constructor_bit_index)
622018334Speter		    = TREE_INT_CST_HIGH (temp);
622118334Speter		}
622218334Speter	    }
622318334Speter	}
622418334Speter
622518334Speter      /* Advance the variable that indicates sequential elements output.  */
622618334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
622718334Speter	{
622818334Speter	  tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index,
622918334Speter				 integer_one_node);
623018334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
623118334Speter	    = TREE_INT_CST_LOW (tem);
623218334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
623318334Speter	    = TREE_INT_CST_HIGH (tem);
623418334Speter	}
623518334Speter      else if (TREE_CODE (constructor_type) == RECORD_TYPE)
623618334Speter	constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
623718334Speter      else if (TREE_CODE (constructor_type) == UNION_TYPE)
623818334Speter	constructor_unfilled_fields = 0;
623918334Speter
624018334Speter      /* Now output any pending elements which have become next.  */
624118334Speter      if (pending)
624218334Speter	output_pending_init_elements (0);
624318334Speter    }
624418334Speter}
624518334Speter
624618334Speter/* Output any pending elements which have become next.
624718334Speter   As we output elements, constructor_unfilled_{fields,index}
624818334Speter   advances, which may cause other elements to become next;
624918334Speter   if so, they too are output.
625018334Speter
625118334Speter   If ALL is 0, we return when there are
625218334Speter   no more pending elements to output now.
625318334Speter
625418334Speter   If ALL is 1, we output space as necessary so that
625518334Speter   we can output all the pending elements.  */
625618334Speter
625718334Speterstatic void
625818334Speteroutput_pending_init_elements (all)
625918334Speter     int all;
626018334Speter{
626150397Sobrien  struct init_node *elt = constructor_pending_elts;
626218334Speter  tree next;
626318334Speter
626418334Speter retry:
626518334Speter
626650397Sobrien  /* Look thru the whole pending tree.
626718334Speter     If we find an element that should be output now,
626818334Speter     output it.  Otherwise, set NEXT to the element
626918334Speter     that comes first among those still pending.  */
627018334Speter
627118334Speter  next = 0;
627250397Sobrien  while (elt)
627318334Speter    {
627418334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
627518334Speter	{
627650397Sobrien	  if (tree_int_cst_equal (elt->purpose,
627718334Speter				  constructor_unfilled_index))
627850397Sobrien	    output_init_element (elt->value,
627950397Sobrien				 TREE_TYPE (constructor_type),
628050397Sobrien				 constructor_unfilled_index, 0);
628150397Sobrien	  else if (tree_int_cst_lt (constructor_unfilled_index,
628250397Sobrien				    elt->purpose))
628318334Speter	    {
628450397Sobrien	      /* Advance to the next smaller node.  */
628550397Sobrien	      if (elt->left)
628650397Sobrien		elt = elt->left;
628750397Sobrien	      else
628850397Sobrien		{
628950397Sobrien		  /* We have reached the smallest node bigger than the
629050397Sobrien		     current unfilled index.  Fill the space first.  */
629150397Sobrien		  next = elt->purpose;
629250397Sobrien		  break;
629350397Sobrien		}
629418334Speter	    }
629550397Sobrien	  else
629650397Sobrien	    {
629750397Sobrien	      /* Advance to the next bigger node.  */
629850397Sobrien	      if (elt->right)
629950397Sobrien		elt = elt->right;
630050397Sobrien	      else
630150397Sobrien		{
630250397Sobrien		  /* We have reached the biggest node in a subtree.  Find
630350397Sobrien		     the parent of it, which is the next bigger node.  */
630450397Sobrien		  while (elt->parent && elt->parent->right == elt)
630550397Sobrien		    elt = elt->parent;
630650397Sobrien		  elt = elt->parent;
630750397Sobrien		  if (elt && tree_int_cst_lt (constructor_unfilled_index,
630850397Sobrien					      elt->purpose))
630950397Sobrien		    {
631050397Sobrien		      next = elt->purpose;
631150397Sobrien		      break;
631250397Sobrien		    }
631350397Sobrien		}
631450397Sobrien	    }
631518334Speter	}
631618334Speter      else if (TREE_CODE (constructor_type) == RECORD_TYPE
631718334Speter	       || TREE_CODE (constructor_type) == UNION_TYPE)
631818334Speter	{
631950397Sobrien	  /* If the current record is complete we are done.  */
632050397Sobrien	  if (constructor_unfilled_fields == 0)
632150397Sobrien	    break;
632250397Sobrien	  if (elt->purpose == constructor_unfilled_fields)
632318334Speter	    {
632450397Sobrien	      output_init_element (elt->value,
632518334Speter				   TREE_TYPE (constructor_unfilled_fields),
632618334Speter				   constructor_unfilled_fields,
632718334Speter				   0);
632818334Speter	    }
632950397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
633050397Sobrien				    DECL_FIELD_BITPOS (elt->purpose)))
633150397Sobrien	    {
633250397Sobrien	      /* Advance to the next smaller node.  */
633350397Sobrien	      if (elt->left)
633450397Sobrien		elt = elt->left;
633550397Sobrien	      else
633650397Sobrien		{
633750397Sobrien		  /* We have reached the smallest node bigger than the
633850397Sobrien		     current unfilled field.  Fill the space first.  */
633950397Sobrien		  next = elt->purpose;
634050397Sobrien		  break;
634150397Sobrien		}
634250397Sobrien	    }
634350397Sobrien	  else
634450397Sobrien	    {
634550397Sobrien	      /* Advance to the next bigger node.  */
634650397Sobrien	      if (elt->right)
634750397Sobrien		elt = elt->right;
634850397Sobrien	      else
634950397Sobrien		{
635050397Sobrien		  /* We have reached the biggest node in a subtree.  Find
635150397Sobrien		     the parent of it, which is the next bigger node.  */
635250397Sobrien		  while (elt->parent && elt->parent->right == elt)
635350397Sobrien		    elt = elt->parent;
635450397Sobrien		  elt = elt->parent;
635550397Sobrien		  if (elt
635650397Sobrien		      && tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
635750397Sobrien					  DECL_FIELD_BITPOS (elt->purpose)))
635850397Sobrien		    {
635950397Sobrien		      next = elt->purpose;
636050397Sobrien		      break;
636150397Sobrien		    }
636250397Sobrien		}
636350397Sobrien	    }
636418334Speter	}
636518334Speter    }
636618334Speter
636718334Speter  /* Ordinarily return, but not if we want to output all
636818334Speter     and there are elements left.  */
636918334Speter  if (! (all && next != 0))
637018334Speter    return;
637118334Speter
637218334Speter  /* Generate space up to the position of NEXT.  */
637318334Speter  if (constructor_incremental)
637418334Speter    {
637518334Speter      tree filled;
637618334Speter      tree nextpos_tree = size_int (0);
637718334Speter
637818334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
637918334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
638018334Speter	{
638150397Sobrien	  tree tail;
638218334Speter	  /* Find the last field written out, if any.  */
638318334Speter	  for (tail = TYPE_FIELDS (constructor_type); tail;
638418334Speter	       tail = TREE_CHAIN (tail))
638518334Speter	    if (TREE_CHAIN (tail) == constructor_unfilled_fields)
638618334Speter	      break;
638718334Speter
638818334Speter	  if (tail)
638918334Speter	    /* Find the offset of the end of that field.  */
639018334Speter	    filled = size_binop (CEIL_DIV_EXPR,
639118334Speter				 size_binop (PLUS_EXPR,
639218334Speter					     DECL_FIELD_BITPOS (tail),
639318334Speter					     DECL_SIZE (tail)),
639418334Speter				 size_int (BITS_PER_UNIT));
639518334Speter	  else
639618334Speter	    filled = size_int (0);
639718334Speter
639818334Speter	  nextpos_tree = size_binop (CEIL_DIV_EXPR,
639918334Speter				     DECL_FIELD_BITPOS (next),
640018334Speter				     size_int (BITS_PER_UNIT));
640118334Speter
640218334Speter	  TREE_INT_CST_HIGH (constructor_bit_index)
640318334Speter	    = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next));
640418334Speter	  TREE_INT_CST_LOW (constructor_bit_index)
640518334Speter	    = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next));
640618334Speter	  constructor_unfilled_fields = next;
640718334Speter	}
640818334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
640918334Speter	{
641018334Speter	  filled = size_binop (MULT_EXPR, constructor_unfilled_index,
641118334Speter			       size_in_bytes (TREE_TYPE (constructor_type)));
641218334Speter	  nextpos_tree
641318334Speter	    = size_binop (MULT_EXPR, next,
641418334Speter			  size_in_bytes (TREE_TYPE (constructor_type)));
641518334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
641618334Speter	    = TREE_INT_CST_LOW (next);
641718334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
641818334Speter	    = TREE_INT_CST_HIGH (next);
641918334Speter	}
642018334Speter      else
642118334Speter	filled = 0;
642218334Speter
642318334Speter      if (filled)
642418334Speter	{
642518334Speter	  int nextpos = TREE_INT_CST_LOW (nextpos_tree);
642618334Speter
642718334Speter	  assemble_zeros (nextpos - TREE_INT_CST_LOW (filled));
642818334Speter	}
642918334Speter    }
643018334Speter  else
643118334Speter    {
643218334Speter      /* If it's not incremental, just skip over the gap,
643318334Speter	 so that after jumping to retry we will output the next
643418334Speter	 successive element.  */
643518334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
643618334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
643718334Speter	constructor_unfilled_fields = next;
643818334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
643918334Speter	{
644018334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
644118334Speter	    = TREE_INT_CST_LOW (next);
644218334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
644318334Speter	    = TREE_INT_CST_HIGH (next);
644418334Speter	}
644518334Speter    }
644618334Speter
644750397Sobrien  /* ELT now points to the node in the pending tree with the next
644850397Sobrien     initializer to output.  */
644918334Speter  goto retry;
645018334Speter}
645118334Speter
645218334Speter/* Add one non-braced element to the current constructor level.
645318334Speter   This adjusts the current position within the constructor's type.
645418334Speter   This may also start or terminate implicit levels
645518334Speter   to handle a partly-braced initializer.
645618334Speter
645718334Speter   Once this has found the correct level for the new element,
645818334Speter   it calls output_init_element.
645918334Speter
646018334Speter   Note: if we are incrementally outputting this constructor,
646118334Speter   this function may be called with a null argument
646218334Speter   representing a sub-constructor that was already incrementally output.
646318334Speter   When that happens, we output nothing, but we do the bookkeeping
646418334Speter   to skip past that element of the current constructor.  */
646518334Speter
646618334Spetervoid
646718334Speterprocess_init_element (value)
646818334Speter     tree value;
646918334Speter{
647018334Speter  tree orig_value = value;
647118334Speter  int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
647218334Speter
647318334Speter  /* Handle superfluous braces around string cst as in
647418334Speter     char x[] = {"foo"}; */
647518334Speter  if (string_flag
647618334Speter      && constructor_type
647718334Speter      && TREE_CODE (constructor_type) == ARRAY_TYPE
647818334Speter      && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE
647918334Speter      && integer_zerop (constructor_unfilled_index))
648018334Speter    {
648118334Speter      constructor_stack->replacement_value = value;
648218334Speter      return;
648318334Speter    }
648418334Speter
648518334Speter  if (constructor_stack->replacement_value != 0)
648618334Speter    {
648752284Sobrien      error_init ("excess elements in struct initializer");
648818334Speter      return;
648918334Speter    }
649018334Speter
649118334Speter  /* Ignore elements of a brace group if it is entirely superfluous
649218334Speter     and has already been diagnosed.  */
649318334Speter  if (constructor_type == 0)
649418334Speter    return;
649518334Speter
649618334Speter  /* If we've exhausted any levels that didn't have braces,
649718334Speter     pop them now.  */
649818334Speter  while (constructor_stack->implicit)
649918334Speter    {
650018334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
650118334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
650218334Speter	  && constructor_fields == 0)
650318334Speter	process_init_element (pop_init_level (1));
650418334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
650550397Sobrien	       && (constructor_max_index == 0
650650397Sobrien		   || tree_int_cst_lt (constructor_max_index,
650750397Sobrien				       constructor_index)))
650818334Speter	process_init_element (pop_init_level (1));
650918334Speter      else
651018334Speter	break;
651118334Speter    }
651218334Speter
651318334Speter  while (1)
651418334Speter    {
651518334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE)
651618334Speter	{
651718334Speter	  tree fieldtype;
651818334Speter	  enum tree_code fieldcode;
651918334Speter
652018334Speter	  if (constructor_fields == 0)
652118334Speter	    {
652252284Sobrien	      pedwarn_init ("excess elements in struct initializer");
652318334Speter	      break;
652418334Speter	    }
652518334Speter
652618334Speter	  fieldtype = TREE_TYPE (constructor_fields);
652718334Speter	  if (fieldtype != error_mark_node)
652818334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
652918334Speter	  fieldcode = TREE_CODE (fieldtype);
653018334Speter
653118334Speter	  /* Accept a string constant to initialize a subarray.  */
653218334Speter	  if (value != 0
653318334Speter	      && fieldcode == ARRAY_TYPE
653418334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
653518334Speter	      && string_flag)
653618334Speter	    value = orig_value;
653718334Speter	  /* Otherwise, if we have come to a subaggregate,
653818334Speter	     and we don't have an element of its type, push into it.  */
653918334Speter	  else if (value != 0 && !constructor_no_implicit
654018334Speter		   && value != error_mark_node
654118334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
654218334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
654318334Speter		       || fieldcode == UNION_TYPE))
654418334Speter	    {
654518334Speter	      push_init_level (1);
654618334Speter	      continue;
654718334Speter	    }
654818334Speter
654918334Speter	  if (value)
655018334Speter	    {
655118334Speter	      push_member_name (constructor_fields);
655218334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
655318334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
655418334Speter	    }
655518334Speter	  else
655618334Speter	    /* Do the bookkeeping for an element that was
655718334Speter	       directly output as a constructor.  */
655818334Speter	    {
655918334Speter	      /* For a record, keep track of end position of last field.  */
656018334Speter	      tree temp = size_binop (PLUS_EXPR,
656118334Speter				      DECL_FIELD_BITPOS (constructor_fields),
656218334Speter				      DECL_SIZE (constructor_fields));
656318334Speter	      TREE_INT_CST_LOW (constructor_bit_index)
656418334Speter		= TREE_INT_CST_LOW (temp);
656518334Speter	      TREE_INT_CST_HIGH (constructor_bit_index)
656618334Speter		= TREE_INT_CST_HIGH (temp);
656718334Speter
656818334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
656918334Speter	    }
657018334Speter
657118334Speter	  constructor_fields = TREE_CHAIN (constructor_fields);
657218334Speter	  /* Skip any nameless bit fields at the beginning.  */
657350397Sobrien	  while (constructor_fields != 0
657450397Sobrien		 && DECL_C_BIT_FIELD (constructor_fields)
657518334Speter		 && DECL_NAME (constructor_fields) == 0)
657618334Speter	    constructor_fields = TREE_CHAIN (constructor_fields);
657718334Speter	  break;
657818334Speter	}
657918334Speter      if (TREE_CODE (constructor_type) == UNION_TYPE)
658018334Speter	{
658118334Speter	  tree fieldtype;
658218334Speter	  enum tree_code fieldcode;
658318334Speter
658418334Speter	  if (constructor_fields == 0)
658518334Speter	    {
658652284Sobrien	      pedwarn_init ("excess elements in union initializer");
658718334Speter	      break;
658818334Speter	    }
658918334Speter
659018334Speter	  fieldtype = TREE_TYPE (constructor_fields);
659118334Speter	  if (fieldtype != error_mark_node)
659218334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
659318334Speter	  fieldcode = TREE_CODE (fieldtype);
659418334Speter
659518334Speter	  /* Accept a string constant to initialize a subarray.  */
659618334Speter	  if (value != 0
659718334Speter	      && fieldcode == ARRAY_TYPE
659818334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
659918334Speter	      && string_flag)
660018334Speter	    value = orig_value;
660118334Speter	  /* Otherwise, if we have come to a subaggregate,
660218334Speter	     and we don't have an element of its type, push into it.  */
660318334Speter	  else if (value != 0 && !constructor_no_implicit
660418334Speter		   && value != error_mark_node
660518334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
660618334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
660718334Speter		       || fieldcode == UNION_TYPE))
660818334Speter	    {
660918334Speter	      push_init_level (1);
661018334Speter	      continue;
661118334Speter	    }
661218334Speter
661318334Speter	  if (value)
661418334Speter	    {
661518334Speter	      push_member_name (constructor_fields);
661618334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
661718334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
661818334Speter	    }
661918334Speter	  else
662018334Speter	    /* Do the bookkeeping for an element that was
662118334Speter	       directly output as a constructor.  */
662218334Speter	    {
662318334Speter	      TREE_INT_CST_LOW (constructor_bit_index)
662418334Speter		= TREE_INT_CST_LOW (DECL_SIZE (constructor_fields));
662518334Speter	      TREE_INT_CST_HIGH (constructor_bit_index)
662618334Speter		= TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields));
662718334Speter
662818334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
662918334Speter	    }
663018334Speter
663118334Speter	  constructor_fields = 0;
663218334Speter	  break;
663318334Speter	}
663418334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
663518334Speter	{
663618334Speter	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
663718334Speter	  enum tree_code eltcode = TREE_CODE (elttype);
663818334Speter
663918334Speter	  /* Accept a string constant to initialize a subarray.  */
664018334Speter	  if (value != 0
664118334Speter	      && eltcode == ARRAY_TYPE
664218334Speter	      && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE
664318334Speter	      && string_flag)
664418334Speter	    value = orig_value;
664518334Speter	  /* Otherwise, if we have come to a subaggregate,
664618334Speter	     and we don't have an element of its type, push into it.  */
664718334Speter	  else if (value != 0 && !constructor_no_implicit
664818334Speter		   && value != error_mark_node
664918334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
665018334Speter		   && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
665118334Speter		       || eltcode == UNION_TYPE))
665218334Speter	    {
665318334Speter	      push_init_level (1);
665418334Speter	      continue;
665518334Speter	    }
665618334Speter
665718334Speter	  if (constructor_max_index != 0
665818334Speter	      && tree_int_cst_lt (constructor_max_index, constructor_index))
665918334Speter	    {
666052284Sobrien	      pedwarn_init ("excess elements in array initializer");
666118334Speter	      break;
666218334Speter	    }
666318334Speter
666450397Sobrien	  /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once.  */
666518334Speter	  if (constructor_range_end)
666650397Sobrien	    {
666750397Sobrien	      if (constructor_max_index != 0
666850397Sobrien		  && tree_int_cst_lt (constructor_max_index,
666950397Sobrien				      constructor_range_end))
667050397Sobrien		{
667152284Sobrien		  pedwarn_init ("excess elements in array initializer");
667250397Sobrien		  TREE_INT_CST_HIGH (constructor_range_end)
667350397Sobrien		    = TREE_INT_CST_HIGH (constructor_max_index);
667450397Sobrien		  TREE_INT_CST_LOW (constructor_range_end)
667550397Sobrien		    = TREE_INT_CST_LOW (constructor_max_index);
667650397Sobrien		}
667718334Speter
667850397Sobrien	      value = save_expr (value);
667950397Sobrien	    }
668050397Sobrien
668118334Speter	  /* Now output the actual element.
668218334Speter	     Ordinarily, output once.
668318334Speter	     If there is a range, repeat it till we advance past the range.  */
668418334Speter	  do
668518334Speter	    {
668618334Speter	      tree tem;
668718334Speter
668818334Speter	      if (value)
668918334Speter		{
669018334Speter		  push_array_bounds (TREE_INT_CST_LOW (constructor_index));
669118334Speter		  output_init_element (value, elttype, constructor_index, 1);
669218334Speter		  RESTORE_SPELLING_DEPTH (constructor_depth);
669318334Speter		}
669418334Speter
669518334Speter	      tem = size_binop (PLUS_EXPR, constructor_index,
669618334Speter				integer_one_node);
669750397Sobrien	      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem);
669850397Sobrien	      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem);
669918334Speter
670018334Speter	      if (!value)
670118334Speter		/* If we are doing the bookkeeping for an element that was
670218334Speter		   directly output as a constructor,
670318334Speter		   we must update constructor_unfilled_index.  */
670418334Speter		{
670518334Speter		  TREE_INT_CST_LOW (constructor_unfilled_index)
670618334Speter		    = TREE_INT_CST_LOW (constructor_index);
670718334Speter		  TREE_INT_CST_HIGH (constructor_unfilled_index)
670818334Speter		    = TREE_INT_CST_HIGH (constructor_index);
670918334Speter		}
671018334Speter	    }
671118334Speter	  while (! (constructor_range_end == 0
671218334Speter		    || tree_int_cst_lt (constructor_range_end,
671318334Speter					constructor_index)));
671418334Speter
671518334Speter	  break;
671618334Speter	}
671718334Speter
671818334Speter      /* Handle the sole element allowed in a braced initializer
671918334Speter	 for a scalar variable.  */
672018334Speter      if (constructor_fields == 0)
672118334Speter	{
672252284Sobrien	  pedwarn_init ("excess elements in scalar initializer");
672318334Speter	  break;
672418334Speter	}
672518334Speter
672618334Speter      if (value)
672718334Speter	output_init_element (value, constructor_type, NULL_TREE, 1);
672818334Speter      constructor_fields = 0;
672918334Speter      break;
673018334Speter    }
673118334Speter
673218334Speter  /* If the (lexically) previous elments are not now saved,
673318334Speter     we can discard the storage for them.  */
673418334Speter  if (constructor_incremental && constructor_pending_elts == 0 && value != 0
673518334Speter      && constructor_stack == 0)
673618334Speter    clear_momentary ();
673718334Speter}
673818334Speter
673918334Speter/* Expand an ASM statement with operands, handling output operands
674018334Speter   that are not variables or INDIRECT_REFS by transforming such
674118334Speter   cases into cases that expand_asm_operands can handle.
674218334Speter
674318334Speter   Arguments are same as for expand_asm_operands.  */
674418334Speter
674518334Spetervoid
674618334Speterc_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
674718334Speter     tree string, outputs, inputs, clobbers;
674818334Speter     int vol;
674918334Speter     char *filename;
675018334Speter     int line;
675118334Speter{
675218334Speter  int noutputs = list_length (outputs);
675318334Speter  register int i;
675418334Speter  /* o[I] is the place that output number I should be written.  */
675518334Speter  register tree *o = (tree *) alloca (noutputs * sizeof (tree));
675618334Speter  register tree tail;
675718334Speter
675818334Speter  if (TREE_CODE (string) == ADDR_EXPR)
675918334Speter    string = TREE_OPERAND (string, 0);
676018334Speter  if (TREE_CODE (string) != STRING_CST)
676118334Speter    {
676218334Speter      error ("asm template is not a string constant");
676318334Speter      return;
676418334Speter    }
676518334Speter
676618334Speter  /* Record the contents of OUTPUTS before it is modified.  */
676718334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
676818334Speter    o[i] = TREE_VALUE (tail);
676918334Speter
677018334Speter  /* Perform default conversions on array and function inputs.  */
677118334Speter  /* Don't do this for other types--
677218334Speter     it would screw up operands expected to be in memory.  */
677318334Speter  for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
677418334Speter    if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE
677518334Speter	|| TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
677618334Speter      TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
677718334Speter
677818334Speter  /* Generate the ASM_OPERANDS insn;
677918334Speter     store into the TREE_VALUEs of OUTPUTS some trees for
678018334Speter     where the values were actually stored.  */
678118334Speter  expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
678218334Speter
678318334Speter  /* Copy all the intermediate outputs into the specified outputs.  */
678418334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
678518334Speter    {
678618334Speter      if (o[i] != TREE_VALUE (tail))
678718334Speter	{
678818334Speter	  expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
678950397Sobrien		       NULL_RTX, VOIDmode, EXPAND_NORMAL);
679018334Speter	  free_temp_slots ();
679118334Speter	}
679218334Speter      /* Detect modification of read-only values.
679318334Speter	 (Otherwise done by build_modify_expr.)  */
679418334Speter      else
679518334Speter	{
679618334Speter	  tree type = TREE_TYPE (o[i]);
679718334Speter	  if (TREE_READONLY (o[i])
679818334Speter	      || TYPE_READONLY (type)
679918334Speter	      || ((TREE_CODE (type) == RECORD_TYPE
680018334Speter		   || TREE_CODE (type) == UNION_TYPE)
680118334Speter		  && C_TYPE_FIELDS_READONLY (type)))
680218334Speter	    readonly_warning (o[i], "modification by `asm'");
680318334Speter	}
680418334Speter    }
680518334Speter
680618334Speter  /* Those MODIFY_EXPRs could do autoincrements.  */
680718334Speter  emit_queue ();
680818334Speter}
680918334Speter
681018334Speter/* Expand a C `return' statement.
681118334Speter   RETVAL is the expression for what to return,
681218334Speter   or a null pointer for `return;' with no value.  */
681318334Speter
681418334Spetervoid
681518334Speterc_expand_return (retval)
681618334Speter     tree retval;
681718334Speter{
681818334Speter  tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
681918334Speter
682018334Speter  if (TREE_THIS_VOLATILE (current_function_decl))
682118334Speter    warning ("function declared `noreturn' has a `return' statement");
682218334Speter
682318334Speter  if (!retval)
682418334Speter    {
682518334Speter      current_function_returns_null = 1;
682618334Speter      if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
682718334Speter	warning ("`return' with no value, in function returning non-void");
682818334Speter      expand_null_return ();
682918334Speter    }
683018334Speter  else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
683118334Speter    {
683218334Speter      current_function_returns_null = 1;
683318334Speter      if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
683418334Speter	pedwarn ("`return' with a value, in function returning void");
683518334Speter      expand_return (retval);
683618334Speter    }
683718334Speter  else
683818334Speter    {
683952284Sobrien      tree t = convert_for_assignment (valtype, retval, _("return"),
684018334Speter				       NULL_TREE, NULL_TREE, 0);
684118334Speter      tree res = DECL_RESULT (current_function_decl);
684218334Speter      tree inner;
684318334Speter
684418334Speter      if (t == error_mark_node)
684518334Speter	return;
684618334Speter
684718334Speter      inner = t = convert (TREE_TYPE (res), t);
684818334Speter
684918334Speter      /* Strip any conversions, additions, and subtractions, and see if
685018334Speter	 we are returning the address of a local variable.  Warn if so.  */
685118334Speter      while (1)
685218334Speter	{
685318334Speter	  switch (TREE_CODE (inner))
685418334Speter	    {
685518334Speter	    case NOP_EXPR:   case NON_LVALUE_EXPR:  case CONVERT_EXPR:
685618334Speter	    case PLUS_EXPR:
685718334Speter	      inner = TREE_OPERAND (inner, 0);
685818334Speter	      continue;
685918334Speter
686018334Speter	    case MINUS_EXPR:
686118334Speter	      /* If the second operand of the MINUS_EXPR has a pointer
686218334Speter		 type (or is converted from it), this may be valid, so
686318334Speter		 don't give a warning.  */
686418334Speter	      {
686518334Speter		tree op1 = TREE_OPERAND (inner, 1);
686618334Speter
686718334Speter		while (! POINTER_TYPE_P (TREE_TYPE (op1))
686818334Speter		       && (TREE_CODE (op1) == NOP_EXPR
686918334Speter			   || TREE_CODE (op1) == NON_LVALUE_EXPR
687018334Speter			   || TREE_CODE (op1) == CONVERT_EXPR))
687118334Speter		  op1 = TREE_OPERAND (op1, 0);
687218334Speter
687318334Speter		if (POINTER_TYPE_P (TREE_TYPE (op1)))
687418334Speter		  break;
687518334Speter
687618334Speter		inner = TREE_OPERAND (inner, 0);
687718334Speter		continue;
687818334Speter	      }
687918334Speter
688018334Speter	    case ADDR_EXPR:
688118334Speter	      inner = TREE_OPERAND (inner, 0);
688218334Speter
688318334Speter	      while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
688418334Speter		inner = TREE_OPERAND (inner, 0);
688518334Speter
688618334Speter	      if (TREE_CODE (inner) == VAR_DECL
688718334Speter		  && ! DECL_EXTERNAL (inner)
688818334Speter		  && ! TREE_STATIC (inner)
688918334Speter		  && DECL_CONTEXT (inner) == current_function_decl)
689018334Speter		warning ("function returns address of local variable");
689118334Speter	      break;
689250397Sobrien
689350397Sobrien	    default:
689450397Sobrien	      break;
689518334Speter	    }
689618334Speter
689718334Speter	  break;
689818334Speter	}
689918334Speter
690018334Speter      t = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
690118334Speter      TREE_SIDE_EFFECTS (t) = 1;
690218334Speter      expand_return (t);
690318334Speter      current_function_returns_value = 1;
690418334Speter    }
690518334Speter}
690618334Speter
690718334Speter/* Start a C switch statement, testing expression EXP.
690818334Speter   Return EXP if it is valid, an error node otherwise.  */
690918334Speter
691018334Spetertree
691118334Speterc_expand_start_case (exp)
691218334Speter     tree exp;
691318334Speter{
691418334Speter  register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
691518334Speter  tree type = TREE_TYPE (exp);
691618334Speter
691718334Speter  if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
691818334Speter    {
691918334Speter      error ("switch quantity not an integer");
692018334Speter      exp = error_mark_node;
692118334Speter    }
692218334Speter  else
692318334Speter    {
692418334Speter      tree index;
692518334Speter      type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
692618334Speter
692718334Speter      if (warn_traditional
692818334Speter	  && (type == long_integer_type_node
692918334Speter	      || type == long_unsigned_type_node))
693018334Speter	pedwarn ("`long' switch expression not converted to `int' in ANSI C");
693118334Speter
693218334Speter      exp = default_conversion (exp);
693318334Speter      type = TREE_TYPE (exp);
693418334Speter      index = get_unwidened (exp, NULL_TREE);
693518334Speter      /* We can't strip a conversion from a signed type to an unsigned,
693618334Speter	 because if we did, int_fits_type_p would do the wrong thing
693718334Speter	 when checking case values for being in range,
693818334Speter	 and it's too hard to do the right thing.  */
693918334Speter      if (TREE_UNSIGNED (TREE_TYPE (exp))
694018334Speter	  == TREE_UNSIGNED (TREE_TYPE (index)))
694118334Speter	exp = index;
694218334Speter    }
694318334Speter
694418334Speter  expand_start_case (1, exp, type, "switch statement");
694518334Speter
694618334Speter  return exp;
694718334Speter}
6948