159279Selan /* Build expressions with type checking for C compiler.
259279Selan    Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
359279Selan 
459279Selan This file is part of GNU CC.
559279Selan 
659279Selan GNU CC is free software; you can redistribute it and/or modify
759279Selan it under the terms of the GNU General Public License as published by
859279Selan the Free Software Foundation; either version 2, or (at your option)
959279Selan any later version.
1059279Selan 
1159279Selan GNU CC is distributed in the hope that it will be useful,
1259279Selan but WITHOUT ANY WARRANTY; without even the implied warranty of
1359279Selan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1459279Selan GNU General Public License for more details.
1559279Selan 
1659279Selan You should have received a copy of the GNU General Public License
1759279Selan along with GNU CC; see the file COPYING.  If not, write to
1859279Selan the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1959279Selan 
2059279Selan 
2159279Selan /* This file is part of the C front end.
2259279Selan    It contains routines to build C expressions given their operands,
2359279Selan    including computing the types of the result, C-specific error checks,
2459279Selan    and some optimization.
2559279Selan 
2659279Selan    There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
2759279Selan    and to process initializations in declarations (since they work
2859279Selan    like a strange sort of assignment).  */
2959279Selan 
3059279Selan #include "config.h"
3159279Selan #include <stdio.h>
3259279Selan #include "tree.h"
3359279Selan #include "c-tree.h"
3459279Selan #include "flags.h"
3559279Selan 
3659279Selan extern char *index ();
3759279Selan extern char *rindex ();
3859279Selan 
3959279Selan int mark_addressable ();
4059279Selan static tree convert_for_assignment ();
4159279Selan static void warn_for_assignment ();
4259279Selan static int function_types_compatible_p ();
4359279Selan static int type_lists_compatible_p ();
4459279Selan int self_promoting_args_p ();
4559279Selan static int self_promoting_type_p ();
4659279Selan static int comp_target_types ();
4759279Selan static tree pointer_int_sum ();
4859279Selan static tree pointer_diff ();
4959279Selan static tree convert_sequence ();
5059279Selan static tree unary_complex_lvalue ();
5159279Selan static tree process_init_constructor ();
5259279Selan static tree convert_arguments ();
5359279Selan static char *get_spelling ();
5459279Selan tree digest_init ();
5559279Selan static void pedantic_lvalue_warning ();
5659279Selan tree truthvalue_conversion ();
5759279Selan void incomplete_type_error ();
5859279Selan void readonly_warning ();
5959279Selan 
6059279Selan /* Do `exp = require_complete_type (exp);' to make sure exp
6159279Selan    does not have an incomplete type.  (That includes void types.)  */
6259279Selan 
6359279Selan tree
require_complete_type(value)6459279Selan require_complete_type (value)
6559279Selan      tree value;
6659279Selan {
6759279Selan   tree type = TREE_TYPE (value);
6859279Selan 
6959279Selan   /* First, detect a valid value with a complete type.  */
7059279Selan   if (TYPE_SIZE (type) != 0
7159279Selan       && type != void_type_node)
7259279Selan     return value;
7359279Selan 
7459279Selan   incomplete_type_error (value, type);
7559279Selan   return error_mark_node;
7659279Selan }
7759279Selan 
7859279Selan /* Print an error message for invalid use of an incomplete type.
7959279Selan    VALUE is the expression that was used (or 0 if that isn't known)
8059279Selan    and TYPE is the type that was invalid.  */
8159279Selan 
8259279Selan void
incomplete_type_error(value,type)8359279Selan incomplete_type_error (value, type)
8459279Selan      tree value;
8559279Selan      tree type;
8659279Selan {
8759279Selan   char *errmsg;
8859279Selan 
8959279Selan   /* Avoid duplicate error message.  */
9059279Selan   if (TREE_CODE (type) == ERROR_MARK)
9159279Selan     return;
9259279Selan 
9359279Selan   if (value != 0 && (TREE_CODE (value) == VAR_DECL
9459279Selan 		     || TREE_CODE (value) == PARM_DECL))
9559279Selan     error ("`%s' has an incomplete type",
9659279Selan 	   IDENTIFIER_POINTER (DECL_NAME (value)));
9759279Selan   else
9859279Selan     {
9959279Selan     retry:
10059279Selan       /* We must print an error message.  Be clever about what it says.  */
10159279Selan 
10259279Selan       switch (TREE_CODE (type))
10359279Selan 	{
10459279Selan 	case RECORD_TYPE:
10559279Selan 	  errmsg = "invalid use of undefined type `struct %s'";
10659279Selan 	  break;
10759279Selan 
10859279Selan 	case UNION_TYPE:
10959279Selan 	  errmsg = "invalid use of undefined type `union %s'";
11059279Selan 	  break;
11159279Selan 
11259279Selan 	case ENUMERAL_TYPE:
11359279Selan 	  errmsg = "invalid use of undefined type `enum %s'";
11459279Selan 	  break;
11559279Selan 
11659279Selan 	case VOID_TYPE:
11759279Selan 	  error ("invalid use of void expression");
11859279Selan 	  return;
11959279Selan 
12059279Selan 	case ARRAY_TYPE:
12159279Selan 	  if (TYPE_DOMAIN (type))
12259279Selan 	    {
12359279Selan 	      type = TREE_TYPE (type);
12459279Selan 	      goto retry;
12559279Selan 	    }
12659279Selan 	  error ("invalid use of array with unspecified bounds");
12759279Selan 	  return;
12859279Selan 
12959279Selan 	default:
13059279Selan 	  abort ();
13159279Selan 	}
13259279Selan 
13359279Selan       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
13459279Selan 	error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
13559279Selan       else
13659279Selan 	/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
13759279Selan 	error ("invalid use of incomplete typedef `%s'",
13859279Selan 	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
13959279Selan     }
14059279Selan }
14159279Selan 
14259279Selan /* Return a variant of TYPE which has all the type qualifiers of LIKE
14359279Selan    as well as those of TYPE.  */
14459279Selan 
14559279Selan static tree
qualify_type(type,like)14659279Selan qualify_type (type, like)
14759279Selan      tree type, like;
14859279Selan {
14959279Selan   int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
15059279Selan   int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
15159279Selan   return c_build_type_variant (type, constflag, volflag);
15259279Selan }
15359279Selan 
15459279Selan /* Return the common type of two types.
15559279Selan    We assume that comptypes has already been done and returned 1;
15659279Selan    if that isn't so, this may crash.  In particular, we assume that qualifiers
15759279Selan    match.
15859279Selan 
15959279Selan    This is the type for the result of most arithmetic operations
16059279Selan    if the operands have the given two types.  */
16159279Selan 
16259279Selan tree
common_type(t1,t2)16359279Selan common_type (t1, t2)
16459279Selan      tree t1, t2;
16559279Selan {
16659279Selan   register enum tree_code code1;
16759279Selan   register enum tree_code code2;
16859279Selan 
16959279Selan   /* Save time if the two types are the same.  */
17059279Selan 
17159279Selan   if (t1 == t2) return t1;
17259279Selan 
17359279Selan   /* If one type is nonsense, use the other.  */
17459279Selan   if (t1 == error_mark_node)
17559279Selan     return t2;
17659279Selan   if (t2 == error_mark_node)
17759279Selan     return t1;
17859279Selan 
17959279Selan   /* Treat an enum type as the unsigned integer type of the same width.  */
18059279Selan 
18159279Selan   if (TREE_CODE (t1) == ENUMERAL_TYPE)
18259279Selan     t1 = type_for_size (TYPE_PRECISION (t1), 1);
18359279Selan   if (TREE_CODE (t2) == ENUMERAL_TYPE)
18459279Selan     t2 = type_for_size (TYPE_PRECISION (t2), 1);
18559279Selan 
18659279Selan   code1 = TREE_CODE (t1);
18759279Selan   code2 = TREE_CODE (t2);
18859279Selan 
18959279Selan   switch (code1)
19059279Selan     {
19159279Selan     case INTEGER_TYPE:
19259279Selan     case REAL_TYPE:
19359279Selan       /* If only one is real, use it as the result.  */
19459279Selan 
19559279Selan       if (code1 == REAL_TYPE && code2 != REAL_TYPE)
19659279Selan 	return t1;
19759279Selan 
19859279Selan       if (code2 == REAL_TYPE && code1 != REAL_TYPE)
19959279Selan 	return t2;
20059279Selan 
20159279Selan       /* Both real or both integers; use the one with greater precision.  */
20259279Selan 
20359279Selan       if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
20459279Selan 	return t1;
20559279Selan       else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
20659279Selan 	return t2;
20759279Selan 
20859279Selan       /* Same precision.  Prefer longs to ints even when same size.  */
20959279Selan 
21059279Selan       if (t1 == long_unsigned_type_node
21159279Selan 	  || t2 == long_unsigned_type_node)
21259279Selan 	return long_unsigned_type_node;
21359279Selan 
21459279Selan       if (t1 == long_integer_type_node
21559279Selan 	  || t2 == long_integer_type_node)
21659279Selan 	{
21759279Selan 	  /* But preserve unsignedness from the other type,
21859279Selan 	     since long cannot hold all the values of an unsigned int.  */
21959279Selan 	  if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
22059279Selan 	    return long_unsigned_type_node;
22159279Selan 	  return long_integer_type_node;
22259279Selan 	}
22359279Selan 
22459279Selan       /* Otherwise prefer the unsigned one.  */
22559279Selan 
22659279Selan       if (TREE_UNSIGNED (t1))
22759279Selan 	return t1;
22859279Selan       else return t2;
22959279Selan 
23059279Selan     case POINTER_TYPE:
23159279Selan       /* For two pointers, do this recursively on the target type,
23259279Selan 	 and combine the qualifiers of the two types' targets.  */
23359279Selan       /* This code was turned off; I don't know why.
23459279Selan 	 But ANSI C specifies doing this with the qualifiers.
23559279Selan 	 So I turned it on again.  */
23659279Selan       {
23759279Selan 	tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
23859279Selan 				   TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
23959279Selan 	int constp
24059279Selan 	  = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
24159279Selan 	int volatilep
24259279Selan 	  = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
24359279Selan 	return build_pointer_type (c_build_type_variant (target, constp, volatilep));
24459279Selan       }
24559279Selan #if 0
24659279Selan       return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
24759279Selan #endif
24859279Selan 
24959279Selan     case ARRAY_TYPE:
25059279Selan       {
25159279Selan 	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
25259279Selan 	/* Save space: see if the result is identical to one of the args.  */
25359279Selan 	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
25459279Selan 	  return t1;
25559279Selan 	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
25659279Selan 	  return t2;
25759279Selan 	/* Merge the element types, and have a size if either arg has one.  */
25859279Selan 	return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
25959279Selan       }
26059279Selan 
26159279Selan     case FUNCTION_TYPE:
26259279Selan       /* Function types: prefer the one that specified arg types.
26359279Selan 	 If both do, merge the arg types.  Also merge the return types.  */
26459279Selan       {
26559279Selan 	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
26659279Selan 	tree p1 = TYPE_ARG_TYPES (t1);
26759279Selan 	tree p2 = TYPE_ARG_TYPES (t2);
26859279Selan 	int len;
26959279Selan 	tree newargs, n;
27059279Selan 	int i;
27159279Selan 
27259279Selan 	/* Save space: see if the result is identical to one of the args.  */
27359279Selan 	if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2))
27459279Selan 	  return t1;
27559279Selan 	if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1))
27659279Selan 	  return t2;
27759279Selan 
27859279Selan 	/* Simple way if one arg fails to specify argument types.  */
27959279Selan 	if (TYPE_ARG_TYPES (t1) == 0)
28059279Selan 	  return build_function_type (valtype, TYPE_ARG_TYPES (t2));
28159279Selan 	if (TYPE_ARG_TYPES (t2) == 0)
28259279Selan 	  return build_function_type (valtype, TYPE_ARG_TYPES (t1));
28359279Selan 
28459279Selan 	/* If both args specify argument types, we must merge the two
28559279Selan 	   lists, argument by argument.  */
28659279Selan 
28759279Selan 	len = list_length (p1);
28859279Selan 	newargs = 0;
28959279Selan 
29059279Selan 	for (i = 0; i < len; i++)
29159279Selan 	  newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
29259279Selan 
29359279Selan 	n = newargs;
29459279Selan 
29559279Selan 	for (; p1;
29659279Selan 	     p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
29759279Selan 	  {
29859279Selan 	    /* A null type means arg type is not specified.
29959279Selan 	       Take whatever the other function type has.  */
30059279Selan 	    if (TREE_VALUE (p1) == 0)
30159279Selan 	      {
30259279Selan 		TREE_VALUE (n) = TREE_VALUE (p2);
30359279Selan 		goto parm_done;
30459279Selan 	      }
30559279Selan 	    if (TREE_VALUE (p2) == 0)
30659279Selan 	      {
30759279Selan 		TREE_VALUE (n) = TREE_VALUE (p1);
30859279Selan 		goto parm_done;
30959279Selan 	      }
31059279Selan 
31159279Selan 	    /* Given  wait (union {union wait *u; int *i} *)
31259279Selan 	       and  wait (union wait *),
31359279Selan 	       prefer  union wait *  as type of parm.  */
31459279Selan 	    if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
31559279Selan 		&& TREE_VALUE (p1) != TREE_VALUE (p2))
31659279Selan 	      {
31759279Selan 		tree memb;
31859279Selan 		for (memb = TYPE_FIELDS (TREE_VALUE (p1));
31959279Selan 		     memb; memb = TREE_CHAIN (memb))
32059279Selan 		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
32159279Selan 		    {
32259279Selan 		      TREE_VALUE (n) = TREE_VALUE (p2);
32359279Selan 		      if (pedantic)
32459279Selan 			pedwarn ("function types not truly compatible in ANSI C");
32559279Selan 		      goto parm_done;
32659279Selan 		    }
32759279Selan 	      }
32859279Selan 	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
32959279Selan 		&& TREE_VALUE (p2) != TREE_VALUE (p1))
33059279Selan 	      {
33159279Selan 		tree memb;
33259279Selan 		for (memb = TYPE_FIELDS (TREE_VALUE (p2));
33359279Selan 		     memb; memb = TREE_CHAIN (memb))
33459279Selan 		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
33559279Selan 		    {
33659279Selan 		      TREE_VALUE (n) = TREE_VALUE (p1);
33759279Selan 		      if (pedantic)
33859279Selan 			pedwarn ("function types not truly compatible in ANSI C");
33959279Selan 		      goto parm_done;
34059279Selan 		    }
34159279Selan 	      }
34259279Selan 	    TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
34359279Selan 	  parm_done: ;
34459279Selan 	  }
34559279Selan 
34659279Selan 	return build_function_type (valtype, newargs);
34759279Selan       }
34859279Selan 
34959279Selan     default:
35059279Selan       return t1;
35159279Selan     }
35259279Selan 
35359279Selan }
35459279Selan 
35559279Selan /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
35659279Selan    or various other operations.  Return 2 if they are compatible
35759279Selan    but a warning may be needed if you use them together.  */
35859279Selan 
35959279Selan int
comptypes(type1,type2)36059279Selan comptypes (type1, type2)
36159279Selan      tree type1, type2;
36259279Selan {
36359279Selan   register tree t1 = type1;
36459279Selan   register tree t2 = type2;
36559279Selan 
36659279Selan   /* Suppress errors caused by previously reported errors.  */
36759279Selan 
36859279Selan   if (t1 == t2 || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
36959279Selan     return 1;
37059279Selan 
37159279Selan   /* Treat an enum type as the unsigned integer type of the same width.  */
37259279Selan 
37359279Selan   if (TREE_CODE (t1) == ENUMERAL_TYPE)
37459279Selan     t1 = type_for_size (TYPE_PRECISION (t1), 1);
37559279Selan   if (TREE_CODE (t2) == ENUMERAL_TYPE)
37659279Selan     t2 = type_for_size (TYPE_PRECISION (t2), 1);
37759279Selan 
37859279Selan   if (t1 == t2)
37959279Selan     return 1;
38059279Selan 
38159279Selan   /* Different classes of types can't be compatible.  */
38259279Selan 
38359279Selan   if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
38459279Selan 
38559279Selan   /* Qualifiers must match.  */
38659279Selan 
38759279Selan   if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
38859279Selan     return 0;
38959279Selan   if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
39059279Selan     return 0;
39159279Selan 
39259279Selan   /* If generating auxiliary info, allow for two different type nodes which
39359279Selan      have essentially the same definition.  */
39459279Selan 
39559279Selan   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
39659279Selan     return 1;
39759279Selan 
39859279Selan   switch (TREE_CODE (t1))
39959279Selan     {
40059279Selan     case POINTER_TYPE:
40159279Selan       return (TREE_TYPE (t1) == TREE_TYPE (t2)
40259279Selan 	      ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
40359279Selan 
40459279Selan     case FUNCTION_TYPE:
40559279Selan       return function_types_compatible_p (t1, t2);
40659279Selan 
40759279Selan     case ARRAY_TYPE:
40859279Selan       {
40959279Selan 	/* 1 if no need for warning yet, 2 if warning cause has been seen.  */
41059279Selan 	int val = 1;
41159279Selan 	tree d1 = TYPE_DOMAIN (t1);
41259279Selan 	tree d2 = TYPE_DOMAIN (t2);
41359279Selan 
41459279Selan 	/* Target types must match incl. qualifiers.  */
41559279Selan 	if (TREE_TYPE (t1) != TREE_TYPE (t2)
41659279Selan 	    && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
41759279Selan 	  return 0;
41859279Selan 
41959279Selan 	/* Sizes must match unless one is missing or variable.  */
42059279Selan 	if (d1 == 0 || d2 == 0 || d1 == d2
42159279Selan 	    || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
42259279Selan 	    || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
42359279Selan 	    || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST
42459279Selan 	    || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
42559279Selan 	  return val;
42659279Selan 
42759279Selan 	return (((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
42859279Selan 		  == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
42959279Selan 		 && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
43059279Selan 		     == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
43159279Selan 		 && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
43259279Selan 		     == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
43359279Selan 		 && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
43459279Selan 		     == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))))
43559279Selan 		? val : 0);
43659279Selan       }
43759279Selan 
43859279Selan     case RECORD_TYPE:
43959279Selan       return maybe_objc_comptypes (t1, t2);
44059279Selan     }
44159279Selan   return 0;
44259279Selan }
44359279Selan 
44459279Selan /* Return 1 if TTL and TTR are pointers to types that are equivalent,
44559279Selan    ignoring their qualifiers.  */
44659279Selan 
44759279Selan static int
comp_target_types(ttl,ttr)44859279Selan comp_target_types (ttl, ttr)
44959279Selan      tree ttl, ttr;
45059279Selan {
45159279Selan   int val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
45259279Selan 		       TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
45359279Selan   if (val == 2 && pedantic)
45459279Selan     pedwarn ("types are not quite compatible");
45559279Selan   return val;
45659279Selan }
45759279Selan 
45859279Selan /* Subroutines of `comptypes'.  */
45959279Selan 
46059279Selan /* Return 1 if two function types F1 and F2 are compatible.
46159279Selan    If either type specifies no argument types,
46259279Selan    the other must specify a fixed number of self-promoting arg types.
46359279Selan    Otherwise, if one type specifies only the number of arguments,
46459279Selan    the other must specify that number of self-promoting arg types.
46559279Selan    Otherwise, the argument types must match.  */
46659279Selan 
46759279Selan static int
function_types_compatible_p(f1,f2)46859279Selan function_types_compatible_p (f1, f2)
46959279Selan      tree f1, f2;
47059279Selan {
47159279Selan   tree args1, args2;
47259279Selan   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
47359279Selan   int val = 1;
47459279Selan   int val1;
47559279Selan 
47659279Selan   if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
47759279Selan 	|| (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
47859279Selan     return 0;
47959279Selan 
48059279Selan   args1 = TYPE_ARG_TYPES (f1);
48159279Selan   args2 = TYPE_ARG_TYPES (f2);
48259279Selan 
48359279Selan   /* An unspecified parmlist matches any specified parmlist
48459279Selan      whose argument types don't need default promotions.  */
48559279Selan 
48659279Selan   if (args1 == 0)
48759279Selan     {
48859279Selan       if (!self_promoting_args_p (args2))
48959279Selan 	return 0;
49059279Selan       /* If one of these types comes from a non-prototype fn definition,
49159279Selan 	 compare that with the other type's arglist.
49259279Selan 	 If they don't match, ask for a warning (but no error).  */
49359279Selan       if (TYPE_ACTUAL_ARG_TYPES (f1)
49459279Selan 	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
49559279Selan 	val = 2;
49659279Selan       return val;
49759279Selan     }
49859279Selan   if (args2 == 0)
49959279Selan     {
50059279Selan       if (!self_promoting_args_p (args1))
50159279Selan 	return 0;
50259279Selan       if (TYPE_ACTUAL_ARG_TYPES (f2)
50359279Selan 	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
50459279Selan 	val = 2;
50559279Selan       return val;
50659279Selan     }
50759279Selan 
50859279Selan   /* Both types have argument lists: compare them and propagate results.  */
50959279Selan   val1 = type_lists_compatible_p (args1, args2);
51059279Selan   return val1 != 1 ? val1 : val;
51159279Selan }
51259279Selan 
51359279Selan /* Check two lists of types for compatibility,
51459279Selan    returning 0 for incompatible, 1 for compatible,
51559279Selan    or 2 for compatible with warning.  */
51659279Selan 
51759279Selan static int
type_lists_compatible_p(args1,args2)51859279Selan type_lists_compatible_p (args1, args2)
51959279Selan      tree args1, args2;
52059279Selan {
52159279Selan   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
52259279Selan   int val = 1;
52359279Selan   int newval;
52459279Selan 
52559279Selan   while (1)
52659279Selan     {
52759279Selan       if (args1 == 0 && args2 == 0)
52859279Selan 	return val;
52959279Selan       /* If one list is shorter than the other,
53059279Selan 	 they fail to match.  */
53159279Selan       if (args1 == 0 || args2 == 0)
53259279Selan 	return 0;
53359279Selan       /* A null pointer instead of a type
53459279Selan 	 means there is supposed to be an argument
53559279Selan 	 but nothing is specified about what type it has.
53659279Selan 	 So match anything that self-promotes.  */
53759279Selan       if (TREE_VALUE (args1) == 0)
53859279Selan 	{
53959279Selan 	  if (! self_promoting_type_p (TREE_VALUE (args2)))
54059279Selan 	    return 0;
54159279Selan 	}
54259279Selan       else if (TREE_VALUE (args2) == 0)
54359279Selan 	{
54459279Selan 	  if (! self_promoting_type_p (TREE_VALUE (args1)))
54559279Selan 	    return 0;
54659279Selan 	}
54759279Selan       else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
54859279Selan 	{
54959279Selan 	  /* Allow  wait (union {union wait *u; int *i} *)
55059279Selan 	     and  wait (union wait *)  to be compatible.  */
55159279Selan 	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
55259279Selan 	      && TYPE_NAME (TREE_VALUE (args1)) == 0
55359279Selan 	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
55459279Selan 	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
55559279Selan 				     TYPE_SIZE (TREE_VALUE (args2))))
55659279Selan 	    {
55759279Selan 	      tree memb;
55859279Selan 	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));
55959279Selan 		   memb; memb = TREE_CHAIN (memb))
56059279Selan 		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
56159279Selan 		  break;
56259279Selan 	      if (memb == 0)
56359279Selan 		return 0;
56459279Selan 	    }
56559279Selan 	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
56659279Selan 		   && TYPE_NAME (TREE_VALUE (args2)) == 0
56759279Selan 		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
56859279Selan 		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
56959279Selan 					  TYPE_SIZE (TREE_VALUE (args1))))
57059279Selan 	    {
57159279Selan 	      tree memb;
57259279Selan 	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));
57359279Selan 		   memb; memb = TREE_CHAIN (memb))
57459279Selan 		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
57559279Selan 		  break;
57659279Selan 	      if (memb == 0)
57759279Selan 		return 0;
57859279Selan 	    }
57959279Selan 	  else
58059279Selan 	    return 0;
58159279Selan 	}
58259279Selan 
58359279Selan       /* comptypes said ok, but record if it said to warn.  */
58459279Selan       if (newval > val)
58559279Selan 	val = newval;
58659279Selan 
58759279Selan       args1 = TREE_CHAIN (args1);
58859279Selan       args2 = TREE_CHAIN (args2);
58959279Selan     }
59059279Selan }
59159279Selan 
59259279Selan /* Return 1 if PARMS specifies a fixed number of parameters
59359279Selan    and none of their types is affected by default promotions.  */
59459279Selan 
59559279Selan int
self_promoting_args_p(parms)59659279Selan self_promoting_args_p (parms)
59759279Selan      tree parms;
59859279Selan {
59959279Selan   register tree t;
60059279Selan   for (t = parms; t; t = TREE_CHAIN (t))
60159279Selan     {
60259279Selan       register tree type = TREE_VALUE (t);
60359279Selan 
60459279Selan       if (TREE_CHAIN (t) == 0 && type != void_type_node)
60559279Selan 	return 0;
60659279Selan 
60759279Selan       if (type == 0)
60859279Selan 	return 0;
60959279Selan 
61059279Selan       if (TYPE_MAIN_VARIANT (type) == float_type_node)
61159279Selan 	return 0;
61259279Selan 
61359279Selan       if (C_PROMOTING_INTEGER_TYPE_P (type))
61459279Selan 	return 0;
61559279Selan     }
61659279Selan   return 1;
61759279Selan }
61859279Selan 
61959279Selan /* Return 1 if TYPE is not affected by default promotions.  */
62059279Selan 
62159279Selan static int
self_promoting_type_p(type)62259279Selan self_promoting_type_p (type)
62359279Selan      tree type;
62459279Selan {
62559279Selan   if (TYPE_MAIN_VARIANT (type) == float_type_node)
62659279Selan     return 0;
62759279Selan 
62859279Selan   if (C_PROMOTING_INTEGER_TYPE_P (type))
62959279Selan     return 0;
63059279Selan 
63159279Selan   return 1;
63259279Selan }
63359279Selan 
63459279Selan /* Return an unsigned type the same as TYPE in other respects.  */
63559279Selan 
63659279Selan tree
unsigned_type(type)63759279Selan unsigned_type (type)
63859279Selan      tree type;
63959279Selan {
64059279Selan   tree type1 = TYPE_MAIN_VARIANT (type);
64159279Selan   if (type1 == signed_char_type_node || type1 == char_type_node)
64259279Selan     return unsigned_char_type_node;
64359279Selan   if (type1 == integer_type_node)
64459279Selan     return unsigned_type_node;
64559279Selan   if (type1 == short_integer_type_node)
64659279Selan     return short_unsigned_type_node;
64759279Selan   if (type1 == long_integer_type_node)
64859279Selan     return long_unsigned_type_node;
64959279Selan   if (type1 == long_long_integer_type_node)
65059279Selan     return long_long_unsigned_type_node;
65159279Selan   return type;
65259279Selan }
65359279Selan 
65459279Selan /* Return a signed type the same as TYPE in other respects.  */
65559279Selan 
65659279Selan tree
signed_type(type)65759279Selan signed_type (type)
65859279Selan      tree type;
65959279Selan {
66059279Selan   tree type1 = TYPE_MAIN_VARIANT (type);
66159279Selan   if (type1 == unsigned_char_type_node || type1 == char_type_node)
66259279Selan     return signed_char_type_node;
66359279Selan   if (type1 == unsigned_type_node)
66459279Selan     return integer_type_node;
66559279Selan   if (type1 == short_unsigned_type_node)
66659279Selan     return short_integer_type_node;
66759279Selan   if (type1 == long_unsigned_type_node)
66859279Selan     return long_integer_type_node;
66959279Selan   if (type1 == long_long_unsigned_type_node)
67059279Selan     return long_long_integer_type_node;
67159279Selan   return type;
67259279Selan }
67359279Selan 
67459279Selan /* Return a type the same as TYPE except unsigned or
67559279Selan    signed according to UNSIGNEDP.  */
67659279Selan 
67759279Selan tree
signed_or_unsigned_type(unsignedp,type)67859279Selan signed_or_unsigned_type (unsignedp, type)
67959279Selan      int unsignedp;
68059279Selan      tree type;
68159279Selan {
68259279Selan   if (TREE_CODE (type) != INTEGER_TYPE)
68359279Selan     return type;
68459279Selan   if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
68559279Selan     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
68659279Selan   if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
68759279Selan     return unsignedp ? unsigned_type_node : integer_type_node;
68859279Selan   if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
68959279Selan     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
69059279Selan   if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
69159279Selan     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
69259279Selan   if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
69359279Selan     return (unsignedp ? long_long_unsigned_type_node
69459279Selan 	    : long_long_integer_type_node);
69559279Selan   return type;
69659279Selan }
69759279Selan 
69859279Selan /* Compute the value of the `sizeof' operator.  */
69959279Selan 
70059279Selan tree
c_sizeof(type)70159279Selan c_sizeof (type)
70259279Selan      tree type;
70359279Selan {
70459279Selan   enum tree_code code = TREE_CODE (type);
70559279Selan 
70659279Selan   if (code == FUNCTION_TYPE)
70759279Selan     {
70859279Selan       if (pedantic || warn_pointer_arith)
70959279Selan 	pedwarn ("sizeof applied to a function type");
71059279Selan       return size_int (1);
71159279Selan     }
71259279Selan   if (code == VOID_TYPE)
71359279Selan     {
71459279Selan       if (pedantic || warn_pointer_arith)
71559279Selan 	pedwarn ("sizeof applied to a void type");
71659279Selan       return size_int (1);
71759279Selan     }
71859279Selan   if (code == ERROR_MARK)
71959279Selan     return size_int (1);
72059279Selan   if (TYPE_SIZE (type) == 0)
72159279Selan     {
72259279Selan       error ("sizeof applied to an incomplete type");
72359279Selan       return size_int (0);
72459279Selan     }
72559279Selan 
72659279Selan   /* Convert in case a char is more than one unit.  */
72759279Selan   return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
72859279Selan 		     size_int (TYPE_PRECISION (char_type_node)));
72959279Selan }
73059279Selan 
73159279Selan tree
c_sizeof_nowarn(type)73259279Selan c_sizeof_nowarn (type)
73359279Selan      tree type;
73459279Selan {
73559279Selan   enum tree_code code = TREE_CODE (type);
73659279Selan 
73759279Selan   if (code == FUNCTION_TYPE
73859279Selan       || code == VOID_TYPE
73959279Selan       || code == ERROR_MARK)
74059279Selan     return size_int (1);
74159279Selan   if (TYPE_SIZE (type) == 0)
74259279Selan     return size_int (0);
74359279Selan 
74459279Selan   /* Convert in case a char is more than one unit.  */
74559279Selan   return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
74659279Selan 		     size_int (TYPE_PRECISION (char_type_node)));
74759279Selan }
74859279Selan 
74959279Selan /* Compute the size to increment a pointer by.  */
75059279Selan 
75159279Selan tree
c_size_in_bytes(type)75259279Selan c_size_in_bytes (type)
75359279Selan      tree type;
75459279Selan {
75559279Selan   enum tree_code code = TREE_CODE (type);
75659279Selan 
75759279Selan   if (code == FUNCTION_TYPE)
75859279Selan     return size_int (1);
75959279Selan   if (code == VOID_TYPE)
76059279Selan     return size_int (1);
76159279Selan   if (code == ERROR_MARK)
76259279Selan     return size_int (1);
76359279Selan   if (TYPE_SIZE (type) == 0)
76459279Selan     {
76559279Selan       error ("arithmetic on pointer to an incomplete type");
76659279Selan       return size_int (1);
76759279Selan     }
76859279Selan 
76959279Selan   /* Convert in case a char is more than one unit.  */
77059279Selan   return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
77159279Selan 		     size_int (BITS_PER_UNIT));
77259279Selan }
77359279Selan 
77459279Selan /* Implement the __alignof keyword: Return the minimum required
77559279Selan    alignment of TYPE, measured in bytes.  */
77659279Selan 
77759279Selan tree
c_alignof(type)77859279Selan c_alignof (type)
77959279Selan      tree type;
78059279Selan {
78159279Selan   enum tree_code code = TREE_CODE (type);
78259279Selan 
78359279Selan   if (code == FUNCTION_TYPE)
78459279Selan     return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
78559279Selan 
78659279Selan   if (code == VOID_TYPE || code == ERROR_MARK)
78759279Selan     return size_int (1);
78859279Selan 
78959279Selan   return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
79059279Selan }
79159279Selan 
79259279Selan /* Implement the __alignof keyword: Return the minimum required
79359279Selan    alignment of EXPR, measured in bytes.  For VAR_DECL's and
79459279Selan    FIELD_DECL's return DECL_ALIGN (which can be set from an
79559279Selan    "aligned" __attribute__ specification).  */
79659279Selan 
79759279Selan tree
c_alignof_expr(expr)79859279Selan c_alignof_expr (expr)
79959279Selan      tree expr;
80059279Selan {
80159279Selan   if (TREE_CODE (expr) == VAR_DECL)
80259279Selan     return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
80359279Selan 
80459279Selan   if (TREE_CODE (expr) == COMPONENT_REF
80559279Selan       && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
80659279Selan     {
80759279Selan       error ("`__alignof' applied to a bit-field");
80859279Selan       return size_int (1);
80959279Selan     }
81059279Selan   else if (TREE_CODE (expr) == COMPONENT_REF
81159279Selan       && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
81259279Selan     return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
81359279Selan 
81459279Selan   if (TREE_CODE (expr) == INDIRECT_REF)
81559279Selan     {
81659279Selan       tree t = TREE_OPERAND (expr, 0);
81759279Selan       tree best = t;
81859279Selan       int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
81959279Selan 
82059279Selan       while (TREE_CODE (t) == NOP_EXPR
82159279Selan 	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
82259279Selan 	{
82359279Selan 	  int thisalign;
82459279Selan 
82559279Selan 	  t = TREE_OPERAND (t, 0);
82659279Selan 	  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
82759279Selan 	  if (thisalign > bestalign)
82859279Selan 	    best = t, bestalign = thisalign;
82959279Selan 	}
83059279Selan       return c_alignof (TREE_TYPE (TREE_TYPE (best)));
83159279Selan     }
83259279Selan   else
83359279Selan     return c_alignof (TREE_TYPE (expr));
83459279Selan }
83559279Selan /* Return either DECL or its known constant value (if it has one).  */
83659279Selan 
83759279Selan static tree
decl_constant_value(decl)83859279Selan decl_constant_value (decl)
83959279Selan      tree decl;
84059279Selan {
84159279Selan   if (! TREE_PUBLIC (decl)
84259279Selan       /* Don't change a variable array bound or initial value to a constant
84359279Selan 	 in a place where a variable is invalid.  */
84459279Selan       && current_function_decl != 0
84559279Selan       && ! pedantic
84659279Selan       && ! TREE_THIS_VOLATILE (decl)
84759279Selan       && DECL_INITIAL (decl) != 0
84859279Selan       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
84959279Selan       /* This is invalid if initial value is not constant.
85059279Selan 	 If it has either a function call, a memory reference,
85159279Selan 	 or a variable, then re-evaluating it could give different results.  */
85259279Selan       && TREE_CONSTANT (DECL_INITIAL (decl))
85359279Selan       /* Check for cases where this is sub-optimal, even though valid.  */
85459279Selan       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
85559279Selan       && DECL_MODE (decl) != BLKmode)
85659279Selan     return DECL_INITIAL (decl);
85759279Selan   return decl;
85859279Selan }
85959279Selan 
86059279Selan /* Perform default promotions for C data used in expressions.
86159279Selan    Arrays and functions are converted to pointers;
86259279Selan    enumeral types or short or char, to int.
86359279Selan    In addition, manifest constants symbols are replaced by their values.  */
86459279Selan 
86559279Selan tree
default_conversion(exp)86659279Selan default_conversion (exp)
86759279Selan      tree exp;
86859279Selan {
86959279Selan   register tree type = TREE_TYPE (exp);
87059279Selan   register enum tree_code code = TREE_CODE (type);
87159279Selan 
87259279Selan   /* Constants can be used directly unless they're not loadable.  */
87359279Selan   if (TREE_CODE (exp) == CONST_DECL)
87459279Selan     exp = DECL_INITIAL (exp);
87559279Selan   /* Replace a nonvolatile const static variable with its value.  */
87659279Selan   else if (optimize
87759279Selan 	   && TREE_CODE (exp) == VAR_DECL
87859279Selan 	   && TREE_READONLY (exp)
87959279Selan 	   && DECL_MODE (exp) != BLKmode)
88059279Selan     {
88159279Selan       exp = decl_constant_value (exp);
88259279Selan       type = TREE_TYPE (exp);
88359279Selan     }
88459279Selan 
88559279Selan   /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
88659279Selan      an lvalue.  */
88759279Selan   /* Do not use STRIP_NOPS here!  It will remove conversions from pointer
88859279Selan      to integer and cause infinite recursion.  */
88959279Selan   while (TREE_CODE (exp) == NON_LVALUE_EXPR
89059279Selan 	 || (TREE_CODE (exp) == NOP_EXPR
89159279Selan 	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
89259279Selan     exp = TREE_OPERAND (exp, 0);
89359279Selan 
89459279Selan   /* Normally convert enums to int,
89559279Selan      but convert wide enums to something wider.  */
89659279Selan   if (code == ENUMERAL_TYPE)
89759279Selan     {
89859279Selan       type = type_for_size (MAX (TYPE_PRECISION (type),
89959279Selan 				 TYPE_PRECISION (integer_type_node)),
90059279Selan 			    (flag_traditional && TREE_UNSIGNED (type)));
90159279Selan       return convert (type, exp);
90259279Selan     }
90359279Selan 
90459279Selan   if (C_PROMOTING_INTEGER_TYPE_P (type))
90559279Selan     {
90659279Selan       /* Traditionally, unsignedness is preserved in default promotions.
90759279Selan          Also preserve unsignedness if not really getting any wider.  */
90859279Selan       if (TREE_UNSIGNED (type)
90959279Selan 	  && (flag_traditional
91059279Selan 	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
91159279Selan 	return convert (unsigned_type_node, exp);
91259279Selan       return convert (integer_type_node, exp);
91359279Selan     }
91459279Selan   if (flag_traditional && TYPE_MAIN_VARIANT (type) == float_type_node)
91559279Selan     return convert (double_type_node, exp);
91659279Selan   if (code == VOID_TYPE)
91759279Selan     {
91859279Selan       error ("void value not ignored as it ought to be");
91959279Selan       return error_mark_node;
92059279Selan     }
92159279Selan   if (code == FUNCTION_TYPE)
92259279Selan     {
92359279Selan       return build_unary_op (ADDR_EXPR, exp, 0);
92459279Selan     }
92559279Selan   if (code == ARRAY_TYPE)
92659279Selan     {
92759279Selan       register tree adr;
92859279Selan       tree restype = TREE_TYPE (type);
92959279Selan       tree ptrtype;
93059279Selan 
93159279Selan       if (TREE_CODE (exp) == INDIRECT_REF)
93259279Selan 	return convert (TYPE_POINTER_TO (restype),
93359279Selan 			TREE_OPERAND (exp, 0));
93459279Selan 
93559279Selan       if (TREE_CODE (exp) == COMPOUND_EXPR)
93659279Selan 	{
93759279Selan 	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));
93859279Selan 	  return build (COMPOUND_EXPR, TREE_TYPE (op1),
93959279Selan 			TREE_OPERAND (exp, 0), op1);
94059279Selan 	}
94159279Selan 
94259279Selan       if (!lvalue_p (exp)
94359279Selan 	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
94459279Selan 	{
94559279Selan 	  error ("invalid use of non-lvalue array");
94659279Selan 	  return error_mark_node;
94759279Selan 	}
94859279Selan 
94959279Selan       if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
95059279Selan 	restype = c_build_type_variant (restype, TYPE_READONLY (type),
95159279Selan 					TYPE_VOLATILE (type));
95259279Selan 
95359279Selan       ptrtype = build_pointer_type (restype);
95459279Selan 
95559279Selan       if (TREE_CODE (exp) == VAR_DECL)
95659279Selan 	{
95759279Selan 	  /* ??? This is not really quite correct
95859279Selan 	     in that the type of the operand of ADDR_EXPR
95959279Selan 	     is not the target type of the type of the ADDR_EXPR itself.
96059279Selan 	     Question is, can this lossage be avoided?  */
96159279Selan 	  adr = build1 (ADDR_EXPR, ptrtype, exp);
96259279Selan 	  if (mark_addressable (exp) == 0)
96359279Selan 	    return error_mark_node;
96459279Selan 	  TREE_CONSTANT (adr) = staticp (exp);
96559279Selan 	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
96659279Selan 	  return adr;
96759279Selan 	}
96859279Selan       /* This way is better for a COMPONENT_REF since it can
96959279Selan 	 simplify the offset for a component.  */
97059279Selan       adr = build_unary_op (ADDR_EXPR, exp, 1);
97159279Selan       return convert (ptrtype, adr);
97259279Selan     }
97359279Selan   return exp;
97459279Selan }
97559279Selan 
97659279Selan /* Make an expression to refer to the COMPONENT field of
97759279Selan    structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
97859279Selan 
97959279Selan tree
build_component_ref(datum,component)98059279Selan build_component_ref (datum, component)
98159279Selan      tree datum, component;
98259279Selan {
98359279Selan   register tree type = TREE_TYPE (datum);
98459279Selan   register enum tree_code code = TREE_CODE (type);
98559279Selan   register tree field = NULL;
98659279Selan   register tree ref;
98759279Selan 
98859279Selan   /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it
98959279Selan      unless we are not to support things not strictly ANSI.  */
99059279Selan   switch (TREE_CODE (datum))
99159279Selan     {
99259279Selan     case COMPOUND_EXPR:
99359279Selan       {
99459279Selan 	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
99559279Selan 	return build (COMPOUND_EXPR, TREE_TYPE (value),
99659279Selan 		      TREE_OPERAND (datum, 0), value);
99759279Selan       }
99859279Selan     case COND_EXPR:
99959279Selan       return build_conditional_expr
100059279Selan 	(TREE_OPERAND (datum, 0),
100159279Selan 	 build_component_ref (TREE_OPERAND (datum, 1), component),
100259279Selan 	 build_component_ref (TREE_OPERAND (datum, 2), component));
100359279Selan     }
100459279Selan 
100559279Selan   /* See if there is a field or component with name COMPONENT.  */
100659279Selan 
100759279Selan   if (code == RECORD_TYPE || code == UNION_TYPE)
100859279Selan     {
100959279Selan       if (TYPE_SIZE (type) == 0)
101059279Selan 	{
101159279Selan 	  incomplete_type_error (NULL_TREE, type);
101259279Selan 	  return error_mark_node;
101359279Selan 	}
101459279Selan 
101559279Selan       /* Look up component name in the structure type definition.
101659279Selan 
101759279Selan 	 If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
101859279Selan 	 to the field elements.  Use a binary search on this array to quickly
101959279Selan 	 find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC
102059279Selan 	 will always be set for structures which have many elements.  */
102159279Selan 
102259279Selan       if (TYPE_LANG_SPECIFIC (type))
102359279Selan 	{
102459279Selan 	  int bot, top, half;
102559279Selan 	  tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];
102659279Selan 
102759279Selan 	  field = TYPE_FIELDS (type);
102859279Selan 	  bot = 0;
102959279Selan 	  top = TYPE_LANG_SPECIFIC (type)->len;
103059279Selan 	  while (top - bot > 1)
103159279Selan 	    {
103259279Selan 	      int cmp;
103359279Selan 
103459279Selan 	      half = (top - bot + 1) >> 1;
103559279Selan 	      field = field_array[bot+half];
103659279Selan 	      cmp = (long)DECL_NAME (field) - (long)component;
103759279Selan 	      if (cmp == 0)
103859279Selan 		break;
103959279Selan 	      if (cmp < 0)
104059279Selan 		bot += half;
104159279Selan 	      else
104259279Selan 		top = bot + half;
104359279Selan 	    }
104459279Selan 
104559279Selan 	  if (DECL_NAME (field_array[bot]) == component)
104659279Selan 	    field = field_array[bot];
104759279Selan 	  else if (DECL_NAME (field) != component)
104859279Selan 	    field = 0;
104959279Selan 	}
105059279Selan       else
105159279Selan 	{
105259279Selan 	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
105359279Selan 	    {
105459279Selan 	      if (DECL_NAME (field) == component)
105559279Selan 		break;
105659279Selan 	    }
105759279Selan 	}
105859279Selan 
105959279Selan       if (!field)
106059279Selan 	{
106159279Selan 	  error (code == RECORD_TYPE
106259279Selan 		 ? "structure has no member named `%s'"
106359279Selan 		 : "union has no member named `%s'",
106459279Selan 		 IDENTIFIER_POINTER (component));
106559279Selan 	  return error_mark_node;
106659279Selan 	}
106759279Selan       if (TREE_TYPE (field) == error_mark_node)
106859279Selan 	return error_mark_node;
106959279Selan 
107059279Selan       ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field);
107159279Selan 
107259279Selan       if (TREE_READONLY (datum) || TREE_READONLY (field))
107359279Selan 	TREE_READONLY (ref) = 1;
107459279Selan       if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
107559279Selan 	TREE_THIS_VOLATILE (ref) = 1;
107659279Selan 
107759279Selan       return ref;
107859279Selan     }
107959279Selan   else if (code != ERROR_MARK)
108059279Selan     error ("request for member `%s' in something not a structure or union",
108159279Selan 	    IDENTIFIER_POINTER (component));
108259279Selan 
108359279Selan   return error_mark_node;
108459279Selan }
108559279Selan 
108659279Selan /* Given an expression PTR for a pointer, return an expression
108759279Selan    for the value pointed to.
108859279Selan    ERRORSTRING is the name of the operator to appear in error messages.  */
108959279Selan 
109059279Selan tree
build_indirect_ref(ptr,errorstring)109159279Selan build_indirect_ref (ptr, errorstring)
109259279Selan      tree ptr;
109359279Selan      char *errorstring;
109459279Selan {
109559279Selan   register tree pointer = default_conversion (ptr);
109659279Selan   register tree type = TREE_TYPE (pointer);
109759279Selan 
109859279Selan   if (TREE_CODE (type) == POINTER_TYPE)
109959279Selan     if (TREE_CODE (pointer) == ADDR_EXPR
110059279Selan 	&& (TREE_TYPE (TREE_OPERAND (pointer, 0))
110159279Selan 	    == TREE_TYPE (type)))
110259279Selan       return TREE_OPERAND (pointer, 0);
110359279Selan     else
110459279Selan       {
110559279Selan 	tree t = TREE_TYPE (type);
110659279Selan 	register tree ref = build1 (INDIRECT_REF,
110759279Selan 				    TYPE_MAIN_VARIANT (t), pointer);
110859279Selan 
110959279Selan 	if (TREE_CODE (t) == VOID_TYPE
111059279Selan 	    || (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE))
111159279Selan 	  {
111259279Selan 	    error ("dereferencing pointer to incomplete type");
111359279Selan 	    return error_mark_node;
111459279Selan 	  }
111559279Selan 
111659279Selan 	/* We *must* set TREE_READONLY when dereferencing a pointer to const,
111759279Selan 	   so that we get the proper error message if the result is used
111859279Selan 	   to assign to.  Also, &* is supposed to be a no-op.
111959279Selan 	   And ANSI C seems to specify that the type of the result
112059279Selan 	   should be the const type.  */
112159279Selan 	/* A de-reference of a pointer to const is not a const.  It is valid
112259279Selan 	   to change it via some other pointer.  */
112359279Selan 	TREE_READONLY (ref) = TYPE_READONLY (t);
112459279Selan 	TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
112559279Selan 	TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
112659279Selan 	return ref;
112759279Selan       }
112859279Selan   else if (TREE_CODE (pointer) != ERROR_MARK)
112959279Selan     error ("invalid type argument of `%s'", errorstring);
113059279Selan   return error_mark_node;
113159279Selan }
113259279Selan 
113359279Selan /* This handles expressions of the form "a[i]", which denotes
113459279Selan    an array reference.
113559279Selan 
113659279Selan    This is logically equivalent in C to *(a+i), but we may do it differently.
113759279Selan    If A is a variable or a member, we generate a primitive ARRAY_REF.
113859279Selan    This avoids forcing the array out of registers, and can work on
113959279Selan    arrays that are not lvalues (for example, members of structures returned
114059279Selan    by functions).  */
114159279Selan 
114259279Selan tree
build_array_ref(array,index)114359279Selan build_array_ref (array, index)
114459279Selan      tree array, index;
114559279Selan {
114659279Selan   if (index == 0)
114759279Selan     {
114859279Selan       error ("subscript missing in array reference");
114959279Selan       return error_mark_node;
115059279Selan     }
115159279Selan 
115259279Selan   if (TREE_TYPE (array) == error_mark_node
115359279Selan       || TREE_TYPE (index) == error_mark_node)
115459279Selan     return error_mark_node;
115559279Selan 
115659279Selan   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
115759279Selan       && TREE_CODE (array) != INDIRECT_REF)
115859279Selan     {
115959279Selan       tree rval, type;
116059279Selan 
116159279Selan       /* Subscripting with type char is likely to lose
116259279Selan 	 on a machine where chars are signed.
116359279Selan 	 So warn on any machine, but optionally.
116459279Selan 	 Don't warn for unsigned char since that type is safe.
116559279Selan 	 Don't warn for signed char because anyone who uses that
116659279Selan 	 must have done so deliberately.  */
116759279Selan       if (warn_char_subscripts
116859279Selan 	  && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
116959279Selan 	warning ("array subscript has type `char'");
117059279Selan 
117159279Selan       /* Apply default promotions *after* noticing character types.  */
117259279Selan       index = default_conversion (index);
117359279Selan 
117459279Selan       /* Require integer *after* promotion, for sake of enums.  */
117559279Selan       if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
117659279Selan 	{
117759279Selan 	  error ("array subscript is not an integer");
117859279Selan 	  return error_mark_node;
117959279Selan 	}
118059279Selan 
118159279Selan       /* An array that is indexed by a non-constant
118259279Selan 	 cannot be stored in a register; we must be able to do
118359279Selan 	 address arithmetic on its address.
118459279Selan 	 Likewise an array of elements of variable size.  */
118559279Selan       if (TREE_CODE (index) != INTEGER_CST
118659279Selan 	  || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
118759279Selan 	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
118859279Selan 	{
118959279Selan 	  if (mark_addressable (array) == 0)
119059279Selan 	    return error_mark_node;
119159279Selan 	}
119259279Selan 
119359279Selan       if (pedantic && !lvalue_p (array))
119459279Selan 	{
119559279Selan 	  if (DECL_REGISTER (array))
119659279Selan 	    pedwarn ("ANSI C forbids subscripting `register' array");
119759279Selan 	  else
119859279Selan 	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
119959279Selan 	}
120059279Selan 
120159279Selan       if (pedantic)
120259279Selan 	{
120359279Selan 	  tree foo = array;
120459279Selan 	  while (TREE_CODE (foo) == COMPONENT_REF)
120559279Selan 	    foo = TREE_OPERAND (foo, 0);
120659279Selan 	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
120759279Selan 	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
120859279Selan 	}
120959279Selan 
121059279Selan       type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
121159279Selan       rval = build (ARRAY_REF, type, array, index);
121259279Selan       /* Array ref is const/volatile if the array elements are
121359279Selan          or if the array is.  */
121459279Selan       TREE_READONLY (rval)
121559279Selan 	|= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
121659279Selan 	    | TREE_READONLY (array));
121759279Selan       TREE_SIDE_EFFECTS (rval)
121859279Selan 	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
121959279Selan 	    | TREE_SIDE_EFFECTS (array));
122059279Selan       TREE_THIS_VOLATILE (rval)
122159279Selan 	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
122259279Selan 	    /* This was added by rms on 16 Nov 91.
122359279Selan 	       It fixes  vol struct foo *a;  a->elts[1]
122459279Selan 	       in an inline function.
122559279Selan 	       Hope it doesn't break something else.  */
122659279Selan 	    | TREE_THIS_VOLATILE (array));
122759279Selan       return require_complete_type (fold (rval));
122859279Selan     }
122959279Selan 
123059279Selan   {
123159279Selan     tree ar = default_conversion (array);
123259279Selan     tree ind = default_conversion (index);
123359279Selan 
123459279Selan     /* Put the integer in IND to simplify error checking.  */
123559279Selan     if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
123659279Selan       {
123759279Selan 	tree temp = ar;
123859279Selan 	ar = ind;
123959279Selan 	ind = temp;
124059279Selan       }
124159279Selan 
124259279Selan     if (ar == error_mark_node)
124359279Selan       return ar;
124459279Selan 
124559279Selan     if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
124659279Selan       {
124759279Selan 	error ("subscripted value is neither array nor pointer");
124859279Selan 	return error_mark_node;
124959279Selan       }
125059279Selan     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
125159279Selan       {
125259279Selan 	error ("array subscript is not an integer");
125359279Selan 	return error_mark_node;
125459279Selan       }
125559279Selan 
125659279Selan     return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
125759279Selan 			       "array indexing");
125859279Selan   }
125959279Selan }
126059279Selan 
126159279Selan /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against PARAMS.  */
126259279Selan 
126359279Selan #define ISDIGIT(c)	((c) >= '0' && (c) <= '9')
126459279Selan 
126559279Selan #define T_I	&integer_type_node
126659279Selan #define T_L	&long_integer_type_node
126759279Selan #define T_S	&short_integer_type_node
126859279Selan #define T_UI	&unsigned_type_node
126959279Selan #define T_UL	&long_unsigned_type_node
127059279Selan #define T_US	&short_unsigned_type_node
127159279Selan #define T_F	&float_type_node
127259279Selan #define T_D	&double_type_node
127359279Selan #define T_LD	&long_double_type_node
127459279Selan #define T_C	&char_type_node
127559279Selan #define T_V	&void_type_node
127659279Selan #define T_W	&wchar_type_node
127759279Selan 
127859279Selan typedef struct
127959279Selan {
128059279Selan   char *format_chars;
128159279Selan   int pointer_count;
128259279Selan   /* Type of argument if no length modifier is used.  */
128359279Selan   tree *nolen;
128459279Selan   /* Type of argument if length modifier for shortening is used.
128559279Selan      If NULL, then this modifier is not allowed.  */
128659279Selan   tree *hlen;
128759279Selan   /* Type of argument if length modifier `l' is used.
128859279Selan      If NULL, then this modifier is not allowed.  */
128959279Selan   tree *llen;
129059279Selan   /* Type of argument if length modifier `L' is used.
129159279Selan      If NULL, then this modifier is not allowed.  */
129259279Selan   tree *bigllen;
129359279Selan   /* List of other modifier characters allowed with these options.  */
129459279Selan   char *flag_chars;
129559279Selan } format_char_info;
129659279Selan 
129759279Selan static format_char_info print_table[]
129859279Selan   = {
129959279Selan       { "di",		0,	T_I,	T_I,	T_L,	NULL,	"-wp0 +" },
130059279Selan       { "oxX",		0,	T_UI,	T_UI,	T_UL,	NULL,	"-wp0#" },
130159279Selan       { "u",		0,	T_UI,	T_UI,	T_UL,	NULL,	"-wp0" },
130259279Selan       { "feEgG",	0,	T_D,	NULL,	NULL,	T_LD,	"-wp0 +#" },
130359279Selan       { "c",		0,	T_I,	NULL,	T_W,	NULL,	"-w" },
130459279Selan       { "C",		0,	T_W,	NULL,	NULL,	NULL,	"-w" },
130559279Selan       { "s",		1,	T_C,	NULL,	T_W,	NULL,	"-wp" },
130659279Selan       { "S",		1,	T_W,	NULL,	NULL,	NULL,	"-wp" },
130759279Selan       { "p",		1,	T_V,	NULL,	NULL,	NULL,	"-" },
130859279Selan       { "n",		1,	T_I,	T_S,	T_L,	NULL,	"" },
130959279Selan       { NULL }
131059279Selan     };
131159279Selan 
131259279Selan static format_char_info scan_table[]
131359279Selan   = {
131459279Selan       { "di",		1,	T_I,	T_S,	T_L,	NULL,	"*" },
131559279Selan       { "ouxX",		1,	T_UI,	T_US,	T_UL,	NULL,	"*" },
131659279Selan       { "efgEG",	1,	T_F,	NULL,	T_D,	T_LD,	"*" },
131759279Selan       { "sc",		1,	T_C,	NULL,	T_W,	NULL,	"*" },
131859279Selan       { "[",		1,	T_C,	NULL,	NULL,	NULL,	"*" },
131959279Selan       { "C",		1,	T_W,	NULL,	NULL,	NULL,	"*" },
132059279Selan       { "S",		1,	T_W,	NULL,	NULL,	NULL,	"*" },
132159279Selan       { "p",		2,	T_V,	NULL,	NULL,	NULL,	"*" },
132259279Selan       { "n",		1,	T_I,	T_S,	T_L,	NULL,	"" },
132359279Selan       { NULL }
132459279Selan     };
132559279Selan 
132659279Selan typedef struct
132759279Selan {
132859279Selan   tree function_ident;		/* identifier such as "printf" */
132959279Selan   int is_scan;			/* TRUE if *scanf */
133059279Selan   int format_num;		/* number of format argument */
133159279Selan   int first_arg_num;		/* number of first arg (zero for varargs) */
133259279Selan } function_info;
133359279Selan 
133459279Selan static unsigned int function_info_entries = 0;
133559279Selan static function_info *function_info_table = NULL;
133659279Selan 
133759279Selan /* Record information for argument format checking.  FUNCTION_IDENT is
133859279Selan    the identifier node for the name of the function to check (its decl
133959279Selan    need not exist yet).  IS_SCAN is true for scanf-type format checking;
134059279Selan    false indicates printf-style format checking.  FORMAT_NUM is the number
134159279Selan    of the argument which is the format control string (starting from 1).
134259279Selan    FIRST_ARG_NUM is the number of the first actual argument to check
134359279Selan    against teh format string, or zero if no checking is not be done
134459279Selan    (e.g. for varargs such as vfprintf).  */
134559279Selan 
134659279Selan void
record_format_info(function_ident,is_scan,format_num,first_arg_num)134759279Selan record_format_info (function_ident, is_scan, format_num, first_arg_num)
134859279Selan       tree function_ident;
134959279Selan       int is_scan;
135059279Selan       int format_num;
135159279Selan       int first_arg_num;
135259279Selan {
135359279Selan   function_info *info;
135459279Selan 
135559279Selan   function_info_entries++;
135659279Selan   if (function_info_table)
135759279Selan     function_info_table
135859279Selan       = (function_info *) xrealloc (function_info_table,
135959279Selan 				    function_info_entries * sizeof (function_info));
136059279Selan   else
136159279Selan     function_info_table = (function_info *) xmalloc (sizeof (function_info));
136259279Selan 
136359279Selan   info = &function_info_table[function_info_entries - 1];
136459279Selan 
136559279Selan   info->function_ident = function_ident;
136659279Selan   info->is_scan = is_scan;
136759279Selan   info->format_num = format_num;
136859279Selan   info->first_arg_num = first_arg_num;
136959279Selan }
137059279Selan 
137159279Selan /* Initialize the table of functions to perform format checking on.
137259279Selan    The ANSI functions are always checked (whether <stdio.h> is
137359279Selan    included or not), since it is common to call printf without
137459279Selan    including <stdio.h>.  There shouldn't be a problem with this,
137559279Selan    since ANSI reserves these function names whether you include the
137659279Selan    header file or not.  In any case, the checking is harmless.  */
137759279Selan 
137859279Selan void
init_format_info_table()137959279Selan init_format_info_table ()
138059279Selan {
138159279Selan   record_format_info (get_identifier ("printf"), 0, 1, 2);
138259279Selan   record_format_info (get_identifier ("fprintf"), 0, 2, 3);
138359279Selan   record_format_info (get_identifier ("sprintf"), 0, 2, 3);
138459279Selan   record_format_info (get_identifier ("scanf"), 1, 1, 2);
138559279Selan   record_format_info (get_identifier ("fscanf"), 1, 2, 3);
138659279Selan   record_format_info (get_identifier ("sscanf"), 1, 2, 3);
138759279Selan   record_format_info (get_identifier ("vprintf"), 0, 1, 0);
138859279Selan   record_format_info (get_identifier ("vfprintf"), 0, 2, 0);
138959279Selan   record_format_info (get_identifier ("vsprintf"), 0, 2, 0);
139059279Selan }
139159279Selan 
139259279Selan static char	tfaff[] = "too few arguments for format";
139359279Selan 
139459279Selan /* Check the argument list of a call to printf, scanf, etc.
139559279Selan    INFO points to the element of function_info_table.
139659279Selan    PARAMS is the list of argument values.  */
139759279Selan 
139859279Selan static void
check_format(info,params)139959279Selan check_format (info, params)
140059279Selan      function_info *info;
140159279Selan      tree params;
140259279Selan {
140359279Selan   int i;
140459279Selan   int arg_num;
140559279Selan   int suppressed, wide, precise;
140659279Selan   int length_char;
140759279Selan   int format_char;
140859279Selan   int format_length;
140959279Selan   tree format_tree;
141059279Selan   tree cur_param;
141159279Selan   tree cur_type;
141259279Selan   tree wanted_type;
141359279Selan   char *format_chars;
141459279Selan   format_char_info *fci;
141559279Selan   static char message[132];
141659279Selan   char flag_chars[8];
141759279Selan 
141859279Selan   /* Skip to format argument.  If the argument isn't available, there's
141959279Selan      no work for us to do; prototype checking will catch the problem.  */
142059279Selan   for (arg_num = 1; ; ++arg_num)
142159279Selan     {
142259279Selan       if (params == 0)
142359279Selan 	return;
142459279Selan       if (arg_num == info->format_num)
142559279Selan 	break;
142659279Selan       params = TREE_CHAIN (params);
142759279Selan     }
142859279Selan   format_tree = TREE_VALUE (params);
142959279Selan   params = TREE_CHAIN (params);
143059279Selan   if (format_tree == 0)
143159279Selan     return;
143259279Selan   /* We can only check the format if it's a string constant.  */
143359279Selan   while (TREE_CODE (format_tree) == NOP_EXPR)
143459279Selan     format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */
143559279Selan   if (format_tree == null_pointer_node)
143659279Selan     {
143759279Selan       warning ("null format string");
143859279Selan       return;
143959279Selan     }
144059279Selan   if (TREE_CODE (format_tree) != ADDR_EXPR)
144159279Selan     return;
144259279Selan   format_tree = TREE_OPERAND (format_tree, 0);
144359279Selan   if (TREE_CODE (format_tree) != STRING_CST)
144459279Selan     return;
144559279Selan   format_chars = TREE_STRING_POINTER (format_tree);
144659279Selan   format_length = TREE_STRING_LENGTH (format_tree);
144759279Selan   if (format_length <= 1)
144859279Selan     warning ("zero-length format string");
144959279Selan   if (format_chars[--format_length] != 0)
145059279Selan     {
145159279Selan       warning ("unterminated format string");
145259279Selan       return;
145359279Selan     }
145459279Selan   /* Skip to first argument to check.  */
145559279Selan   while (arg_num + 1 < info->first_arg_num)
145659279Selan     {
145759279Selan       if (params == 0)
145859279Selan 	return;
145959279Selan       params = TREE_CHAIN (params);
146059279Selan       ++arg_num;
146159279Selan     }
146259279Selan   while (1)
146359279Selan     {
146459279Selan       if (*format_chars == 0)
146559279Selan 	{
146659279Selan 	  if (format_chars - TREE_STRING_POINTER (format_tree) != format_length)
146759279Selan 	    warning ("embedded `\\0' in format");
146859279Selan 	  if (info->first_arg_num != 0 && params != 0)
146959279Selan 	    warning ("too many arguments for format");
147059279Selan 	  return;
147159279Selan 	}
147259279Selan       if (*format_chars++ != '%')
147359279Selan 	continue;
147459279Selan       if (*format_chars == 0)
147559279Selan 	{
147659279Selan 	  warning ("spurious trailing `%%' in format");
147759279Selan 	  continue;
147859279Selan 	}
147959279Selan       if (*format_chars == '%')
148059279Selan 	{
148159279Selan 	  ++format_chars;
148259279Selan 	  continue;
148359279Selan 	}
148459279Selan       flag_chars[0] = 0;
148559279Selan       suppressed = wide = precise = FALSE;
148659279Selan       if (info->is_scan)
148759279Selan 	{
148859279Selan 	  suppressed = *format_chars == '*';
148959279Selan 	  if (suppressed)
149059279Selan 	    ++format_chars;
149159279Selan 	  while (ISDIGIT (*format_chars))
149259279Selan 	    ++format_chars;
149359279Selan 	}
149459279Selan       else
149559279Selan 	{
149659279Selan 	  while (*format_chars != 0 && index (" +#0-", *format_chars) != 0)
149759279Selan 	    {
149859279Selan 	      if (index (flag_chars, *format_chars) != 0)
149959279Selan 		{
150059279Selan 		  sprintf (message, "repeated `%c' flag in format",
150159279Selan 			   *format_chars);
150259279Selan 		  warning (message);
150359279Selan 		}
150459279Selan 	      i = strlen (flag_chars);
150559279Selan 	      flag_chars[i++] = *format_chars++;
150659279Selan 	      flag_chars[i] = 0;
150759279Selan 	    }
150859279Selan 	  /* "If the space and + flags both appear,
150959279Selan 	     the space flag will be ignored."  */
151059279Selan 	  if (index (flag_chars, ' ') != 0
151159279Selan 	      && index (flag_chars, '+') != 0)
151259279Selan 	    warning ("use of both ` ' and `+' flags in format");
151359279Selan 	  /* "If the 0 and - flags both appear,
151459279Selan 	     the 0 flag will be ignored."  */
151559279Selan 	  if (index (flag_chars, '0') != 0
151659279Selan 	      && index (flag_chars, '-') != 0)
151759279Selan 	    warning ("use of both `0' and `-' flags in format");
151859279Selan 	  if (*format_chars == '*')
151959279Selan 	    {
152059279Selan 	      wide = TRUE;
152159279Selan 	      /* "...a field width...may be indicated by an asterisk.
152259279Selan 		 In this case, an int argument supplies the field width..."  */
152359279Selan 	      ++format_chars;
152459279Selan 	      if (params == 0)
152559279Selan 		{
152659279Selan 		  warning (tfaff);
152759279Selan 		  return;
152859279Selan 		}
152959279Selan 	      if (info->first_arg_num != 0)
153059279Selan 		{
153159279Selan 		  cur_param = TREE_VALUE (params);
153259279Selan 		  params = TREE_CHAIN (params);
153359279Selan 		  ++arg_num;
153459279Selan 		  /* size_t is generally not valid here.
153559279Selan 		     It will work on most machines, because size_t and int
153659279Selan 		     have the same mode.  But might as well warn anyway,
153759279Selan 		     since it will fail on other machines.  */
153859279Selan 		  if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
153959279Selan 		      != integer_type_node)
154059279Selan 		    {
154159279Selan 		      sprintf (message,
154259279Selan 			       "field width is not type int (arg %d)",
154359279Selan 			       arg_num);
154459279Selan 		      warning (message);
154559279Selan 		    }
154659279Selan 		}
154759279Selan 	    }
154859279Selan 	  else
154959279Selan 	    {
155059279Selan 	      while (ISDIGIT (*format_chars))
155159279Selan 		{
155259279Selan 		  wide = TRUE;
155359279Selan 		  ++format_chars;
155459279Selan 		}
155559279Selan 	    }
155659279Selan 	  if (*format_chars == '.')
155759279Selan 	    {
155859279Selan 	      precise = TRUE;
155959279Selan 	      /* "For d, i, o, u, x, and X conversions,
156059279Selan 		 if a precision is specified, the 0 flag will be ignored.
156159279Selan 		 For other conversions, the behavior is undefined."  */
156259279Selan 	      if (index (flag_chars, '0') != 0)
156359279Selan 		warning ("precision and `0' flag both used in one %%-sequence");
156459279Selan 	      ++format_chars;
156559279Selan 	      if (*format_chars != '*' && !ISDIGIT (*format_chars))
156659279Selan 		warning ("`.' not followed by `*' or digit in format");
156759279Selan 	      /* "...a...precision...may be indicated by an asterisk.
156859279Selan 		 In this case, an int argument supplies the...precision."  */
156959279Selan 	      if (*format_chars == '*')
157059279Selan 		{
157159279Selan 		  if (info->first_arg_num != 0)
157259279Selan 		    {
157359279Selan 		      ++format_chars;
157459279Selan 		      if (params == 0)
157559279Selan 		        {
157659279Selan 			  warning (tfaff);
157759279Selan 			  return;
157859279Selan 			}
157959279Selan 		      cur_param = TREE_VALUE (params);
158059279Selan 		      params = TREE_CHAIN (params);
158159279Selan 		      ++arg_num;
158259279Selan 		      if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
158359279Selan 			  != integer_type_node)
158459279Selan 		        {
158559279Selan 		          sprintf (message,
158659279Selan 				   "field width is not type int (arg %d)",
158759279Selan 				   arg_num);
158859279Selan 		          warning (message);
158959279Selan 		        }
159059279Selan 		    }
159159279Selan 		}
159259279Selan 	      else
159359279Selan 		{
159459279Selan 		  while (ISDIGIT (*format_chars))
159559279Selan 		    ++format_chars;
159659279Selan 		}
159759279Selan 	    }
159859279Selan 	}
159959279Selan       if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L')
160059279Selan 	length_char = *format_chars++;
160159279Selan       else
160259279Selan 	length_char = 0;
160359279Selan       if (suppressed && length_char != 0)
160459279Selan 	{
160559279Selan 	  sprintf (message,
160659279Selan 		   "use of `*' and `%c' together in format",
160759279Selan 		   length_char);
160859279Selan 	  warning (message);
160959279Selan 	}
161059279Selan       format_char = *format_chars;
161159279Selan       if (format_char == 0)
161259279Selan 	{
161359279Selan 	  warning ("conversion lacks type at end of format");
161459279Selan 	  continue;
161559279Selan 	}
161659279Selan       format_chars++;
161759279Selan       fci = info->is_scan ? scan_table : print_table;
161859279Selan       while (1)
161959279Selan 	{
162059279Selan 	  if (fci->format_chars == 0
162159279Selan 	      || index (fci->format_chars, format_char) != 0)
162259279Selan 	    break;
162359279Selan 	  ++fci;
162459279Selan 	}
162559279Selan       if (fci->format_chars == 0)
162659279Selan 	{
162759279Selan 	  if (format_char >= 040 && format_char < 0177)
162859279Selan 	    sprintf (message,
162959279Selan 		     "unknown conversion type character `%c' in format",
163059279Selan 		     format_char);
163159279Selan 	  else
163259279Selan 	    sprintf (message,
163359279Selan 		     "unknown conversion type character 0x%x in format",
163459279Selan 		     format_char);
163559279Selan 	  warning (message);
163659279Selan 	  continue;
163759279Selan 	}
163859279Selan       if (wide && index (fci->flag_chars, 'w') == 0)
163959279Selan 	{
164059279Selan 	  sprintf (message, "width used with `%c' format",
164159279Selan 		   format_char);
164259279Selan 	  warning (message);
164359279Selan 	}
164459279Selan       if (precise && index (fci->flag_chars, 'p') == 0)
164559279Selan 	{
164659279Selan 	  sprintf (message, "precision used with `%c' format",
164759279Selan 		   format_char);
164859279Selan 	  warning (message);
164959279Selan 	}
165059279Selan       if (suppressed)
165159279Selan 	{
165259279Selan 	  if (index (fci->flag_chars, '*') == 0)
165359279Selan 	    {
165459279Selan 	      sprintf (message,
165559279Selan 		       "suppression of `%c' conversion in format",
165659279Selan 		       format_char);
165759279Selan 	      warning (message);
165859279Selan 	    }
165959279Selan 	  continue;
166059279Selan 	}
166159279Selan       for (i = 0; flag_chars[i] != 0; ++i)
166259279Selan 	{
166359279Selan 	  if (index (fci->flag_chars, flag_chars[i]) == 0)
166459279Selan 	    {
166559279Selan 	      sprintf (message, "flag `%c' used with type `%c'",
166659279Selan 		       flag_chars[i], format_char);
166759279Selan 	      warning (message);
166859279Selan 	    }
166959279Selan 	}
167059279Selan       switch (length_char)
167159279Selan 	{
167259279Selan 	default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break;
167359279Selan 	case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break;
167459279Selan 	case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break;
167559279Selan 	case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
167659279Selan 	}
167759279Selan       if (wanted_type == 0)
167859279Selan 	{
167959279Selan 	  sprintf (message,
168059279Selan 		   "use of `%c' length character with `%c' type character",
168159279Selan 		   length_char, format_char);
168259279Selan 	  warning (message);
168359279Selan 	}
168459279Selan 
168559279Selan       /*
168659279Selan        ** XXX -- should kvetch about stuff such as
168759279Selan        **	{
168859279Selan        **		const int	i;
168959279Selan        **
169059279Selan        **		scanf ("%d", &i);
169159279Selan        **	}
169259279Selan        */
169359279Selan 
169459279Selan       /* Finally. . .check type of argument against desired type!  */
169559279Selan       if (info->first_arg_num == 0)
169659279Selan 	continue;
169759279Selan       if (params == 0)
169859279Selan 	{
169959279Selan 	  warning (tfaff);
170059279Selan 	  return;
170159279Selan 	}
170259279Selan       cur_param = TREE_VALUE (params);
170359279Selan       params = TREE_CHAIN (params);
170459279Selan       ++arg_num;
170559279Selan       cur_type = TREE_TYPE (cur_param);
170659279Selan 
170759279Selan       /* Check the types of any additional pointer arguments
170859279Selan 	 that precede the "real" argument.  */
170959279Selan       for (i = 0; i < fci->pointer_count; ++i)
171059279Selan 	{
171159279Selan 	  if (TREE_CODE (cur_type) == POINTER_TYPE)
171259279Selan 	    {
171359279Selan 	      cur_type = TREE_TYPE (cur_type);
171459279Selan 	      continue;
171559279Selan 	    }
171659279Selan 	  sprintf (message,
171759279Selan 		   "format argument is not a %s (arg %d)",
171859279Selan 		   ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"),
171959279Selan 		   arg_num);
172059279Selan 	  warning (message);
172159279Selan 	  break;
172259279Selan 	}
172359279Selan 
172459279Selan       /* Check the type of the "real" argument, if there's a type we want.  */
172559279Selan       if (i == fci->pointer_count && wanted_type != 0
172659279Selan 	  && wanted_type != TYPE_MAIN_VARIANT (cur_type)
172759279Selan 	  /* If we want `void *', allow any pointer type.
172859279Selan 	     (Anything else would already have got a warning.)  */
172959279Selan 	  && ! (wanted_type == void_type_node
173059279Selan 		&& fci->pointer_count > 0)
173159279Selan 	  /* Don't warn about differences merely in signedness.  */
173259279Selan 	  && !(TREE_CODE (wanted_type) == INTEGER_TYPE
173359279Selan 	       && TREE_CODE (cur_type) == INTEGER_TYPE
173459279Selan 	       && TYPE_PRECISION (wanted_type) == TYPE_PRECISION (cur_type)))
173559279Selan 	{
173659279Selan 	  register char *this;
173759279Selan 	  register char *that;
173859279Selan 
173959279Selan 	  this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
174059279Selan 	  that = 0;
174159279Selan 	  if (TYPE_NAME (cur_type) != 0
174259279Selan 	      && TREE_CODE (cur_type) != INTEGER_TYPE
174359279Selan 	      && !(TREE_CODE (cur_type) == POINTER_TYPE
174459279Selan 		   && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE)
174559279Selan 	      && DECL_NAME (TYPE_NAME (cur_type)) != 0)
174659279Selan 	    that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
174759279Selan 
174859279Selan 	  /* A nameless type can't possibly match what the format wants.
174959279Selan 	     So there will be a warning for it.
175059279Selan 	     Make up a string to describe vaguely what it is.  */
175159279Selan 	  if (that == 0)
175259279Selan 	    {
175359279Selan 	      if (TREE_CODE (cur_type) == POINTER_TYPE)
175459279Selan 		that = "pointer";
175559279Selan 	      else
175659279Selan 		that = "different type";
175759279Selan 	    }
175859279Selan 
175959279Selan 	  if (strcmp (this, that) != 0)
176059279Selan 	    {
176159279Selan 	      sprintf (message, "%s format, %s arg (arg %d)",
176259279Selan 			this, that, arg_num);
176359279Selan 	      warning (message);
176459279Selan 	    }
176559279Selan 	}
176659279Selan     }
176759279Selan }
176859279Selan 
176959279Selan /* Build a function call to function FUNCTION with parameters PARAMS.
177059279Selan    PARAMS is a list--a chain of TREE_LIST nodes--in which the
177159279Selan    TREE_VALUE of each node is a parameter-expression.
177259279Selan    FUNCTION's data type may be a function type or a pointer-to-function.  */
177359279Selan 
177459279Selan tree
build_function_call(function,params)177559279Selan build_function_call (function, params)
177659279Selan      tree function, params;
177759279Selan {
177859279Selan   register tree fntype;
177959279Selan   register tree coerced_params;
178059279Selan   tree name = NULL_TREE;
178159279Selan 
178259279Selan   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
178359279Selan   STRIP_TYPE_NOPS (function);
178459279Selan 
178559279Selan   /* Convert anything with function type to a pointer-to-function.  */
178659279Selan   if (TREE_CODE (function) == FUNCTION_DECL)
178759279Selan     {
178859279Selan       name = DECL_NAME (function);
178959279Selan       /* Differs from default_conversion by not setting TREE_ADDRESSABLE
179059279Selan 	 (because calling an inline function does not mean the function
179159279Selan 	 needs to be separately compiled).  */
179259279Selan       fntype = build_type_variant (TREE_TYPE (function),
179359279Selan 				   TREE_READONLY (function),
179459279Selan 				   TREE_THIS_VOLATILE (function));
179559279Selan       function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
179659279Selan     }
179759279Selan   else
179859279Selan     function = default_conversion (function);
179959279Selan 
180059279Selan   fntype = TREE_TYPE (function);
180159279Selan 
180259279Selan   if (TREE_CODE (fntype) == ERROR_MARK)
180359279Selan     return error_mark_node;
180459279Selan 
180559279Selan   if (!(TREE_CODE (fntype) == POINTER_TYPE
180659279Selan 	&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
180759279Selan     {
180859279Selan       error ("called object is not a function");
180959279Selan       return error_mark_node;
181059279Selan     }
181159279Selan 
181259279Selan   /* fntype now gets the type of function pointed to.  */
181359279Selan   fntype = TREE_TYPE (fntype);
181459279Selan 
181559279Selan   /* Convert the parameters to the types declared in the
181659279Selan      function prototype, or apply default promotions.  */
181759279Selan 
181859279Selan   coerced_params
181959279Selan     = convert_arguments (TYPE_ARG_TYPES (fntype), params, name);
182059279Selan 
182159279Selan   /* Check for errors in format strings.  */
182259279Selan   if (warn_format && name != 0)
182359279Selan     {
182459279Selan       unsigned int i;
182559279Selan 
182659279Selan       /* See if this function is a format function.  */
182759279Selan       for (i = 0; i < function_info_entries; i++)
182859279Selan 	if (function_info_table[i].function_ident == name)
182959279Selan 	  {
183059279Selan 	    register char *message;
183159279Selan 
183259279Selan 	    /* If so, check it.  */
183359279Selan 	    check_format (&function_info_table[i], coerced_params);
183459279Selan 	    break;
183559279Selan 	  }
183659279Selan     }
183759279Selan 
183859279Selan   /* Recognize certain built-in functions so we can make tree-codes
183959279Selan      other than CALL_EXPR.  We do this when it enables fold-const.c
184059279Selan      to do something useful.  */
184159279Selan 
184259279Selan   if (TREE_CODE (function) == ADDR_EXPR
184359279Selan       && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
184459279Selan       && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
184559279Selan     switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
184659279Selan       {
184759279Selan       case BUILT_IN_ABS:
184859279Selan       case BUILT_IN_LABS:
184959279Selan       case BUILT_IN_FABS:
185059279Selan 	if (coerced_params == 0)
185159279Selan 	  return integer_zero_node;
185259279Selan 	return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
185359279Selan       }
185459279Selan 
185559279Selan   {
185659279Selan     register tree result
185759279Selan       = build (CALL_EXPR, TREE_TYPE (fntype),
185859279Selan 	       function, coerced_params, NULL_TREE);
185959279Selan 
186059279Selan     TREE_SIDE_EFFECTS (result) = 1;
186159279Selan     if (TREE_TYPE (result) == void_type_node)
186259279Selan       return result;
186359279Selan     return require_complete_type (result);
186459279Selan   }
186559279Selan }
186659279Selan 
186759279Selan /* Convert the argument expressions in the list VALUES
186859279Selan    to the types in the list TYPELIST.  The result is a list of converted
186959279Selan    argument expressions.
187059279Selan 
187159279Selan    If TYPELIST is exhausted, or when an element has NULL as its type,
187259279Selan    perform the default conversions.
187359279Selan 
187459279Selan    PARMLIST is the chain of parm decls for the function being called.
187559279Selan    It may be 0, if that info is not available.
187659279Selan    It is used only for generating error messages.
187759279Selan 
187859279Selan    NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
187959279Selan 
188059279Selan    This is also where warnings about wrong number of args are generated.
188159279Selan 
188259279Selan    Both VALUES and the returned value are chains of TREE_LIST nodes
188359279Selan    with the elements of the list in the TREE_VALUE slots of those nodes.  */
188459279Selan 
188559279Selan static tree
convert_arguments(typelist,values,name)188659279Selan convert_arguments (typelist, values, name)
188759279Selan      tree typelist, values, name;
188859279Selan {
188959279Selan   register tree typetail, valtail;
189059279Selan   register tree result = NULL;
189159279Selan   int parmnum;
189259279Selan 
189359279Selan   /* Scan the given expressions and types, producing individual
189459279Selan      converted arguments and pushing them on RESULT in reverse order.  */
189559279Selan 
189659279Selan   for (valtail = values, typetail = typelist, parmnum = 0;
189759279Selan        valtail;
189859279Selan        valtail = TREE_CHAIN (valtail), parmnum++)
189959279Selan     {
190059279Selan       register tree type = typetail ? TREE_VALUE (typetail) : 0;
190159279Selan       register tree val = TREE_VALUE (valtail);
190259279Selan 
190359279Selan       if (type == void_type_node)
190459279Selan 	{
190559279Selan 	  if (name)
190659279Selan 	    error ("too many arguments to function `%s'",
190759279Selan 		   IDENTIFIER_POINTER (name));
190859279Selan 	  else
190959279Selan 	    error ("too many arguments to function");
191059279Selan 	  break;
191159279Selan 	}
191259279Selan 
191359279Selan       /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
191459279Selan       /* Do not use STRIP_NOPS here!  We do not want an enumerator with value 0
191559279Selan 	 to convert automatically to a pointer.  */
191659279Selan       if (TREE_CODE (val) == NON_LVALUE_EXPR)
191759279Selan 	val = TREE_OPERAND (val, 0);
191859279Selan 
191959279Selan       if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
192059279Selan 	  || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE)
192159279Selan 	val = default_conversion (val);
192259279Selan 
192359279Selan       val = require_complete_type (val);
192459279Selan 
192559279Selan       if (type != 0)
192659279Selan 	{
192759279Selan 	  /* Formal parm type is specified by a function prototype.  */
192859279Selan 	  tree parmval;
192959279Selan 
193059279Selan 	  if (TYPE_SIZE (type) == 0)
193159279Selan 	    {
193259279Selan 	      error ("type of formal parameter %d is incomplete", parmnum + 1);
193359279Selan 	      parmval = val;
193459279Selan 	    }
193559279Selan 	  else
193659279Selan 	    {
193759279Selan 	      tree parmname;
193859279Selan #ifdef PROMOTE_PROTOTYPES
193959279Selan 	      /* Rather than truncating and then reextending,
194059279Selan 		 convert directly to int, if that's the type we will want.  */
194159279Selan 	      if (! flag_traditional
194259279Selan 		  && TREE_CODE (type) == INTEGER_TYPE
194359279Selan 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
194459279Selan 		type = integer_type_node;
194559279Selan #endif
194659279Selan 
194759279Selan #if 0 /* This turns out not to win--there's no way to write a prototype
194859279Selan 	 for a function whose arg type is a union with no tag.  */
194959279Selan 	      /* Nameless union automatically casts the types it contains.  */
195059279Selan 	      if (TREE_CODE (type) == UNION_TYPE && TYPE_NAME (type) == 0)
195159279Selan 		{
195259279Selan 		  tree field;
195359279Selan 
195459279Selan 		  for (field = TYPE_FIELDS (type); field;
195559279Selan 		       field = TREE_CHAIN (field))
195659279Selan 		    if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
195759279Selan 				   TYPE_MAIN_VARIANT (TREE_TYPE (val))))
195859279Selan 		      break;
195959279Selan 
196059279Selan 		  if (field)
196159279Selan 		    val = build1 (CONVERT_EXPR, type, val);
196259279Selan 		}
196359279Selan #endif
196459279Selan 
196559279Selan 	      /* Optionally warn about conversions that
196659279Selan 		 differ from the default conversions.  */
196759279Selan 	      if (warn_conversion)
196859279Selan 		{
196959279Selan 		  int formal_prec = TYPE_PRECISION (type);
197059279Selan 
197159279Selan 		  if (TREE_CODE (type) != REAL_TYPE
197259279Selan 		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
197359279Selan 		    warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
197459279Selan 		  else if (TREE_CODE (type) == REAL_TYPE
197559279Selan 		      && TREE_CODE (TREE_TYPE (val)) != REAL_TYPE)
197659279Selan 		    warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
197759279Selan 		  else if (TREE_CODE (type) == REAL_TYPE
197859279Selan 			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
197959279Selan 		    {
198059279Selan 		      /* Warn if any argument is passed as `float',
198159279Selan 			 since without a prototype it would be `double'.  */
198259279Selan 		      if (formal_prec == TYPE_PRECISION (float_type_node))
198359279Selan 			warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1);
198459279Selan 		    }
198559279Selan 		  /* Detect integer changing in width or signedness.  */
198659279Selan 		  else if ((TREE_CODE (type) == INTEGER_TYPE
198759279Selan 			    || TREE_CODE (type) == ENUMERAL_TYPE)
198859279Selan 			   && (TREE_CODE (TREE_TYPE (val)) == INTEGER_TYPE
198959279Selan 			       || TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE))
199059279Selan 		    {
199159279Selan 		      tree would_have_been = default_conversion (val);
199259279Selan 		      tree type1 = TREE_TYPE (would_have_been);
199359279Selan 
199459279Selan 		      if (TREE_CODE (type) == ENUMERAL_TYPE
199559279Selan 			  && type == TREE_TYPE (val))
199659279Selan 			/* No warning if function asks for enum
199759279Selan 			   and the actual arg is that enum type.  */
199859279Selan 			;
199959279Selan 		      else if (formal_prec != TYPE_PRECISION (type1))
200059279Selan 			warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
200159279Selan 		      else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1))
200259279Selan 			;
200359279Selan 		      /* Don't complain if the formal parameter type
200459279Selan 			 is an enum, because we can't tell now whether
200559279Selan 			 the value was an enum--even the same enum.  */
200659279Selan 		      else if (TREE_CODE (type) == ENUMERAL_TYPE)
200759279Selan 			;
200859279Selan 		      else if (TREE_CODE (val) == INTEGER_CST
200959279Selan 			       && int_fits_type_p (val, type))
201059279Selan 			/* Change in signedness doesn't matter
201159279Selan 			   if a constant value is unaffected.  */
201259279Selan 			;
201359279Selan 		      else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE
201459279Selan 			       && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type)
201559279Selan 			       && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type))
201659279Selan 			/* Change in signedness doesn't matter
201759279Selan 			   if an enum value is unaffected.  */
201859279Selan 			;
201959279Selan 		      else if (TREE_UNSIGNED (type))
202059279Selan 			warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
202159279Selan 		      else
202259279Selan 			warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
202359279Selan 		    }
202459279Selan 		}
202559279Selan 
202659279Selan 	      parmval = convert_for_assignment (type, val,
202759279Selan 					        (char *)0, /* arg passing  */
202859279Selan 						name, parmnum + 1);
202959279Selan 
203059279Selan #ifdef PROMOTE_PROTOTYPES
203159279Selan 	      if (TREE_CODE (type) == INTEGER_TYPE
203259279Selan 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
203359279Selan 		parmval = default_conversion (parmval);
203459279Selan #endif
203559279Selan 	    }
203659279Selan 	  result = tree_cons (NULL_TREE, parmval, result);
203759279Selan 	}
203859279Selan       else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
203959279Selan                && (TYPE_PRECISION (TREE_TYPE (val))
204059279Selan 	           < TYPE_PRECISION (double_type_node)))
204159279Selan 	/* Convert `float' to `double'.  */
204259279Selan 	result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
204359279Selan       else
204459279Selan 	/* Convert `short' and `char' to full-size `int'.  */
204559279Selan 	result = tree_cons (NULL_TREE, default_conversion (val), result);
204659279Selan 
204759279Selan       if (typetail)
204859279Selan 	typetail = TREE_CHAIN (typetail);
204959279Selan     }
205059279Selan 
205159279Selan   if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
205259279Selan     {
205359279Selan       if (name)
205459279Selan 	error ("too few arguments to function `%s'",
205559279Selan 	       IDENTIFIER_POINTER (name));
205659279Selan       else
205759279Selan 	error ("too few arguments to function");
205859279Selan     }
205959279Selan 
206059279Selan   return nreverse (result);
206159279Selan }
206259279Selan 
206359279Selan /* This is the entry point used by the parser
206459279Selan    for binary operators in the input.
206559279Selan    In addition to constructing the expression,
206659279Selan    we check for operands that were written with other binary operators
206759279Selan    in a way that is likely to confuse the user.  */
206859279Selan 
206959279Selan tree
parser_build_binary_op(code,arg1,arg2)207059279Selan parser_build_binary_op (code, arg1, arg2)
207159279Selan      enum tree_code code;
207259279Selan      tree arg1, arg2;
207359279Selan {
207459279Selan   tree result = build_binary_op (code, arg1, arg2, 1);
207559279Selan 
207659279Selan   char class;
207759279Selan   char class1 = TREE_CODE_CLASS (TREE_CODE (arg1));
207859279Selan   char class2 = TREE_CODE_CLASS (TREE_CODE (arg2));
207959279Selan   enum tree_code code1 = ERROR_MARK;
208059279Selan   enum tree_code code2 = ERROR_MARK;
208159279Selan 
208259279Selan   if (class1 == 'e' || class1 == '1'
208359279Selan       || class1 == '2' || class1 == '<')
208459279Selan     code1 = C_EXP_ORIGINAL_CODE (arg1);
208559279Selan   if (class2 == 'e' || class2 == '1'
208659279Selan       || class2 == '2' || class2 == '<')
208759279Selan     code2 = C_EXP_ORIGINAL_CODE (arg2);
208859279Selan 
208959279Selan   /* Check for cases such as x+y<<z which users are likely
209059279Selan      to misinterpret.  If parens are used, C_EXP_ORIGINAL_CODE
209159279Selan      is cleared to prevent these warnings.  */
209259279Selan   if (warn_parentheses)
209359279Selan     {
209459279Selan       if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
209559279Selan 	{
209659279Selan 	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
209759279Selan 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
209859279Selan 	    warning ("suggest parentheses around + or - inside shift");
209959279Selan 	}
210059279Selan 
210159279Selan       if (code == TRUTH_ORIF_EXPR)
210259279Selan 	{
210359279Selan 	  if (code1 == TRUTH_ANDIF_EXPR
210459279Selan 	      || code2 == TRUTH_ANDIF_EXPR)
210559279Selan 	    warning ("suggest parentheses around && within ||");
210659279Selan 	}
210759279Selan 
210859279Selan       if (code == BIT_IOR_EXPR)
210959279Selan 	{
211059279Selan 	  if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
211159279Selan 	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
211259279Selan 	      || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
211359279Selan 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
211459279Selan 	    warning ("suggest parentheses around arithmetic in operand of |");
211559279Selan 	}
211659279Selan 
211759279Selan       if (code == BIT_XOR_EXPR)
211859279Selan 	{
211959279Selan 	  if (code1 == BIT_AND_EXPR
212059279Selan 	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
212159279Selan 	      || code2 == BIT_AND_EXPR
212259279Selan 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
212359279Selan 	    warning ("suggest parentheses around arithmetic in operand of ^");
212459279Selan 	}
212559279Selan 
212659279Selan       if (code == BIT_AND_EXPR)
212759279Selan 	{
212859279Selan 	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
212959279Selan 	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
213059279Selan 	    warning ("suggest parentheses around + or - in operand of &");
213159279Selan 	}
213259279Selan     }
213359279Selan 
213459279Selan   /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
213559279Selan   if (TREE_CODE_CLASS (code) == '<' && extra_warnings
213659279Selan       && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<'))
213759279Selan     warning ("comparisons like X<=Y<=Z do not have their mathematical meaning");
213859279Selan 
213959279Selan   class = TREE_CODE_CLASS (TREE_CODE (result));
214059279Selan 
214159279Selan   /* Record the code that was specified in the source,
214259279Selan      for the sake of warnings about confusing nesting.  */
214359279Selan   if (class == 'e' || class == '1'
214459279Selan       || class == '2' || class == '<')
214559279Selan     C_SET_EXP_ORIGINAL_CODE (result, code);
214659279Selan   else
214759279Selan     {
214859279Selan       int flag = TREE_CONSTANT (result);
214959279Selan       result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
215059279Selan       C_SET_EXP_ORIGINAL_CODE (result, code);
215159279Selan       TREE_CONSTANT (result) = flag;
215259279Selan     }
215359279Selan 
215459279Selan   return result;
215559279Selan }
215659279Selan 
215759279Selan /* Build a binary-operation expression without default conversions.
215859279Selan    CODE is the kind of expression to build.
215959279Selan    This function differs from `build' in several ways:
216059279Selan    the data type of the result is computed and recorded in it,
216159279Selan    warnings are generated if arg data types are invalid,
216259279Selan    special handling for addition and subtraction of pointers is known,
216359279Selan    and some optimization is done (operations on narrow ints
216459279Selan    are done in the narrower type when that gives the same result).
216559279Selan    Constant folding is also done before the result is returned.
216659279Selan 
216759279Selan    Note that the operands will never have enumeral types, or function
216859279Selan    or array types, because either they will have the default conversions
216959279Selan    performed or they have both just been converted to some other type in which
217059279Selan    the arithmetic is to be done.  */
217159279Selan 
217259279Selan tree
build_binary_op(code,orig_op0,orig_op1,convert_p)217359279Selan build_binary_op (code, orig_op0, orig_op1, convert_p)
217459279Selan      enum tree_code code;
217559279Selan      tree orig_op0, orig_op1;
217659279Selan      int convert_p;
217759279Selan {
217859279Selan   tree type0, type1;
217959279Selan   register enum tree_code code0, code1;
218059279Selan   tree op0, op1;
218159279Selan 
218259279Selan   /* Expression code to give to the expression when it is built.
218359279Selan      Normally this is CODE, which is what the caller asked for,
218459279Selan      but in some special cases we change it.  */
218559279Selan   register enum tree_code resultcode = code;
218659279Selan 
218759279Selan   /* Data type in which the computation is to be performed.
218859279Selan      In the simplest cases this is the common type of the arguments.  */
218959279Selan   register tree result_type = NULL;
219059279Selan 
219159279Selan   /* Nonzero means operands have already been type-converted
219259279Selan      in whatever way is necessary.
219359279Selan      Zero means they need to be converted to RESULT_TYPE.  */
219459279Selan   int converted = 0;
219559279Selan 
219659279Selan   /* Nonzero means after finally constructing the expression
219759279Selan      give it this type.  Otherwise, give it type RESULT_TYPE.  */
219859279Selan   tree final_type = 0;
219959279Selan 
220059279Selan   /* Nonzero if this is an operation like MIN or MAX which can
220159279Selan      safely be computed in short if both args are promoted shorts.
220259279Selan      Also implies COMMON.
220359279Selan      -1 indicates a bitwise operation; this makes a difference
220459279Selan      in the exact conditions for when it is safe to do the operation
220559279Selan      in a narrower mode.  */
220659279Selan   int shorten = 0;
220759279Selan 
220859279Selan   /* Nonzero if this is a comparison operation;
220959279Selan      if both args are promoted shorts, compare the original shorts.
221059279Selan      Also implies COMMON.  */
221159279Selan   int short_compare = 0;
221259279Selan 
221359279Selan   /* Nonzero if this is a right-shift operation, which can be computed on the
221459279Selan      original short and then promoted if the operand is a promoted short.  */
221559279Selan   int short_shift = 0;
221659279Selan 
221759279Selan   /* Nonzero means set RESULT_TYPE to the common type of the args.  */
221859279Selan   int common = 0;
221959279Selan 
222059279Selan   if (convert_p)
222159279Selan     {
222259279Selan       op0 = default_conversion (orig_op0);
222359279Selan       op1 = default_conversion (orig_op1);
222459279Selan     }
222559279Selan   else
222659279Selan     {
222759279Selan       op0 = orig_op0;
222859279Selan       op1 = orig_op1;
222959279Selan     }
223059279Selan 
223159279Selan   type0 = TREE_TYPE (op0);
223259279Selan   type1 = TREE_TYPE (op1);
223359279Selan 
223459279Selan   /* The expression codes of the data types of the arguments tell us
223559279Selan      whether the arguments are integers, floating, pointers, etc.  */
223659279Selan   code0 = TREE_CODE (type0);
223759279Selan   code1 = TREE_CODE (type1);
223859279Selan 
223959279Selan   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
224059279Selan   STRIP_TYPE_NOPS (op0);
224159279Selan   STRIP_TYPE_NOPS (op1);
224259279Selan 
224359279Selan   /* If an error was already reported for one of the arguments,
224459279Selan      avoid reporting another error.  */
224559279Selan 
224659279Selan   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
224759279Selan     return error_mark_node;
224859279Selan 
224959279Selan   switch (code)
225059279Selan     {
225159279Selan     case PLUS_EXPR:
225259279Selan       /* Handle the pointer + int case.  */
225359279Selan       if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
225459279Selan 	return pointer_int_sum (PLUS_EXPR, op0, op1);
225559279Selan       else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
225659279Selan 	return pointer_int_sum (PLUS_EXPR, op1, op0);
225759279Selan       else
225859279Selan 	common = 1;
225959279Selan       break;
226059279Selan 
226159279Selan     case MINUS_EXPR:
226259279Selan       /* Subtraction of two similar pointers.
226359279Selan 	 We must subtract them as integers, then divide by object size.  */
226459279Selan       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
226559279Selan 	  && comp_target_types (type0, type1))
226659279Selan 	return pointer_diff (op0, op1);
226759279Selan       /* Handle pointer minus int.  Just like pointer plus int.  */
226859279Selan       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
226959279Selan 	return pointer_int_sum (MINUS_EXPR, op0, op1);
227059279Selan       else
227159279Selan 	common = 1;
227259279Selan       break;
227359279Selan 
227459279Selan     case MULT_EXPR:
227559279Selan       common = 1;
227659279Selan       break;
227759279Selan 
227859279Selan     case TRUNC_DIV_EXPR:
227959279Selan     case CEIL_DIV_EXPR:
228059279Selan     case FLOOR_DIV_EXPR:
228159279Selan     case ROUND_DIV_EXPR:
228259279Selan     case EXACT_DIV_EXPR:
228359279Selan       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
228459279Selan 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
228559279Selan 	{
228659279Selan 	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
228759279Selan 	    resultcode = RDIV_EXPR;
228859279Selan 	  else
228959279Selan 	    /* When dividing two signed integers, you have to promote to int.
229059279Selan 	       E.g. (short) -32868 / (short) -1 doesn't fit in a short.  */
229159279Selan 	    shorten = TREE_UNSIGNED (op0);
229259279Selan 	  common = 1;
229359279Selan 	}
229459279Selan       break;
229559279Selan 
229659279Selan     case BIT_AND_EXPR:
229759279Selan     case BIT_ANDTC_EXPR:
229859279Selan     case BIT_IOR_EXPR:
229959279Selan     case BIT_XOR_EXPR:
230059279Selan       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
230159279Selan 	shorten = -1;
230259279Selan       /* If one operand is a constant, and the other is a short type
230359279Selan 	 that has been converted to an int,
230459279Selan 	 really do the work in the short type and then convert the
230559279Selan 	 result to int.  If we are lucky, the constant will be 0 or 1
230659279Selan 	 in the short type, making the entire operation go away.  */
230759279Selan       if (TREE_CODE (op0) == INTEGER_CST
230859279Selan 	  && TREE_CODE (op1) == NOP_EXPR
230959279Selan 	  && TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))
231059279Selan 	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
231159279Selan 	{
231259279Selan 	  final_type = result_type;
231359279Selan 	  op1 = TREE_OPERAND (op1, 0);
231459279Selan 	  result_type = TREE_TYPE (op1);
231559279Selan 	}
231659279Selan       if (TREE_CODE (op1) == INTEGER_CST
231759279Selan 	  && TREE_CODE (op0) == NOP_EXPR
231859279Selan 	  && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))
231959279Selan 	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
232059279Selan 	{
232159279Selan 	  final_type = result_type;
232259279Selan 	  op0 = TREE_OPERAND (op0, 0);
232359279Selan 	  result_type = TREE_TYPE (op0);
232459279Selan 	}
232559279Selan       break;
232659279Selan 
232759279Selan     case TRUNC_MOD_EXPR:
232859279Selan     case FLOOR_MOD_EXPR:
232959279Selan       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
233059279Selan 	shorten = 1;
233159279Selan       break;
233259279Selan 
233359279Selan     case TRUTH_ANDIF_EXPR:
233459279Selan     case TRUTH_ORIF_EXPR:
233559279Selan     case TRUTH_AND_EXPR:
233659279Selan     case TRUTH_OR_EXPR:
233759279Selan       if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE)
233859279Selan 	  && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE))
233959279Selan 	{
234059279Selan 	  /* Result of these operations is always an int,
234159279Selan 	     but that does not mean the operands should be
234259279Selan 	     converted to ints!  */
234359279Selan 	  result_type = integer_type_node;
234459279Selan 	  op0 = truthvalue_conversion (op0);
234559279Selan 	  op1 = truthvalue_conversion (op1);
234659279Selan 	  converted = 1;
234759279Selan 	}
234859279Selan       break;
234959279Selan 
235059279Selan       /* Shift operations: result has same type as first operand;
235159279Selan 	 always convert second operand to int.
235259279Selan 	 Also set SHORT_SHIFT if shifting rightward.  */
235359279Selan 
235459279Selan     case RSHIFT_EXPR:
235559279Selan       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
235659279Selan 	{
235759279Selan 	  if (TREE_CODE (op1) == INTEGER_CST)
235859279Selan 	    {
235959279Selan 	      if (tree_int_cst_lt (op1, integer_zero_node))
236059279Selan 		warning ("shift count is negative");
236159279Selan 	      else
236259279Selan 		{
236359279Selan 		  if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
236459279Selan 		    short_shift = 1;
236559279Selan 		  if (TREE_INT_CST_HIGH (op1) != 0
236659279Selan 		      || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
236759279Selan 			  >= TYPE_PRECISION (type0)))
236859279Selan 		    warning ("shift count >= width of type");
236959279Selan 		}
237059279Selan 	    }
237159279Selan 	  /* Use the type of the value to be shifted.
237259279Selan 	     This is what most traditional C compilers do.  */
237359279Selan 	  result_type = type0;
237459279Selan 	  /* Unless traditional, convert the shift-count to an integer,
237559279Selan 	     regardless of size of value being shifted.  */
237659279Selan 	  if (! flag_traditional)
237759279Selan 	    {
237859279Selan 	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
237959279Selan 		op1 = convert (integer_type_node, op1);
238059279Selan 	      /* Avoid converting op1 to result_type later.  */
238159279Selan 	      converted = 1;
238259279Selan 	    }
238359279Selan 	}
238459279Selan       break;
238559279Selan 
238659279Selan     case LSHIFT_EXPR:
238759279Selan       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
238859279Selan 	{
238959279Selan 	  if (TREE_CODE (op1) == INTEGER_CST)
239059279Selan 	    {
239159279Selan 	      if (tree_int_cst_lt (op1, integer_zero_node))
239259279Selan 		warning ("shift count is negative");
239359279Selan 	      else if (TREE_INT_CST_HIGH (op1) != 0
239459279Selan 		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
239559279Selan 			   >= TYPE_PRECISION (type0)))
239659279Selan 		warning ("shift count >= width of type");
239759279Selan 	    }
239859279Selan 	  /* Use the type of the value to be shifted.
239959279Selan 	     This is what most traditional C compilers do.  */
240059279Selan 	  result_type = type0;
240159279Selan 	  /* Unless traditional, convert the shift-count to an integer,
240259279Selan 	     regardless of size of value being shifted.  */
240359279Selan 	  if (! flag_traditional)
240459279Selan 	    {
240559279Selan 	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
240659279Selan 		op1 = convert (integer_type_node, op1);
240759279Selan 	      /* Avoid converting op1 to result_type later.  */
240859279Selan 	      converted = 1;
240959279Selan 	    }
241059279Selan 	}
241159279Selan       break;
241259279Selan 
241359279Selan     case RROTATE_EXPR:
241459279Selan     case LROTATE_EXPR:
241559279Selan       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
241659279Selan 	{
241759279Selan 	  if (TREE_CODE (op1) == INTEGER_CST)
241859279Selan 	    {
241959279Selan 	      if (tree_int_cst_lt (op1, integer_zero_node))
242059279Selan 		warning ("shift count is negative");
242159279Selan 	      else if (TREE_INT_CST_HIGH (op1) != 0
242259279Selan 		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
242359279Selan 			   >= TYPE_PRECISION (type0)))
242459279Selan 		warning ("shift count >= width of type");
242559279Selan 	    }
242659279Selan 	  /* Use the type of the value to be shifted.
242759279Selan 	     This is what most traditional C compilers do.  */
242859279Selan 	  result_type = type0;
242959279Selan 	  /* Unless traditional, convert the shift-count to an integer,
243059279Selan 	     regardless of size of value being shifted.  */
243159279Selan 	  if (! flag_traditional)
243259279Selan 	    {
243359279Selan 	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
243459279Selan 		op1 = convert (integer_type_node, op1);
243559279Selan 	      /* Avoid converting op1 to result_type later.  */
243659279Selan 	      converted = 1;
243759279Selan 	    }
243859279Selan 	}
243959279Selan       break;
244059279Selan 
244159279Selan     case EQ_EXPR:
244259279Selan     case NE_EXPR:
244359279Selan       /* Result of comparison is always int,
244459279Selan 	 but don't convert the args to int!  */
244559279Selan       result_type = integer_type_node;
244659279Selan       converted = 1;
244759279Selan       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
244859279Selan 	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
244959279Selan 	short_compare = 1;
245059279Selan       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
245159279Selan 	{
245259279Selan 	  register tree tt0 = TREE_TYPE (type0);
245359279Selan 	  register tree tt1 = TREE_TYPE (type1);
245459279Selan 	  /* Anything compares with void *.  void * compares with anything.
245559279Selan 	     Otherwise, the targets must be the same.  */
245659279Selan 	  if (comp_target_types (type0, type1))
245759279Selan 	    ;
245859279Selan 	  else if (TYPE_MAIN_VARIANT (tt0) == void_type_node)
245959279Selan 	    {
246059279Selan 	      if (pedantic && !integer_zerop (op0)
246159279Selan 		  && TREE_CODE (tt1) == FUNCTION_TYPE)
246259279Selan 		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
246359279Selan 	    }
246459279Selan 	  else if (TYPE_MAIN_VARIANT (tt1) == void_type_node)
246559279Selan 	    {
246659279Selan 	      if (pedantic && !integer_zerop (op1)
246759279Selan 		  && TREE_CODE (tt0) == FUNCTION_TYPE)
246859279Selan 		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
246959279Selan 	    }
247059279Selan 	  else
247159279Selan 	    pedwarn ("comparison of distinct pointer types lacks a cast");
247259279Selan 	}
247359279Selan       else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
247459279Selan 	       && integer_zerop (op1))
247559279Selan 	op1 = null_pointer_node;
247659279Selan       else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
247759279Selan 	       && integer_zerop (op0))
247859279Selan 	op0 = null_pointer_node;
247959279Selan       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
248059279Selan 	{
248159279Selan 	  if (! flag_traditional)
248259279Selan 	    pedwarn ("comparison between pointer and integer");
248359279Selan 	  op1 = convert (TREE_TYPE (op0), op1);
248459279Selan 	}
248559279Selan       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
248659279Selan 	{
248759279Selan 	  if (! flag_traditional)
248859279Selan 	    pedwarn ("comparison between pointer and integer");
248959279Selan 	  op0 = convert (TREE_TYPE (op1), op0);
249059279Selan 	}
249159279Selan       else
249259279Selan 	/* If args are not valid, clear out RESULT_TYPE
249359279Selan 	   to cause an error message later.  */
249459279Selan 	result_type = 0;
249559279Selan       break;
249659279Selan 
249759279Selan     case MAX_EXPR:
249859279Selan     case MIN_EXPR:
249959279Selan       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
250059279Selan 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
250159279Selan 	shorten = 1;
250259279Selan       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
250359279Selan 	{
250459279Selan 	  if (! comp_target_types (type0, type1))
250559279Selan 	    pedwarn ("comparison of distinct pointer types lacks a cast");
250659279Selan 	  else if (pedantic
250759279Selan 		   && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
250859279Selan 	    pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
250959279Selan 	  result_type = common_type (type0, type1);
251059279Selan 	}
251159279Selan       break;
251259279Selan 
251359279Selan     case LE_EXPR:
251459279Selan     case GE_EXPR:
251559279Selan     case LT_EXPR:
251659279Selan     case GT_EXPR:
251759279Selan       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
251859279Selan 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
251959279Selan 	short_compare = 1;
252059279Selan       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
252159279Selan 	{
252259279Selan 	  if (! comp_target_types (type0, type1))
252359279Selan 	    pedwarn ("comparison of distinct pointer types lacks a cast");
252459279Selan 	  else if (pedantic
252559279Selan 		   && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
252659279Selan 	    pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
252759279Selan 	  result_type = integer_type_node;
252859279Selan 	}
252959279Selan       else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
253059279Selan 	       && integer_zerop (op1))
253159279Selan 	{
253259279Selan 	  result_type = integer_type_node;
253359279Selan 	  op1 = null_pointer_node;
253459279Selan 	  if (! flag_traditional)
253559279Selan 	    pedwarn ("ordered comparison of pointer with integer zero");
253659279Selan 	}
253759279Selan       else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
253859279Selan 	       && integer_zerop (op0))
253959279Selan 	{
254059279Selan 	  result_type = integer_type_node;
254159279Selan 	  op0 = null_pointer_node;
254259279Selan 	  if (pedantic)
254359279Selan 	    pedwarn ("ordered comparison of pointer with integer zero");
254459279Selan 	}
254559279Selan       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
254659279Selan 	{
254759279Selan 	  result_type = integer_type_node;
254859279Selan 	  if (! flag_traditional)
254959279Selan 	    pedwarn ("comparison between pointer and integer");
255059279Selan 	  op1 = convert (TREE_TYPE (op0), op1);
255159279Selan 	}
255259279Selan       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
255359279Selan 	{
255459279Selan 	  result_type = integer_type_node;
255559279Selan 	  if (! flag_traditional)
255659279Selan 	    pedwarn ("comparison between pointer and integer");
255759279Selan 	  op0 = convert (TREE_TYPE (op1), op0);
255859279Selan 	}
255959279Selan       converted = 1;
256059279Selan       break;
256159279Selan     }
256259279Selan 
256359279Selan   if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
256459279Selan       && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
256559279Selan     {
256659279Selan       if (shorten || common || short_compare)
256759279Selan 	result_type = common_type (type0, type1);
256859279Selan 
256959279Selan       /* For certain operations (which identify themselves by shorten != 0)
257059279Selan 	 if both args were extended from the same smaller type,
257159279Selan 	 do the arithmetic in that type and then extend.
257259279Selan 
257359279Selan 	 shorten !=0 and !=1 indicates a bitwise operation.
257459279Selan 	 For them, this optimization is safe only if
257559279Selan 	 both args are zero-extended or both are sign-extended.
257659279Selan 	 Otherwise, we might change the result.
257759279Selan 	 Eg, (short)-1 | (unsigned short)-1 is (int)-1
257859279Selan 	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
257959279Selan 
258059279Selan       if (shorten)
258159279Selan 	{
258259279Selan 	  int unsigned0, unsigned1;
258359279Selan 	  tree arg0 = get_narrower (op0, &unsigned0);
258459279Selan 	  tree arg1 = get_narrower (op1, &unsigned1);
258559279Selan 	  /* UNS is 1 if the operation to be done is an unsigned one.  */
258659279Selan 	  int uns = TREE_UNSIGNED (result_type);
258759279Selan 	  tree type;
258859279Selan 
258959279Selan 	  final_type = result_type;
259059279Selan 
259159279Selan 	  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
259259279Selan 	     but it *requires* conversion to FINAL_TYPE.  */
259359279Selan 
259459279Selan 	  if ((TYPE_PRECISION (TREE_TYPE (op0))
259559279Selan 	       == TYPE_PRECISION (TREE_TYPE (arg0)))
259659279Selan 	      && TREE_TYPE (op0) != final_type)
259759279Selan 	    unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
259859279Selan 	  if ((TYPE_PRECISION (TREE_TYPE (op1))
259959279Selan 	       == TYPE_PRECISION (TREE_TYPE (arg1)))
260059279Selan 	      && TREE_TYPE (op1) != final_type)
260159279Selan 	    unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
260259279Selan 
260359279Selan 	  /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
260459279Selan 
260559279Selan 	  /* For bitwise operations, signedness of nominal type
260659279Selan 	     does not matter.  Consider only how operands were extended.  */
260759279Selan 	  if (shorten == -1)
260859279Selan 	    uns = unsigned0;
260959279Selan 
261059279Selan 	  /* Note that in all three cases below we refrain from optimizing
261159279Selan 	     an unsigned operation on sign-extended args.
261259279Selan 	     That would not be valid.  */
261359279Selan 
261459279Selan 	  /* Both args variable: if both extended in same way
261559279Selan 	     from same width, do it in that width.
261659279Selan 	     Do it unsigned if args were zero-extended.  */
261759279Selan 	  if ((TYPE_PRECISION (TREE_TYPE (arg0))
261859279Selan 	       < TYPE_PRECISION (result_type))
261959279Selan 	      && (TYPE_PRECISION (TREE_TYPE (arg1))
262059279Selan 		  == TYPE_PRECISION (TREE_TYPE (arg0)))
262159279Selan 	      && unsigned0 == unsigned1
262259279Selan 	      && (unsigned0 || !uns))
262359279Selan 	    result_type
262459279Selan 	      = signed_or_unsigned_type (unsigned0,
262559279Selan 					 common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
262659279Selan 	  else if (TREE_CODE (arg0) == INTEGER_CST
262759279Selan 		   && (unsigned1 || !uns)
262859279Selan 		   && (TYPE_PRECISION (TREE_TYPE (arg1))
262959279Selan 		       < TYPE_PRECISION (result_type))
263059279Selan 		   && (type = signed_or_unsigned_type (unsigned1,
263159279Selan 						       TREE_TYPE (arg1)),
263259279Selan 		       int_fits_type_p (arg0, type)))
263359279Selan 	    result_type = type;
263459279Selan 	  else if (TREE_CODE (arg1) == INTEGER_CST
263559279Selan 		   && (unsigned0 || !uns)
263659279Selan 		   && (TYPE_PRECISION (TREE_TYPE (arg0))
263759279Selan 		       < TYPE_PRECISION (result_type))
263859279Selan 		   && (type = signed_or_unsigned_type (unsigned0,
263959279Selan 						       TREE_TYPE (arg0)),
264059279Selan 		       int_fits_type_p (arg1, type)))
264159279Selan 	    result_type = type;
264259279Selan 	}
264359279Selan 
264459279Selan       /* Shifts can be shortened if shifting right.  */
264559279Selan 
264659279Selan       if (short_shift)
264759279Selan 	{
264859279Selan 	  int unsigned_arg;
264959279Selan 	  tree arg0 = get_narrower (op0, &unsigned_arg);
265059279Selan 
265159279Selan 	  final_type = result_type;
265259279Selan 
265359279Selan 	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
265459279Selan 	    unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
265559279Selan 
265659279Selan 	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
265759279Selan 	      /* If arg is sign-extended and then unsigned-shifted,
265859279Selan 		 we can simulate this with a signed shift in arg's type
265959279Selan 		 only if the extended result is at least twice as wide
266059279Selan 		 as the arg.  Otherwise, the shift could use up all the
266159279Selan 		 ones made by sign-extension and bring in zeros.
266259279Selan 		 We can't optimize that case at all, but in most machines
266359279Selan 		 it never happens because available widths are 2**N.  */
266459279Selan 	      && (!TREE_UNSIGNED (final_type)
266559279Selan 		  || unsigned_arg
266659279Selan 		  || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type)))
266759279Selan 	    {
266859279Selan 	      /* Do an unsigned shift if the operand was zero-extended.  */
266959279Selan 	      result_type
267059279Selan 		= signed_or_unsigned_type (unsigned_arg,
267159279Selan 					   TREE_TYPE (arg0));
267259279Selan 	      /* Convert value-to-be-shifted to that type.  */
267359279Selan 	      if (TREE_TYPE (op0) != result_type)
267459279Selan 		op0 = convert (result_type, op0);
267559279Selan 	      converted = 1;
267659279Selan 	    }
267759279Selan 	}
267859279Selan 
267959279Selan       /* Comparison operations are shortened too but differently.
268059279Selan 	 They identify themselves by setting short_compare = 1.  */
268159279Selan 
268259279Selan       if (short_compare)
268359279Selan 	{
268459279Selan 	  /* Don't write &op0, etc., because that would prevent op0
268559279Selan 	     from being kept in a register.
268659279Selan 	     Instead, make copies of the our local variables and
268759279Selan 	     pass the copies by reference, then copy them back afterward.  */
268859279Selan 	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
268959279Selan 	  enum tree_code xresultcode = resultcode;
269059279Selan 	  tree val
269159279Selan 	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
269259279Selan 	  if (val != 0)
269359279Selan 	    return val;
269459279Selan 	  op0 = xop0, op1 = xop1, result_type = xresult_type;
269559279Selan 	  resultcode = xresultcode;
269659279Selan 
269759279Selan 	  if (extra_warnings)
269859279Selan 	    {
269959279Selan 	      tree op0_type = TREE_TYPE (orig_op0);
270059279Selan 	      tree op1_type = TREE_TYPE (orig_op1);
270159279Selan 	      int op0_unsigned = TREE_UNSIGNED (op0_type);
270259279Selan 	      int op1_unsigned = TREE_UNSIGNED (op1_type);
270359279Selan 
270459279Selan 	      /* Give warnings for comparisons between signed and unsigned
270559279Selan 		 quantities that will fail.  Do not warn if the signed quantity
270659279Selan 		 is an unsuffixed integer literal (or some static constant
270759279Selan 		 expression involving such literals) and it is positive.
270859279Selan 		 Do not warn if the width of the unsigned quantity is less
270959279Selan 		 than that of the signed quantity, since in this case all
271059279Selan 		 values of the unsigned quantity fit in the signed quantity.
271159279Selan 		 Do not warn if the signed type is the same size as the
271259279Selan 		 result_type since sign extension does not cause trouble in
271359279Selan 		 this case.  */
271459279Selan 	      /* Do the checking based on the original operand trees, so that
271559279Selan 		 casts will be considered, but default promotions won't be.  */
271659279Selan 	      if (op0_unsigned != op1_unsigned
271759279Selan 		  && ((op0_unsigned
271859279Selan 		       && TYPE_PRECISION (op0_type) >= TYPE_PRECISION (op1_type)
271959279Selan 		       && TYPE_PRECISION (op0_type) < TYPE_PRECISION (result_type)
272059279Selan 		       && (TREE_CODE (op1) != INTEGER_CST
272159279Selan 			   || (TREE_CODE (op1) == INTEGER_CST
272259279Selan 			       && INT_CST_LT (op1, integer_zero_node))))
272359279Selan 		      ||
272459279Selan 		      (op1_unsigned
272559279Selan 		       && TYPE_PRECISION (op1_type) >= TYPE_PRECISION (op0_type)
272659279Selan 		       && TYPE_PRECISION (op1_type) < TYPE_PRECISION (result_type)
272759279Selan 		       && (TREE_CODE (op0) != INTEGER_CST
272859279Selan 			   || (TREE_CODE (op0) == INTEGER_CST
272959279Selan 			       && INT_CST_LT (op0, integer_zero_node))))))
273059279Selan 		warning ("comparison between signed and unsigned");
273159279Selan 	    }
273259279Selan 	}
273359279Selan     }
273459279Selan 
273559279Selan   /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
273659279Selan      If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
273759279Selan      Then the expression will be built.
273859279Selan      It will be given type FINAL_TYPE if that is nonzero;
273959279Selan      otherwise, it will be given type RESULT_TYPE.  */
274059279Selan 
274159279Selan   if (!result_type)
274259279Selan     {
274359279Selan       binary_op_error (code);
274459279Selan       return error_mark_node;
274559279Selan     }
274659279Selan 
274759279Selan   if (! converted)
274859279Selan     {
274959279Selan       if (TREE_TYPE (op0) != result_type)
275059279Selan 	op0 = convert (result_type, op0);
275159279Selan       if (TREE_TYPE (op1) != result_type)
275259279Selan 	op1 = convert (result_type, op1);
275359279Selan     }
275459279Selan 
275559279Selan   {
275659279Selan     register tree result = build (resultcode, result_type, op0, op1);
275759279Selan     register tree folded;
275859279Selan 
275959279Selan     folded = fold (result);
276059279Selan     if (folded == result)
276159279Selan       TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
276259279Selan     if (final_type != 0)
276359279Selan       return convert (final_type, folded);
276459279Selan     return folded;
276559279Selan   }
276659279Selan }
276759279Selan 
276859279Selan /* Return a tree for the sum or difference (RESULTCODE says which)
276959279Selan    of pointer PTROP and integer INTOP.  */
277059279Selan 
277159279Selan static tree
pointer_int_sum(resultcode,ptrop,intop)277259279Selan pointer_int_sum (resultcode, ptrop, intop)
277359279Selan      enum tree_code resultcode;
277459279Selan      register tree ptrop, intop;
277559279Selan {
277659279Selan   tree size_exp;
277759279Selan 
277859279Selan   register tree result;
277959279Selan   register tree folded;
278059279Selan 
278159279Selan   /* The result is a pointer of the same type that is being added.  */
278259279Selan 
278359279Selan   register tree result_type = TREE_TYPE (ptrop);
278459279Selan 
278559279Selan   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
278659279Selan     {
278759279Selan       if (pedantic || warn_pointer_arith)
278859279Selan 	pedwarn ("pointer of type `void *' used in arithmetic");
278959279Selan       size_exp = integer_one_node;
279059279Selan     }
279159279Selan   else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
279259279Selan     {
279359279Selan       if (pedantic || warn_pointer_arith)
279459279Selan 	pedwarn ("pointer to a function used in arithmetic");
279559279Selan       size_exp = integer_one_node;
279659279Selan     }
279759279Selan   else
279859279Selan     size_exp = c_size_in_bytes (TREE_TYPE (result_type));
279959279Selan 
280059279Selan   /* If what we are about to multiply by the size of the elements
280159279Selan      contains a constant term, apply distributive law
280259279Selan      and multiply that constant term separately.
280359279Selan      This helps produce common subexpressions.  */
280459279Selan 
280559279Selan   if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
280659279Selan       && ! TREE_CONSTANT (intop)
280759279Selan       && TREE_CONSTANT (TREE_OPERAND (intop, 1))
280859279Selan       && TREE_CONSTANT (size_exp)
280959279Selan       /* If the constant comes from pointer subtraction,
281059279Selan 	 skip this optimization--it would cause an error.  */
281159279Selan       && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE)
281259279Selan     {
281359279Selan       enum tree_code subcode = resultcode;
281459279Selan       tree int_type = TREE_TYPE (intop);
281559279Selan       if (TREE_CODE (intop) == MINUS_EXPR)
281659279Selan 	subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
281759279Selan       /* Convert both subexpression types to the type of intop,
281859279Selan 	 because weird cases involving pointer arithmetic
281959279Selan 	 can result in a sum or difference with different type args.  */
282059279Selan       ptrop = build_binary_op (subcode, ptrop,
282159279Selan 			       convert (int_type, TREE_OPERAND (intop, 1)), 1);
282259279Selan       intop = convert (int_type, TREE_OPERAND (intop, 0));
282359279Selan     }
282459279Selan 
282559279Selan   /* Convert the integer argument to a type the same size as a pointer
282659279Selan      so the multiply won't overflow spuriously.  */
282759279Selan 
282859279Selan   if (TYPE_PRECISION (TREE_TYPE (intop)) != POINTER_SIZE)
282959279Selan     intop = convert (type_for_size (POINTER_SIZE, 0), intop);
283059279Selan 
283159279Selan   /* Replace the integer argument
283259279Selan      with a suitable product by the object size.  */
283359279Selan 
283459279Selan   intop = build_binary_op (MULT_EXPR, intop, size_exp, 1);
283559279Selan 
283659279Selan   /* Create the sum or difference.  */
283759279Selan 
283859279Selan   result = build (resultcode, result_type, ptrop, intop);
283959279Selan 
284059279Selan   folded = fold (result);
284159279Selan   if (folded == result)
284259279Selan     TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
284359279Selan   return folded;
284459279Selan }
284559279Selan 
284659279Selan /* Return a tree for the difference of pointers OP0 and OP1.
284759279Selan    The resulting tree has type int.  */
284859279Selan 
284959279Selan static tree
pointer_diff(op0,op1)285059279Selan pointer_diff (op0, op1)
285159279Selan      register tree op0, op1;
285259279Selan {
285359279Selan   register tree result, folded;
285459279Selan   tree restype = ptrdiff_type_node;
285559279Selan 
285659279Selan   tree target_type = TREE_TYPE (TREE_TYPE (op0));
285759279Selan 
285859279Selan   if (pedantic || warn_pointer_arith)
285959279Selan     {
286059279Selan       if (TREE_CODE (target_type) == VOID_TYPE)
286159279Selan 	pedwarn ("pointer of type `void *' used in subtraction");
286259279Selan       if (TREE_CODE (target_type) == FUNCTION_TYPE)
286359279Selan 	pedwarn ("pointer to a function used in subtraction");
286459279Selan     }
286559279Selan 
286659279Selan   /* First do the subtraction as integers;
286759279Selan      then drop through to build the divide operator.  */
286859279Selan 
286959279Selan   op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
287059279Selan 			 convert (restype, op1), 1);
287159279Selan   op1 = c_size_in_bytes (target_type);
287259279Selan 
287359279Selan   /* Divide by the size, in easiest possible way.  */
287459279Selan 
287559279Selan   result = build (EXACT_DIV_EXPR, restype, op0, op1);
287659279Selan 
287759279Selan   folded = fold (result);
287859279Selan   if (folded == result)
287959279Selan     TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
288059279Selan   return folded;
288159279Selan }
288259279Selan 
288359279Selan /* Construct and perhaps optimize a tree representation
288459279Selan    for a unary operation.  CODE, a tree_code, specifies the operation
288559279Selan    and XARG is the operand.  NOCONVERT nonzero suppresses
288659279Selan    the default promotions (such as from short to int).  */
288759279Selan 
288859279Selan tree
build_unary_op(code,xarg,noconvert)288959279Selan build_unary_op (code, xarg, noconvert)
289059279Selan      enum tree_code code;
289159279Selan      tree xarg;
289259279Selan      int noconvert;
289359279Selan {
289459279Selan   /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
289559279Selan   register tree arg = xarg;
289659279Selan   register tree argtype = 0;
289759279Selan   register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
289859279Selan   char *errstring = NULL;
289959279Selan   tree val;
290059279Selan 
290159279Selan   if (typecode == ERROR_MARK)
290259279Selan     return error_mark_node;
290359279Selan   if (typecode == ENUMERAL_TYPE)
290459279Selan     typecode = INTEGER_TYPE;
290559279Selan 
290659279Selan   switch (code)
290759279Selan     {
290859279Selan     case CONVERT_EXPR:
290959279Selan       /* This is used for unary plus, because a CONVERT_EXPR
291059279Selan 	 is enough to prevent anybody from looking inside for
291159279Selan 	 associativity, but won't generate any code.  */
291259279Selan       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
291359279Selan         errstring = "wrong type argument to unary plus";
291459279Selan       else if (!noconvert)
291559279Selan 	arg = default_conversion (arg);
291659279Selan       break;
291759279Selan 
291859279Selan     case NEGATE_EXPR:
291959279Selan       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
292059279Selan         errstring = "wrong type argument to unary minus";
292159279Selan       else if (!noconvert)
292259279Selan 	arg = default_conversion (arg);
292359279Selan       break;
292459279Selan 
292559279Selan     case BIT_NOT_EXPR:
292659279Selan       if (typecode != INTEGER_TYPE)
292759279Selan         errstring = "wrong type argument to bit-complement";
292859279Selan       else if (!noconvert)
292959279Selan 	arg = default_conversion (arg);
293059279Selan       break;
293159279Selan 
293259279Selan     case ABS_EXPR:
293359279Selan       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
293459279Selan         errstring = "wrong type argument to abs";
293559279Selan       else if (!noconvert)
293659279Selan 	arg = default_conversion (arg);
293759279Selan       break;
293859279Selan 
293959279Selan     case TRUTH_NOT_EXPR:
294059279Selan       if (typecode != INTEGER_TYPE
294159279Selan 	  && typecode != REAL_TYPE && typecode != POINTER_TYPE
294259279Selan 	  /* These will convert to a pointer.  */
294359279Selan 	  && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
294459279Selan 	{
294559279Selan 	  errstring = "wrong type argument to unary exclamation mark";
294659279Selan 	  break;
294759279Selan 	}
294859279Selan       arg = truthvalue_conversion (arg);
294959279Selan       return invert_truthvalue (arg);
295059279Selan 
295159279Selan     case NOP_EXPR:
295259279Selan       break;
295359279Selan 
295459279Selan     case PREINCREMENT_EXPR:
295559279Selan     case POSTINCREMENT_EXPR:
295659279Selan     case PREDECREMENT_EXPR:
295759279Selan     case POSTDECREMENT_EXPR:
295859279Selan       /* Handle complex lvalues (when permitted)
295959279Selan 	 by reduction to simpler cases.  */
296059279Selan 
296159279Selan       val = unary_complex_lvalue (code, arg);
296259279Selan       if (val != 0)
296359279Selan 	return val;
296459279Selan 
296559279Selan       /* Report invalid types.  */
296659279Selan 
296759279Selan       if (typecode != POINTER_TYPE
296859279Selan 	  && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
296959279Selan 	{
297059279Selan 	  if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
297159279Selan 	    errstring ="wrong type argument to increment";
297259279Selan 	  else
297359279Selan 	    errstring ="wrong type argument to decrement";
297459279Selan 	  break;
297559279Selan 	}
297659279Selan 
297759279Selan       {
297859279Selan 	register tree inc;
297959279Selan 	tree result_type = TREE_TYPE (arg);
298059279Selan 
298159279Selan 	arg = get_unwidened (arg, 0);
298259279Selan 	argtype = TREE_TYPE (arg);
298359279Selan 
298459279Selan 	/* Compute the increment.  */
298559279Selan 
298659279Selan 	if (typecode == POINTER_TYPE)
298759279Selan 	  {
298859279Selan 	    if ((pedantic || warn_pointer_arith)
298959279Selan 		&& (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
299059279Selan 		    || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
299159279Selan 	      pedwarn ("wrong type argument to %s",
299259279Selan 		       ((code == PREINCREMENT_EXPR
299359279Selan 			 || code == POSTINCREMENT_EXPR)
299459279Selan 			? "increment" : "decrement"));
299559279Selan 	    inc = c_sizeof_nowarn (TREE_TYPE (result_type));
299659279Selan 	  }
299759279Selan 	else
299859279Selan 	  inc = integer_one_node;
299959279Selan 
300059279Selan 	inc = convert (argtype, inc);
300159279Selan 
300259279Selan 	/* Handle incrementing a cast-expression.  */
300359279Selan 
300459279Selan 	while (1)
300559279Selan 	  switch (TREE_CODE (arg))
300659279Selan 	    {
300759279Selan 	    case NOP_EXPR:
300859279Selan 	    case CONVERT_EXPR:
300959279Selan 	    case FLOAT_EXPR:
301059279Selan 	    case FIX_TRUNC_EXPR:
301159279Selan 	    case FIX_FLOOR_EXPR:
301259279Selan 	    case FIX_ROUND_EXPR:
301359279Selan 	    case FIX_CEIL_EXPR:
301459279Selan 	      pedantic_lvalue_warning (CONVERT_EXPR);
301559279Selan 	      /* If the real type has the same machine representation
301659279Selan 		 as the type it is cast to, we can make better output
301759279Selan 		 by adding directly to the inside of the cast.  */
301859279Selan 	      if ((TREE_CODE (TREE_TYPE (arg))
301959279Selan 		   == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
302059279Selan 		  && (TYPE_MODE (TREE_TYPE (arg))
302159279Selan 		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
302259279Selan 		arg = TREE_OPERAND (arg, 0);
302359279Selan 	      else
302459279Selan 		{
302559279Selan 		  tree incremented, modify, value;
302659279Selan 		  arg = stabilize_reference (arg);
302759279Selan 		  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
302859279Selan 		    value = arg;
302959279Selan 		  else
303059279Selan 		    value = save_expr (arg);
303159279Selan 		  incremented = build (((code == PREINCREMENT_EXPR
303259279Selan 					 || code == POSTINCREMENT_EXPR)
303359279Selan 					? PLUS_EXPR : MINUS_EXPR),
303459279Selan 				       argtype, value, inc);
303559279Selan 		  TREE_SIDE_EFFECTS (incremented) = 1;
303659279Selan 		  modify = build_modify_expr (arg, NOP_EXPR, incremented);
303759279Selan 		  value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
303859279Selan 		  TREE_USED (value) = 1;
303959279Selan 		  return value;
304059279Selan 		}
304159279Selan 	      break;
304259279Selan 
304359279Selan 	    default:
304459279Selan 	      goto give_up;
304559279Selan 	    }
304659279Selan       give_up:
304759279Selan 
304859279Selan 	/* Complain about anything else that is not a true lvalue.  */
304959279Selan 	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
305059279Selan 				    || code == POSTINCREMENT_EXPR)
305159279Selan 				   ? "increment" : "decrement")))
305259279Selan 	  return error_mark_node;
305359279Selan 
305459279Selan 	/* Report a read-only lvalue.  */
305559279Selan 	if (TREE_READONLY (arg))
305659279Selan 	  readonly_warning (arg,
305759279Selan 			    ((code == PREINCREMENT_EXPR
305859279Selan 			      || code == POSTINCREMENT_EXPR)
305959279Selan 			     ? "increment" : "decrement"));
306059279Selan 
306159279Selan 	val = build (code, TREE_TYPE (arg), arg, inc);
306259279Selan 	TREE_SIDE_EFFECTS (val) = 1;
306359279Selan 	val = convert (result_type, val);
306459279Selan 	if (TREE_CODE (val) != code)
306559279Selan 	  TREE_NO_UNUSED_WARNING (val) = 1;
306659279Selan 	return val;
306759279Selan       }
306859279Selan 
306959279Selan     case ADDR_EXPR:
307059279Selan       /* Note that this operation never does default_conversion
307159279Selan 	 regardless of NOCONVERT.  */
307259279Selan 
307359279Selan       /* Let &* cancel out to simplify resulting code.  */
307459279Selan       if (TREE_CODE (arg) == INDIRECT_REF)
307559279Selan 	{
307659279Selan 	  /* Don't let this be an lvalue.  */
307759279Selan 	  if (lvalue_p (TREE_OPERAND (arg, 0)))
307859279Selan 	    return non_lvalue (TREE_OPERAND (arg, 0));
307959279Selan 	  return TREE_OPERAND (arg, 0);
308059279Selan 	}
308159279Selan 
308259279Selan       /* For &x[y], return x+y */
308359279Selan       if (TREE_CODE (arg) == ARRAY_REF)
308459279Selan 	{
308559279Selan 	  if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
308659279Selan 	    return error_mark_node;
308759279Selan 	  return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
308859279Selan 				  TREE_OPERAND (arg, 1), 1);
308959279Selan 	}
309059279Selan 
309159279Selan       /* Handle complex lvalues (when permitted)
309259279Selan 	 by reduction to simpler cases.  */
309359279Selan       val = unary_complex_lvalue (code, arg);
309459279Selan       if (val != 0)
309559279Selan 	return val;
309659279Selan 
309759279Selan #if 0 /* Turned off because inconsistent;
309859279Selan 	 float f; *&(int)f = 3.4 stores in int format
309959279Selan 	 whereas (int)f = 3.4 stores in float format.  */
310059279Selan       /* Address of a cast is just a cast of the address
310159279Selan 	 of the operand of the cast.  */
310259279Selan       switch (TREE_CODE (arg))
310359279Selan 	{
310459279Selan 	case NOP_EXPR:
310559279Selan 	case CONVERT_EXPR:
310659279Selan 	case FLOAT_EXPR:
310759279Selan 	case FIX_TRUNC_EXPR:
310859279Selan 	case FIX_FLOOR_EXPR:
310959279Selan 	case FIX_ROUND_EXPR:
311059279Selan 	case FIX_CEIL_EXPR:
311159279Selan 	  if (pedantic)
311259279Selan 	    pedwarn ("ANSI C forbids the address of a cast expression");
311359279Selan 	  return convert (build_pointer_type (TREE_TYPE (arg)),
311459279Selan 			  build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0),
311559279Selan 					  0));
311659279Selan 	}
311759279Selan #endif
311859279Selan 
311959279Selan       /* Allow the address of a constructor if all the elements
312059279Selan 	 are constant.  */
312159279Selan       if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg))
312259279Selan 	;
312359279Selan       /* Anything not already handled and not a true memory reference
312459279Selan 	 is an error.  */
312559279Selan       else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'"))
312659279Selan 	return error_mark_node;
312759279Selan 
312859279Selan       /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
312959279Selan       argtype = TREE_TYPE (arg);
313059279Selan       /* If the lvalue is const or volatile,
313159279Selan 	 merge that into the type that the address will point to.  */
313259279Selan       if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
313359279Selan 	  || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
313459279Selan 	{
313559279Selan 	  if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
313659279Selan 	    argtype = c_build_type_variant (argtype,
313759279Selan 					    TREE_READONLY (arg),
313859279Selan 					    TREE_THIS_VOLATILE (arg));
313959279Selan 	}
314059279Selan 
314159279Selan       argtype = build_pointer_type (argtype);
314259279Selan 
314359279Selan       if (mark_addressable (arg) == 0)
314459279Selan 	return error_mark_node;
314559279Selan 
314659279Selan       {
314759279Selan 	tree addr;
314859279Selan 
314959279Selan 	if (TREE_CODE (arg) == COMPONENT_REF)
315059279Selan 	  {
315159279Selan 	    tree field = TREE_OPERAND (arg, 1);
315259279Selan 
315359279Selan 	    addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
315459279Selan 
315559279Selan 	    if (DECL_BIT_FIELD (field))
315659279Selan 	      {
315759279Selan 		error ("attempt to take address of bit-field structure member `%s'",
315859279Selan 		       IDENTIFIER_POINTER (DECL_NAME (field)));
315959279Selan 		return error_mark_node;
316059279Selan 	      }
316159279Selan 
316259279Selan 	    addr = convert (argtype, addr);
316359279Selan 
316459279Selan 	    if (! integer_zerop (DECL_FIELD_BITPOS (field)))
316559279Selan 	      {
316659279Selan 		tree offset
316759279Selan 		  = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
316859279Selan 				size_int (BITS_PER_UNIT));
316959279Selan 		int flag = TREE_CONSTANT (addr);
317059279Selan 		addr = fold (build (PLUS_EXPR, argtype,
317159279Selan 				    addr, convert (argtype, offset)));
317259279Selan 		TREE_CONSTANT (addr) = flag;
317359279Selan 	      }
317459279Selan 	  }
317559279Selan 	else
317659279Selan 	  addr = build1 (code, argtype, arg);
317759279Selan 
317859279Selan 	/* Address of a static or external variable or
317959279Selan 	   file-scope function counts as a constant.  */
318059279Selan 	if (staticp (arg)
318159279Selan 	    && ! (TREE_CODE (arg) == FUNCTION_DECL
318259279Selan 		  && DECL_CONTEXT (arg) != 0))
318359279Selan 	  TREE_CONSTANT (addr) = 1;
318459279Selan 	return addr;
318559279Selan       }
318659279Selan     }
318759279Selan 
318859279Selan   if (!errstring)
318959279Selan     {
319059279Selan       if (argtype == 0)
319159279Selan 	argtype = TREE_TYPE (arg);
319259279Selan       return fold (build1 (code, argtype, arg));
319359279Selan     }
319459279Selan 
319559279Selan   error (errstring);
319659279Selan   return error_mark_node;
319759279Selan }
319859279Selan 
319959279Selan #if 0
320059279Selan /* If CONVERSIONS is a conversion expression or a nested sequence of such,
320159279Selan    convert ARG with the same conversions in the same order
320259279Selan    and return the result.  */
320359279Selan 
320459279Selan static tree
320559279Selan convert_sequence (conversions, arg)
320659279Selan      tree conversions;
320759279Selan      tree arg;
320859279Selan {
320959279Selan   switch (TREE_CODE (conversions))
321059279Selan     {
321159279Selan     case NOP_EXPR:
321259279Selan     case CONVERT_EXPR:
321359279Selan     case FLOAT_EXPR:
321459279Selan     case FIX_TRUNC_EXPR:
321559279Selan     case FIX_FLOOR_EXPR:
321659279Selan     case FIX_ROUND_EXPR:
321759279Selan     case FIX_CEIL_EXPR:
321859279Selan       return convert (TREE_TYPE (conversions),
321959279Selan 		      convert_sequence (TREE_OPERAND (conversions, 0),
322059279Selan 					arg));
322159279Selan 
322259279Selan     default:
322359279Selan       return arg;
322459279Selan     }
322559279Selan }
322659279Selan #endif /* 0 */
322759279Selan 
322859279Selan /* Return nonzero if REF is an lvalue valid for this language.
322959279Selan    Lvalues can be assigned, unless their type has TYPE_READONLY.
323059279Selan    Lvalues can have their address taken, unless they have DECL_REGISTER.  */
323159279Selan 
323259279Selan int
lvalue_p(ref)323359279Selan lvalue_p (ref)
323459279Selan      tree ref;
323559279Selan {
323659279Selan   register enum tree_code code = TREE_CODE (ref);
323759279Selan 
323859279Selan   switch (code)
323959279Selan     {
324059279Selan     case COMPONENT_REF:
324159279Selan       return lvalue_p (TREE_OPERAND (ref, 0));
324259279Selan 
324359279Selan     case STRING_CST:
324459279Selan       return 1;
324559279Selan 
324659279Selan     case INDIRECT_REF:
324759279Selan     case ARRAY_REF:
324859279Selan     case VAR_DECL:
324959279Selan     case PARM_DECL:
325059279Selan     case RESULT_DECL:
325159279Selan     case ERROR_MARK:
325259279Selan       if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
325359279Selan 	  && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
325459279Selan 	return 1;
325559279Selan       break;
325659279Selan     }
325759279Selan   return 0;
325859279Selan }
325959279Selan 
326059279Selan /* Return nonzero if REF is an lvalue valid for this language;
326159279Selan    otherwise, print an error message and return zero.  */
326259279Selan 
326359279Selan int
lvalue_or_else(ref,string)326459279Selan lvalue_or_else (ref, string)
326559279Selan      tree ref;
326659279Selan      char *string;
326759279Selan {
326859279Selan   int win = lvalue_p (ref);
326959279Selan   if (! win)
327059279Selan     error ("invalid lvalue in %s", string);
327159279Selan   return win;
327259279Selan }
327359279Selan 
327459279Selan /* Apply unary lvalue-demanding operator CODE to the expression ARG
327559279Selan    for certain kinds of expressions which are not really lvalues
327659279Selan    but which we can accept as lvalues.
327759279Selan 
327859279Selan    If ARG is not a kind of expression we can handle, return zero.  */
327959279Selan 
328059279Selan static tree
unary_complex_lvalue(code,arg)328159279Selan unary_complex_lvalue (code, arg)
328259279Selan      enum tree_code code;
328359279Selan      tree arg;
328459279Selan {
328559279Selan   /* Handle (a, b) used as an "lvalue".  */
328659279Selan   if (TREE_CODE (arg) == COMPOUND_EXPR)
328759279Selan     {
328859279Selan       tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
328959279Selan       pedantic_lvalue_warning (COMPOUND_EXPR);
329059279Selan       return build (COMPOUND_EXPR, TREE_TYPE (real_result),
329159279Selan 		    TREE_OPERAND (arg, 0), real_result);
329259279Selan     }
329359279Selan 
329459279Selan   /* Handle (a ? b : c) used as an "lvalue".  */
329559279Selan   if (TREE_CODE (arg) == COND_EXPR)
329659279Selan     {
329759279Selan       pedantic_lvalue_warning (COND_EXPR);
329859279Selan       return (build_conditional_expr
329959279Selan 	      (TREE_OPERAND (arg, 0),
330059279Selan 	       build_unary_op (code, TREE_OPERAND (arg, 1), 0),
330159279Selan 	       build_unary_op (code, TREE_OPERAND (arg, 2), 0)));
330259279Selan     }
330359279Selan 
330459279Selan   return 0;
330559279Selan }
330659279Selan 
330759279Selan /* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
330859279Selan    COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
330959279Selan 
331059279Selan static void
pedantic_lvalue_warning(code)331159279Selan pedantic_lvalue_warning (code)
331259279Selan      enum tree_code code;
331359279Selan {
331459279Selan   if (pedantic)
331559279Selan     pedwarn ("ANSI C forbids use of %s expressions as lvalues",
331659279Selan 	     code == COND_EXPR ? "conditional"
331759279Selan 	     : code == COMPOUND_EXPR ? "compound" : "cast");
331859279Selan }
331959279Selan 
332059279Selan /* Warn about storing in something that is `const'.  */
332159279Selan 
332259279Selan void
readonly_warning(arg,string)332359279Selan readonly_warning (arg, string)
332459279Selan      tree arg;
332559279Selan      char *string;
332659279Selan {
332759279Selan   char buf[80];
332859279Selan   strcpy (buf, string);
332959279Selan 
333059279Selan   if (TREE_CODE (arg) == COMPONENT_REF)
333159279Selan     {
333259279Selan       if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
333359279Selan 	readonly_warning (TREE_OPERAND (arg, 0), string);
333459279Selan       else
333559279Selan 	{
333659279Selan 	  strcat (buf, " of read-only member `%s'");
333759279Selan 	  pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
333859279Selan 	}
333959279Selan     }
334059279Selan   else if (TREE_CODE (arg) == VAR_DECL)
334159279Selan     {
334259279Selan       strcat (buf, " of read-only variable `%s'");
334359279Selan       pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg)));
334459279Selan     }
334559279Selan   else
334659279Selan     {
334759279Selan       pedwarn ("%s of read-only location", buf);
334859279Selan     }
334959279Selan }
335059279Selan 
335159279Selan /* Mark EXP saying that we need to be able to take the
335259279Selan    address of it; it should not be allocated in a register.
335359279Selan    Value is 1 if successful.  */
335459279Selan 
335559279Selan int
mark_addressable(exp)335659279Selan mark_addressable (exp)
335759279Selan      tree exp;
335859279Selan {
335959279Selan   register tree x = exp;
336059279Selan   while (1)
336159279Selan     switch (TREE_CODE (x))
336259279Selan       {
336359279Selan       case ADDR_EXPR:
336459279Selan       case COMPONENT_REF:
336559279Selan       case ARRAY_REF:
336659279Selan 	x = TREE_OPERAND (x, 0);
336759279Selan 	break;
336859279Selan 
336959279Selan       case CONSTRUCTOR:
337059279Selan 	TREE_ADDRESSABLE (x) = 1;
337159279Selan 	return 1;
337259279Selan 
337359279Selan       case VAR_DECL:
337459279Selan       case CONST_DECL:
337559279Selan       case PARM_DECL:
337659279Selan       case RESULT_DECL:
337759279Selan 	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
337859279Selan 	    && DECL_NONLOCAL (x))
337959279Selan 	  {
338059279Selan 	    if (TREE_PUBLIC (x))
338159279Selan 	      {
338259279Selan 		error ("global register variable `%s' used in nested function",
338359279Selan 		       IDENTIFIER_POINTER (DECL_NAME (x)));
338459279Selan 		return 0;
338559279Selan 	      }
338659279Selan 	    pedwarn ("register variable `%s' used in nested function",
338759279Selan 		     IDENTIFIER_POINTER (DECL_NAME (x)));
338859279Selan 	  }
338959279Selan 	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
339059279Selan 	  {
339159279Selan 	    if (TREE_PUBLIC (x))
339259279Selan 	      {
339359279Selan 		error ("address of global register variable `%s' requested",
339459279Selan 		       IDENTIFIER_POINTER (DECL_NAME (x)));
339559279Selan 		return 0;
339659279Selan 	      }
339759279Selan 	    pedwarn ("address of register variable `%s' requested",
339859279Selan 		     IDENTIFIER_POINTER (DECL_NAME (x)));
339959279Selan 	  }
340059279Selan 	put_var_into_stack (x);
340159279Selan 
340259279Selan 	/* drops in */
340359279Selan       case FUNCTION_DECL:
340459279Selan 	TREE_ADDRESSABLE (x) = 1;
340559279Selan #if 0  /* poplevel deals with this now.  */
340659279Selan 	if (DECL_CONTEXT (x) == 0)
340759279Selan 	  TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
340859279Selan #endif
340959279Selan 
341059279Selan       default:
341159279Selan 	return 1;
341259279Selan     }
341359279Selan }
341459279Selan 
341559279Selan /* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
341659279Selan 
341759279Selan tree
build_conditional_expr(ifexp,op1,op2)341859279Selan build_conditional_expr (ifexp, op1, op2)
341959279Selan      tree ifexp, op1, op2;
342059279Selan {
342159279Selan   register tree type1;
342259279Selan   register tree type2;
342359279Selan   register enum tree_code code1;
342459279Selan   register enum tree_code code2;
342559279Selan   register tree result_type = NULL;
342659279Selan 
342759279Selan   /* If second operand is omitted, it is the same as the first one;
342859279Selan      make sure it is calculated only once.  */
342959279Selan   if (op1 == 0)
343059279Selan     {
343159279Selan       if (pedantic)
343259279Selan 	pedwarn ("ANSI C forbids omitting the middle term of a ?: expression");
343359279Selan       ifexp = op1 = save_expr (ifexp);
343459279Selan     }
343559279Selan 
343659279Selan   ifexp = truthvalue_conversion (default_conversion (ifexp));
343759279Selan 
343859279Selan   if (TREE_CODE (ifexp) == ERROR_MARK
343959279Selan       || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
344059279Selan       || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
344159279Selan     return error_mark_node;
344259279Selan 
344359279Selan #if 0 /* Produces wrong result if within sizeof.  */
344459279Selan   /* Don't promote the operands separately if they promote
344559279Selan      the same way.  Return the unpromoted type and let the combined
344659279Selan      value get promoted if necessary.  */
344759279Selan 
344859279Selan   if (TREE_TYPE (op1) == TREE_TYPE (op2)
344959279Selan       && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE
345059279Selan       && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE
345159279Selan       && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE)
345259279Selan     {
345359279Selan       if (TREE_CODE (ifexp) == INTEGER_CST)
345459279Selan 	return (integer_zerop (ifexp) ? op2 : op1);
345559279Selan 
345659279Selan       return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2));
345759279Selan     }
345859279Selan #endif
345959279Selan 
346059279Selan   /* They don't match; promote them both and then try to reconcile them.  */
346159279Selan 
346259279Selan   if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
346359279Selan     op1 = default_conversion (op1);
346459279Selan   if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
346559279Selan     op2 = default_conversion (op2);
346659279Selan 
346759279Selan   type1 = TREE_TYPE (op1);
346859279Selan   code1 = TREE_CODE (type1);
346959279Selan   type2 = TREE_TYPE (op2);
347059279Selan   code2 = TREE_CODE (type2);
347159279Selan 
347259279Selan   /* Quickly detect the usual case where op1 and op2 have the same type
347359279Selan      after promotion.  */
347459279Selan   if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
347559279Selan     {
347659279Selan       if (type1 == type2)
347759279Selan 	result_type = type1;
347859279Selan       else
347959279Selan 	result_type = TYPE_MAIN_VARIANT (type1);
348059279Selan     }
348159279Selan   else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
348259279Selan            && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
348359279Selan     {
348459279Selan       result_type = common_type (type1, type2);
348559279Selan     }
348659279Selan   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
348759279Selan     {
348859279Selan       if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
348959279Selan 	pedwarn ("ANSI C forbids conditional expr with only one void side");
349059279Selan       result_type = void_type_node;
349159279Selan     }
349259279Selan   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
349359279Selan     {
349459279Selan       if (comp_target_types (type1, type2))
349559279Selan 	result_type = common_type (type1, type2);
349659279Selan       else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node)
349759279Selan 	result_type = qualify_type (type2, type1);
349859279Selan       else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node)
349959279Selan 	result_type = qualify_type (type1, type2);
350059279Selan       else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node)
350159279Selan 	{
350259279Selan 	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
350359279Selan 	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
350459279Selan 	  result_type = qualify_type (type1, type2);
350559279Selan 	}
350659279Selan       else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node)
350759279Selan 	{
350859279Selan 	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
350959279Selan 	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
351059279Selan 	  result_type = qualify_type (type2, type1);
351159279Selan 	}
351259279Selan       else
351359279Selan 	{
351459279Selan 	  pedwarn ("pointer type mismatch in conditional expression");
351559279Selan 	  result_type = build_pointer_type (void_type_node);
351659279Selan 	}
351759279Selan     }
351859279Selan   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
351959279Selan     {
352059279Selan       if (! integer_zerop (op2))
352159279Selan 	pedwarn ("pointer/integer type mismatch in conditional expression");
352259279Selan       else
352359279Selan 	{
352459279Selan 	  op2 = null_pointer_node;
352559279Selan #if 0  /* The spec seems to say this is permitted.  */
352659279Selan 	  if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE)
352759279Selan 	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
352859279Selan #endif
352959279Selan 	}
353059279Selan       result_type = type1;
353159279Selan     }
353259279Selan   else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
353359279Selan     {
353459279Selan       if (!integer_zerop (op1))
353559279Selan 	pedwarn ("pointer/integer type mismatch in conditional expression");
353659279Selan       else
353759279Selan 	{
353859279Selan 	  op1 = null_pointer_node;
353959279Selan #if 0  /* The spec seems to say this is permitted.  */
354059279Selan 	  if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
354159279Selan 	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
354259279Selan #endif
354359279Selan 	}
354459279Selan       result_type = type2;
354559279Selan     }
354659279Selan 
354759279Selan   if (!result_type)
354859279Selan     {
354959279Selan       if (flag_cond_mismatch)
355059279Selan 	result_type = void_type_node;
355159279Selan       else
355259279Selan 	{
355359279Selan 	  error ("type mismatch in conditional expression");
355459279Selan 	  return error_mark_node;
355559279Selan 	}
355659279Selan     }
355759279Selan 
355859279Selan   /* Merge const and volatile flags of the incoming types.  */
355959279Selan   result_type
356059279Selan     = build_type_variant (result_type,
356159279Selan 			  TREE_READONLY (op1) || TREE_READONLY (op2),
356259279Selan 			  TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
356359279Selan 
356459279Selan   if (result_type != TREE_TYPE (op1))
356559279Selan     op1 = convert (result_type, op1);
356659279Selan   if (result_type != TREE_TYPE (op2))
356759279Selan     op2 = convert (result_type, op2);
356859279Selan 
356959279Selan #if 0
357059279Selan   if (code1 == RECORD_TYPE || code1 == UNION_TYPE)
357159279Selan     {
357259279Selan       result_type = TREE_TYPE (op1);
357359279Selan       if (TREE_CONSTANT (ifexp))
357459279Selan 	return (integer_zerop (ifexp) ? op2 : op1);
357559279Selan 
357659279Selan       if (TYPE_MODE (result_type) == BLKmode)
357759279Selan 	{
357859279Selan 	  register tree tempvar
357959279Selan 	    = build_decl (VAR_DECL, NULL_TREE, result_type);
358059279Selan 	  register tree xop1 = build_modify_expr (tempvar, op1);
358159279Selan 	  register tree xop2 = build_modify_expr (tempvar, op2);
358259279Selan 	  register tree result = fold (build (COND_EXPR, result_type,
358359279Selan 					      ifexp, xop1, xop2));
358459279Selan 
358559279Selan 	  layout_decl (tempvar, TYPE_ALIGN (result_type));
358659279Selan 	  /* No way to handle variable-sized objects here.
358759279Selan 	     I fear that the entire handling of BLKmode conditional exprs
358859279Selan 	     needs to be redone.  */
358959279Selan 	  if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST)
359059279Selan 	    abort ();
359159279Selan 	  DECL_RTL (tempvar)
359259279Selan 	    = assign_stack_local (DECL_MODE (tempvar),
359359279Selan 				  (TREE_INT_CST_LOW (DECL_SIZE (tempvar))
359459279Selan 				   + BITS_PER_UNIT - 1)
359559279Selan 				  / BITS_PER_UNIT,
359659279Selan 				  0);
359759279Selan 
359859279Selan 	  TREE_SIDE_EFFECTS (result)
359959279Selan 	    = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1)
360059279Selan 	      | TREE_SIDE_EFFECTS (op2);
360159279Selan 	  return build (COMPOUND_EXPR, result_type, result, tempvar);
360259279Selan 	}
360359279Selan     }
360459279Selan #endif /* 0 */
360559279Selan 
360659279Selan   if (TREE_CODE (ifexp) == INTEGER_CST)
360759279Selan     return (integer_zerop (ifexp) ? op2 : op1);
360859279Selan   return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
360959279Selan }
361059279Selan 
361159279Selan /* Given a list of expressions, return a compound expression
361259279Selan    that performs them all and returns the value of the last of them.  */
361359279Selan 
361459279Selan tree
build_compound_expr(list)361559279Selan build_compound_expr (list)
361659279Selan      tree list;
361759279Selan {
361859279Selan   register tree rest;
361959279Selan 
362059279Selan   if (TREE_CHAIN (list) == 0)
362159279Selan     {
362259279Selan #if 0 /* If something inside inhibited lvalueness, we should not override.  */
362359279Selan       /* Consider (x, y+0), which is not an lvalue since y+0 is not.  */
362459279Selan 
362559279Selan       /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
362659279Selan       if (TREE_CODE (list) == NON_LVALUE_EXPR)
362759279Selan 	list = TREE_OPERAND (list, 0);
362859279Selan #endif
362959279Selan 
363059279Selan 	return TREE_VALUE (list);
363159279Selan     }
363259279Selan 
363359279Selan   if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0)
363459279Selan     {
363559279Selan       /* Convert arrays to pointers when there really is a comma operator.  */
363659279Selan       if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE)
363759279Selan 	TREE_VALUE (TREE_CHAIN (list))
363859279Selan 	  = default_conversion (TREE_VALUE (TREE_CHAIN (list)));
363959279Selan     }
364059279Selan 
364159279Selan   rest = build_compound_expr (TREE_CHAIN (list));
364259279Selan 
364359279Selan   if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
364459279Selan     return rest;
364559279Selan 
364659279Selan   return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
364759279Selan }
364859279Selan 
364959279Selan /* Build an expression representing a cast to type TYPE of expression EXPR.  */
365059279Selan 
365159279Selan tree
build_c_cast(type,expr)365259279Selan build_c_cast (type, expr)
365359279Selan      register tree type;
365459279Selan      tree expr;
365559279Selan {
365659279Selan   register tree value = expr;
365759279Selan 
365859279Selan   if (type == error_mark_node || expr == error_mark_node)
365959279Selan     return error_mark_node;
366059279Selan   type = TYPE_MAIN_VARIANT (type);
366159279Selan 
366259279Selan #if 0
366359279Selan   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
366459279Selan   if (TREE_CODE (value) == NON_LVALUE_EXPR)
366559279Selan     value = TREE_OPERAND (value, 0);
366659279Selan #endif
366759279Selan 
366859279Selan   if (TREE_CODE (type) == ARRAY_TYPE)
366959279Selan     {
367059279Selan       error ("cast specifies array type");
367159279Selan       return error_mark_node;
367259279Selan     }
367359279Selan 
367459279Selan   if (TREE_CODE (type) == FUNCTION_TYPE)
367559279Selan     {
367659279Selan       error ("cast specifies function type");
367759279Selan       return error_mark_node;
367859279Selan     }
367959279Selan 
368059279Selan   if (type == TREE_TYPE (value))
368159279Selan     {
368259279Selan       if (pedantic)
368359279Selan 	{
368459279Selan 	  if (TREE_CODE (type) == RECORD_TYPE
368559279Selan 	      || TREE_CODE (type) == UNION_TYPE)
368659279Selan 	    pedwarn ("ANSI C forbids casting nonscalar to the same type");
368759279Selan 	}
368859279Selan     }
368959279Selan   else if (TREE_CODE (type) == UNION_TYPE)
369059279Selan     {
369159279Selan       tree field;
369259279Selan       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
369359279Selan 	if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
369459279Selan 		       TYPE_MAIN_VARIANT (TREE_TYPE (value))))
369559279Selan 	  break;
369659279Selan 
369759279Selan       if (field)
369859279Selan 	{
369959279Selan 	  char *name;
370059279Selan 	  tree nvalue;
370159279Selan 
370259279Selan 	  if (pedantic)
370359279Selan 	    pedwarn ("ANSI C forbids casts to union type");
370459279Selan 	  if (TYPE_NAME (type) != 0)
370559279Selan 	    {
370659279Selan 	      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
370759279Selan 		name = IDENTIFIER_POINTER (TYPE_NAME (type));
370859279Selan 	      else
370959279Selan 		name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
371059279Selan 	    }
371159279Selan 	  else
371259279Selan 	    name = "";
371359279Selan 	  return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE,
371459279Selan 					      build_tree_list (field, value)),
371559279Selan 			      NULL_PTR, 0, 0, name);
371659279Selan 	}
371759279Selan       error ("cast to union type from type not present in union");
371859279Selan       return error_mark_node;
371959279Selan     }
372059279Selan   else
372159279Selan     {
372259279Selan       tree otype;
372359279Selan       /* Convert functions and arrays to pointers,
372459279Selan 	 but don't convert any other types.  */
372559279Selan       if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
372659279Selan 	  || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE)
372759279Selan 	value = default_conversion (value);
372859279Selan       otype = TREE_TYPE (value);
372959279Selan 
373059279Selan       /* Optionally warn about potentially worrisome casts.  */
373159279Selan 
373259279Selan       if (warn_cast_qual
373359279Selan 	  && TREE_CODE (type) == POINTER_TYPE
373459279Selan 	  && TREE_CODE (otype) == POINTER_TYPE)
373559279Selan 	{
373659279Selan 	  if (TYPE_VOLATILE (TREE_TYPE (otype))
373759279Selan 	      && ! TYPE_VOLATILE (TREE_TYPE (type)))
373859279Selan 	    pedwarn ("cast discards `volatile' from pointer target type");
373959279Selan 	  if (TYPE_READONLY (TREE_TYPE (otype))
374059279Selan 	      && ! TYPE_READONLY (TREE_TYPE (type)))
374159279Selan 	    pedwarn ("cast discards `const' from pointer target type");
374259279Selan 	}
374359279Selan 
374459279Selan       /* Warn about possible alignment problems.  */
374559279Selan       if (STRICT_ALIGNMENT && warn_cast_align
374659279Selan 	  && TREE_CODE (type) == POINTER_TYPE
374759279Selan 	  && TREE_CODE (otype) == POINTER_TYPE
374859279Selan 	  && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
374959279Selan 	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
375059279Selan 	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
375159279Selan 	warning ("cast increases required alignment of target type");
375259279Selan 
375359279Selan       if (TREE_CODE (type) == INTEGER_TYPE
375459279Selan 	  && TREE_CODE (otype) == POINTER_TYPE
375559279Selan 	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
375659279Selan 	  && !TREE_CONSTANT (value))
375759279Selan 	warning ("cast from pointer to integer of different size");
375859279Selan 
375959279Selan       if (TREE_CODE (type) == POINTER_TYPE
376059279Selan 	  && TREE_CODE (otype) == INTEGER_TYPE
376159279Selan 	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
376259279Selan #if 0
376359279Selan 	  /* Don't warn about converting 0 to pointer,
376459279Selan 	     provided the 0 was explicit--not cast or made by folding.  */
376559279Selan 	  && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))
376659279Selan #endif
376759279Selan 	  /* Don't warn about converting any constant.  */
376859279Selan 	  && !TREE_CONSTANT (value))
376959279Selan 	warning ("cast to pointer from integer of different size");
377059279Selan 
377159279Selan       value = convert (type, value);
377259279Selan     }
377359279Selan 
377459279Selan   if (value == expr && pedantic)
377559279Selan     {
377659279Selan       /* If pedantic, don't let a cast be an lvalue.  */
377759279Selan       return non_lvalue (value);
377859279Selan     }
377959279Selan   return value;
378059279Selan }
378159279Selan 
378259279Selan /* Build an assignment expression of lvalue LHS from value RHS.
378359279Selan    MODIFYCODE is the code for a binary operator that we use
378459279Selan    to combine the old value of LHS with RHS to get the new value.
378559279Selan    Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.  */
378659279Selan 
378759279Selan tree
build_modify_expr(lhs,modifycode,rhs)378859279Selan build_modify_expr (lhs, modifycode, rhs)
378959279Selan      tree lhs, rhs;
379059279Selan      enum tree_code modifycode;
379159279Selan {
379259279Selan   register tree result;
379359279Selan   tree newrhs;
379459279Selan   tree lhstype = TREE_TYPE (lhs);
379559279Selan   tree olhstype = lhstype;
379659279Selan 
379759279Selan   /* Types that aren't fully specified cannot be used in assignments.  */
379859279Selan   lhs = require_complete_type (lhs);
379959279Selan 
380059279Selan   /* Avoid duplicate error messages from operands that had errors.  */
380159279Selan   if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
380259279Selan     return error_mark_node;
380359279Selan 
380459279Selan   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
380559279Selan   /* Do not use STRIP_NOPS here.  We do not want an enumerator
380659279Selan      whose value is 0 to count as a null pointer constant.  */
380759279Selan   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
380859279Selan     rhs = TREE_OPERAND (rhs, 0);
380959279Selan 
381059279Selan   newrhs = rhs;
381159279Selan 
381259279Selan   /* Handle control structure constructs used as "lvalues".  */
381359279Selan 
381459279Selan   switch (TREE_CODE (lhs))
381559279Selan     {
381659279Selan       /* Handle (a, b) used as an "lvalue".  */
381759279Selan     case COMPOUND_EXPR:
381859279Selan       pedantic_lvalue_warning (COMPOUND_EXPR);
381959279Selan       return build (COMPOUND_EXPR, lhstype,
382059279Selan 		    TREE_OPERAND (lhs, 0),
382159279Selan 		    build_modify_expr (TREE_OPERAND (lhs, 1),
382259279Selan 				       modifycode, rhs));
382359279Selan 
382459279Selan       /* Handle (a ? b : c) used as an "lvalue".  */
382559279Selan     case COND_EXPR:
382659279Selan       pedantic_lvalue_warning (COND_EXPR);
382759279Selan       rhs = save_expr (rhs);
382859279Selan       {
382959279Selan 	/* Produce (a ? (b = rhs) : (c = rhs))
383059279Selan 	   except that the RHS goes through a save-expr
383159279Selan 	   so the code to compute it is only emitted once.  */
383259279Selan 	tree cond
383359279Selan 	  = build_conditional_expr (TREE_OPERAND (lhs, 0),
383459279Selan 				    build_modify_expr (TREE_OPERAND (lhs, 1),
383559279Selan 						       modifycode, rhs),
383659279Selan 				    build_modify_expr (TREE_OPERAND (lhs, 2),
383759279Selan 						       modifycode, rhs));
383859279Selan 	/* Make sure the code to compute the rhs comes out
383959279Selan 	   before the split.  */
384059279Selan 	return build (COMPOUND_EXPR, TREE_TYPE (lhs),
384159279Selan 		      /* But cast it to void to avoid an "unused" error.  */
384259279Selan 		      convert (void_type_node, rhs), cond);
384359279Selan       }
384459279Selan     }
384559279Selan 
384659279Selan   /* If a binary op has been requested, combine the old LHS value with the RHS
384759279Selan      producing the value we should actually store into the LHS.  */
384859279Selan 
384959279Selan   if (modifycode != NOP_EXPR)
385059279Selan     {
385159279Selan       lhs = stabilize_reference (lhs);
385259279Selan       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
385359279Selan     }
385459279Selan 
385559279Selan   /* Handle a cast used as an "lvalue".
385659279Selan      We have already performed any binary operator using the value as cast.
385759279Selan      Now convert the result to the cast type of the lhs,
385859279Selan      and then true type of the lhs and store it there;
385959279Selan      then convert result back to the cast type to be the value
386059279Selan      of the assignment.  */
386159279Selan 
386259279Selan   switch (TREE_CODE (lhs))
386359279Selan     {
386459279Selan     case NOP_EXPR:
386559279Selan     case CONVERT_EXPR:
386659279Selan     case FLOAT_EXPR:
386759279Selan     case FIX_TRUNC_EXPR:
386859279Selan     case FIX_FLOOR_EXPR:
386959279Selan     case FIX_ROUND_EXPR:
387059279Selan     case FIX_CEIL_EXPR:
387159279Selan       if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
387259279Selan 	  || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE)
387359279Selan 	newrhs = default_conversion (newrhs);
387459279Selan       {
387559279Selan 	tree inner_lhs = TREE_OPERAND (lhs, 0);
387659279Selan 	tree result;
387759279Selan 	result = build_modify_expr (inner_lhs, NOP_EXPR,
387859279Selan 				    convert (TREE_TYPE (inner_lhs),
387959279Selan 					     convert (lhstype, newrhs)));
388059279Selan 	pedantic_lvalue_warning (CONVERT_EXPR);
388159279Selan 	return convert (TREE_TYPE (lhs), result);
388259279Selan       }
388359279Selan     }
388459279Selan 
388559279Selan   /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
388659279Selan      Reject anything strange now.  */
388759279Selan 
388859279Selan   if (!lvalue_or_else (lhs, "assignment"))
388959279Selan     return error_mark_node;
389059279Selan 
389159279Selan   /* Warn about storing in something that is `const'.  */
389259279Selan 
389359279Selan   if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
389459279Selan       || ((TREE_CODE (lhstype) == RECORD_TYPE
389559279Selan 	   || TREE_CODE (lhstype) == UNION_TYPE)
389659279Selan 	  && C_TYPE_FIELDS_READONLY (lhstype)))
389759279Selan     readonly_warning (lhs, "assignment");
389859279Selan 
389959279Selan   /* If storing into a structure or union member,
390059279Selan      it has probably been given type `int'.
390159279Selan      Compute the type that would go with
390259279Selan      the actual amount of storage the member occupies.  */
390359279Selan 
390459279Selan   if (TREE_CODE (lhs) == COMPONENT_REF
390559279Selan       && (TREE_CODE (lhstype) == INTEGER_TYPE
390659279Selan 	  || TREE_CODE (lhstype) == REAL_TYPE
390759279Selan 	  || TREE_CODE (lhstype) == ENUMERAL_TYPE))
390859279Selan     lhstype = TREE_TYPE (get_unwidened (lhs, 0));
390959279Selan 
391059279Selan   /* If storing in a field that is in actuality a short or narrower than one,
391159279Selan      we must store in the field in its actual type.  */
391259279Selan 
391359279Selan   if (lhstype != TREE_TYPE (lhs))
391459279Selan     {
391559279Selan       lhs = copy_node (lhs);
391659279Selan       TREE_TYPE (lhs) = lhstype;
391759279Selan     }
391859279Selan 
391959279Selan   /* Convert new value to destination type.  */
392059279Selan 
392159279Selan   newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
392259279Selan 				   NULL_TREE, 0);
392359279Selan   if (TREE_CODE (newrhs) == ERROR_MARK)
392459279Selan     return error_mark_node;
392559279Selan 
392659279Selan   result = build (MODIFY_EXPR, lhstype, lhs, newrhs);
392759279Selan   TREE_SIDE_EFFECTS (result) = 1;
392859279Selan 
392959279Selan   /* If we got the LHS in a different type for storing in,
393059279Selan      convert the result back to the nominal type of LHS
393159279Selan      so that the value we return always has the same type
393259279Selan      as the LHS argument.  */
393359279Selan 
393459279Selan   if (olhstype == TREE_TYPE (result))
393559279Selan     return result;
393659279Selan   return convert_for_assignment (olhstype, result, "assignment", NULL_TREE, 0);
393759279Selan }
393859279Selan 
393959279Selan /* Convert value RHS to type TYPE as preparation for an assignment
394059279Selan    to an lvalue of type TYPE.
394159279Selan    The real work of conversion is done by `convert'.
394259279Selan    The purpose of this function is to generate error messages
394359279Selan    for assignments that are not allowed in C.
394459279Selan    ERRTYPE is a string to use in error messages:
394559279Selan    "assignment", "return", etc.  If it is null, this is parameter passing
394659279Selan    for a function call (and different error messages are output).  Otherwise,
394759279Selan    it may be a name stored in the spelling stack and interpreted by
394859279Selan    get_spelling.
394959279Selan 
395059279Selan    FUNNAME is the name of the function being called,
395159279Selan    as an IDENTIFIER_NODE, or null.
395259279Selan    PARMNUM is the number of the argument, for printing in error messages.  */
395359279Selan 
395459279Selan static tree
convert_for_assignment(type,rhs,errtype,funname,parmnum)395559279Selan convert_for_assignment (type, rhs, errtype, funname, parmnum)
395659279Selan      tree type, rhs;
395759279Selan      char *errtype;
395859279Selan      tree funname;
395959279Selan      int parmnum;
396059279Selan {
396159279Selan   register enum tree_code codel = TREE_CODE (type);
396259279Selan   register tree rhstype;
396359279Selan   register enum tree_code coder;
396459279Selan 
396559279Selan   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
396659279Selan   /* Do not use STRIP_NOPS here.  We do not want an enumerator
396759279Selan      whose value is 0 to count as a null pointer constant.  */
396859279Selan   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
396959279Selan     rhs = TREE_OPERAND (rhs, 0);
397059279Selan 
397159279Selan   if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
397259279Selan       || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE)
397359279Selan     rhs = default_conversion (rhs);
397459279Selan 
397559279Selan   rhstype = TREE_TYPE (rhs);
397659279Selan   coder = TREE_CODE (rhstype);
397759279Selan 
397859279Selan   if (coder == ERROR_MARK)
397959279Selan     return error_mark_node;
398059279Selan 
398159279Selan   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
398259279Selan     return rhs;
398359279Selan 
398459279Selan   if (coder == VOID_TYPE)
398559279Selan     {
398659279Selan       error ("void value not ignored as it ought to be");
398759279Selan       return error_mark_node;
398859279Selan     }
398959279Selan   /* Arithmetic types all interconvert, and enum is treated like int.  */
399059279Selan   if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE)
399159279Selan        &&
399259279Selan       (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE))
399359279Selan     {
399459279Selan       return convert (type, rhs);
399559279Selan     }
399659279Selan   /* Conversions among pointers */
399759279Selan   else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
399859279Selan     {
399959279Selan       register tree ttl = TREE_TYPE (type);
400059279Selan       register tree ttr = TREE_TYPE (rhstype);
400159279Selan 
400259279Selan       /* Any non-function converts to a [const][volatile] void *
400359279Selan 	 and vice versa; otherwise, targets must be the same.
400459279Selan 	 Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
400559279Selan       if (TYPE_MAIN_VARIANT (ttl) == void_type_node
400659279Selan 	  || TYPE_MAIN_VARIANT (ttr) == void_type_node
400759279Selan 	  || comp_target_types (type, rhstype)
400859279Selan 	  || (!pedantic	  /* Unless pedantic, mix signed and unsigned.  */
400959279Selan 	      && TREE_CODE (ttl) == INTEGER_TYPE
401059279Selan 	      && TREE_CODE (ttr) == INTEGER_TYPE
401159279Selan 	      && TYPE_PRECISION (ttl) == TYPE_PRECISION (ttr)))
401259279Selan 	{
401359279Selan 	  if (pedantic
401459279Selan 	      && ((TYPE_MAIN_VARIANT (ttl) == void_type_node
401559279Selan 		   && TREE_CODE (ttr) == FUNCTION_TYPE)
401659279Selan 		  ||
401759279Selan 		  (TYPE_MAIN_VARIANT (ttr) == void_type_node
401859279Selan 		   && !integer_zerop (rhs)
401959279Selan 		   && TREE_CODE (ttl) == FUNCTION_TYPE)))
402059279Selan 	    warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
402159279Selan 				 get_spelling (errtype), funname, parmnum);
402259279Selan 	  /* Const and volatile mean something different for function types,
402359279Selan 	     so the usual warnings are not appropriate.  */
402459279Selan 	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
402559279Selan 		   || TREE_CODE (ttl) != FUNCTION_TYPE)
402659279Selan 	    {
402759279Selan 	      if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
402859279Selan 		warn_for_assignment ("%s discards `const' from pointer target type",
402959279Selan 				     get_spelling (errtype), funname, parmnum);
403059279Selan 	      if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
403159279Selan 		warn_for_assignment ("%s discards `volatile' from pointer target type",
403259279Selan 				     get_spelling (errtype), funname, parmnum);
403359279Selan 	    }
403459279Selan 	  else
403559279Selan 	    {
403659279Selan 	      /* Because const and volatile on functions are restrictions
403759279Selan 		 that say the function will not do certain things,
403859279Selan 		 it is okay to use a const or volatile function
403959279Selan 		 where an ordinary one is wanted, but not vice-versa.  */
404059279Selan 	      if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr))
404159279Selan 		warn_for_assignment ("%s makes `const *' function pointer from non-const",
404259279Selan 				     get_spelling (errtype), funname, parmnum);
404359279Selan 	      if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr))
404459279Selan 		warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile",
404559279Selan 				     get_spelling (errtype), funname, parmnum);
404659279Selan 	    }
404759279Selan 	}
404859279Selan       else if (unsigned_type (TYPE_MAIN_VARIANT (ttl))
404959279Selan 	       == unsigned_type (TYPE_MAIN_VARIANT (ttr)))
405059279Selan 	warn_for_assignment ("pointer targets in %s differ in signedness",
405159279Selan 			     get_spelling (errtype), funname, parmnum);
405259279Selan       else
405359279Selan 	warn_for_assignment ("%s from incompatible pointer type",
405459279Selan 			     get_spelling (errtype), funname, parmnum);
405559279Selan       return convert (type, rhs);
405659279Selan     }
405759279Selan   else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
405859279Selan     {
405959279Selan       /* An explicit constant 0 can convert to a pointer,
406059279Selan 	 but not a 0 that results from casting or folding.  */
406159279Selan       if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)))
406259279Selan 	{
406359279Selan 	  warn_for_assignment ("%s makes pointer from integer without a cast",
406459279Selan 			       get_spelling (errtype), funname, parmnum);
406559279Selan 	  return convert (type, rhs);
406659279Selan 	}
406759279Selan       return null_pointer_node;
406859279Selan     }
406959279Selan   else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
407059279Selan     {
407159279Selan       warn_for_assignment ("%s makes integer from pointer without a cast",
407259279Selan 			   get_spelling (errtype), funname, parmnum);
407359279Selan       return convert (type, rhs);
407459279Selan     }
407559279Selan 
407659279Selan   if (!errtype)
407759279Selan     {
407859279Selan       if (funname)
407959279Selan 	error ("incompatible type for argument %d of `%s'",
408059279Selan 	       parmnum, IDENTIFIER_POINTER (funname));
408159279Selan       else
408259279Selan 	error ("incompatible type for argument %d of indirect function call",
408359279Selan 	       parmnum);
408459279Selan     }
408559279Selan   else
408659279Selan     error ("incompatible types in %s", get_spelling (errtype));
408759279Selan 
408859279Selan   return error_mark_node;
408959279Selan }
409059279Selan 
409159279Selan /* Print a warning using MSG.
409259279Selan    It gets OPNAME as its one parameter.
409359279Selan    If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
409459279Selan    FUNCTION and ARGNUM are handled specially if we are building an
409559279Selan    Objective-C selector.  */
409659279Selan 
409759279Selan static void
warn_for_assignment(msg,opname,function,argnum)409859279Selan warn_for_assignment (msg, opname, function, argnum)
409959279Selan      char *msg;
410059279Selan      char *opname;
410159279Selan      tree function;
410259279Selan      int argnum;
410359279Selan {
410459279Selan   static char argstring[] = "passing arg %d of `%s'";
410559279Selan   static char argnofun[] =  "passing arg %d";
410659279Selan 
410759279Selan   if (opname == 0)
410859279Selan     {
410959279Selan       tree selector = maybe_building_objc_message_expr ();
411059279Selan 
411159279Selan       if (selector && argnum > 2)
411259279Selan 	{
411359279Selan 	  function = selector;
411459279Selan 	  argnum -= 2;
411559279Selan 	}
411659279Selan       if (function)
411759279Selan 	{
411859279Selan 	  /* Function name is known; supply it.  */
411959279Selan 	  opname = (char *) alloca (IDENTIFIER_LENGTH (function)
412059279Selan 				    + sizeof (argstring) + 25 /*%d*/ + 1);
412159279Selan 	  sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function));
412259279Selan 	}
412359279Selan       else
412459279Selan 	{
412559279Selan 	  /* Function name unknown (call through ptr); just give arg number.  */
412659279Selan 	  opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1);
412759279Selan 	  sprintf (opname, argnofun, argnum);
412859279Selan 	}
412959279Selan     }
413059279Selan   pedwarn (msg, opname);
413159279Selan }
413259279Selan 
413359279Selan /* Return nonzero if VALUE is a valid constant-valued expression
413459279Selan    for use in initializing a static variable; one that can be an
413559279Selan    element of a "constant" initializer.
413659279Selan 
413759279Selan    Return null_pointer_node if the value is absolute;
413859279Selan    if it is relocatable, return the variable that determines the relocation.
413959279Selan    We assume that VALUE has been folded as much as possible;
414059279Selan    therefore, we do not need to check for such things as
414159279Selan    arithmetic-combinations of integers.  */
414259279Selan 
414359279Selan static tree
initializer_constant_valid_p(value,endtype)414459279Selan initializer_constant_valid_p (value, endtype)
414559279Selan      tree value;
414659279Selan      tree endtype;
414759279Selan {
414859279Selan   switch (TREE_CODE (value))
414959279Selan     {
415059279Selan     case CONSTRUCTOR:
415159279Selan       return TREE_STATIC (value) ? null_pointer_node : 0;
415259279Selan 
415359279Selan     case INTEGER_CST:
415459279Selan     case REAL_CST:
415559279Selan     case STRING_CST:
415659279Selan       return null_pointer_node;
415759279Selan 
415859279Selan     case ADDR_EXPR:
415959279Selan       return TREE_OPERAND (value, 0);
416059279Selan 
416159279Selan     case NON_LVALUE_EXPR:
416259279Selan       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
416359279Selan 
416459279Selan     case CONVERT_EXPR:
416559279Selan     case NOP_EXPR:
416659279Selan       /* Allow conversions between pointer types.  */
416759279Selan       if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
416859279Selan 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
416959279Selan 	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
417059279Selan       /* Allow conversions between real types.  */
417159279Selan       if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
417259279Selan 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
417359279Selan 	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
417459279Selan       /* Allow length-preserving conversions between integer types.  */
417559279Selan       if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
417659279Selan 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
417759279Selan 	  && tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)),
417859279Selan 				 TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0)))))
417959279Selan 	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
418059279Selan       /* Allow conversions between integer types only if explicit value.  */
418159279Selan       if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
418259279Selan 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
418359279Selan 	{
418459279Selan 	  tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
418559279Selan 						     endtype);
418659279Selan 	  if (inner == null_pointer_node)
418759279Selan 	    return null_pointer_node;
418859279Selan 	  return 0;
418959279Selan 	}
419059279Selan       /* Allow (int) &foo.  */
419159279Selan       if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
419259279Selan 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
419359279Selan 	  && tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)),
419459279Selan 				 TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0)))))
419559279Selan 	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
419659279Selan 					     endtype);
419759279Selan       /* Allow conversions to union types if the value inside is okay.  */
419859279Selan       if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
419959279Selan 	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
420059279Selan 					     endtype);
420159279Selan       return 0;
420259279Selan 
420359279Selan     case PLUS_EXPR:
420459279Selan       if (TREE_CODE (endtype) == INTEGER_TYPE
420559279Selan 	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
420659279Selan 	return 0;
420759279Selan       {
420859279Selan 	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
420959279Selan 						    endtype);
421059279Selan 	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
421159279Selan 						    endtype);
421259279Selan 	/* If either term is absolute, use the other terms relocation.  */
421359279Selan 	if (valid0 == null_pointer_node)
421459279Selan 	  return valid1;
421559279Selan 	if (valid1 == null_pointer_node)
421659279Selan 	  return valid0;
421759279Selan 	return 0;
421859279Selan       }
421959279Selan 
422059279Selan     case MINUS_EXPR:
422159279Selan       if (TREE_CODE (endtype) == INTEGER_TYPE
422259279Selan 	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
422359279Selan 	return 0;
422459279Selan       {
422559279Selan 	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
422659279Selan 						    endtype);
422759279Selan 	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
422859279Selan 						    endtype);
422959279Selan 	/* Win if second argument is absolute.  */
423059279Selan 	if (valid1 == null_pointer_node)
423159279Selan 	  return valid0;
423259279Selan 	/* Win if both arguments have the same relocation.
423359279Selan 	   Then the value is absolute.  */
423459279Selan 	if (valid0 == valid1)
423559279Selan 	  return null_pointer_node;
423659279Selan 	return 0;
423759279Selan       }
423859279Selan     }
423959279Selan 
424059279Selan   return 0;
424159279Selan }
424259279Selan 
424359279Selan /* Perform appropriate conversions on the initial value of a variable,
424459279Selan    store it in the declaration DECL,
424559279Selan    and print any error messages that are appropriate.
424659279Selan    If the init is invalid, store an ERROR_MARK.  */
424759279Selan 
424859279Selan void
store_init_value(decl,init)424959279Selan store_init_value (decl, init)
425059279Selan      tree decl, init;
425159279Selan {
425259279Selan   register tree value, type;
425359279Selan 
425459279Selan   /* If variable's type was invalidly declared, just ignore it.  */
425559279Selan 
425659279Selan   type = TREE_TYPE (decl);
425759279Selan   if (TREE_CODE (type) == ERROR_MARK)
425859279Selan     return;
425959279Selan 
426059279Selan   /* Digest the specified initializer into an expression.  */
426159279Selan 
426259279Selan   value = digest_init (type, init, NULL_PTR, TREE_STATIC (decl),
426359279Selan 		       TREE_STATIC (decl) || pedantic,
426459279Selan 		       IDENTIFIER_POINTER (DECL_NAME (decl)));
426559279Selan 
426659279Selan   /* Store the expression if valid; else report error.  */
426759279Selan 
426859279Selan #if 0
426959279Selan   /* Note that this is the only place we can detect the error
427059279Selan      in a case such as   struct foo bar = (struct foo) { x, y };
427159279Selan      where there is one initial value which is a constructor expression.  */
427259279Selan   if (value == error_mark_node)
427359279Selan     ;
427459279Selan   else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value))
427559279Selan     {
427659279Selan       error ("initializer for static variable is not constant");
427759279Selan       value = error_mark_node;
427859279Selan     }
427959279Selan   else if (TREE_STATIC (decl)
428059279Selan 	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
428159279Selan     {
428259279Selan       error ("initializer for static variable uses complicated arithmetic");
428359279Selan       value = error_mark_node;
428459279Selan     }
428559279Selan   else
428659279Selan     {
428759279Selan       if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
428859279Selan 	{
428959279Selan 	  if (! TREE_CONSTANT (value))
429059279Selan 	    pedwarn ("aggregate initializer is not constant");
429159279Selan 	  else if (! TREE_STATIC (value))
429259279Selan 	    pedwarn ("aggregate initializer uses complicated arithmetic");
429359279Selan 	}
429459279Selan     }
429559279Selan #endif
429659279Selan 
429759279Selan   /* ANSI wants warnings about out-of-range constant initializers.  */
429859279Selan   constant_expression_warning (value);
429959279Selan 
430059279Selan   DECL_INITIAL (decl) = value;
430159279Selan }
430259279Selan 
430359279Selan /* Methods for storing and printing names for error messages.  */
430459279Selan 
430559279Selan /* Implement a spelling stack that allows components of a name to be pushed
430659279Selan    and popped.  Each element on the stack is this structure.  */
430759279Selan 
430859279Selan struct spelling
430959279Selan {
431059279Selan   int kind;
431159279Selan   union
431259279Selan     {
431359279Selan       int i;
431459279Selan       char *s;
431559279Selan     } u;
431659279Selan };
431759279Selan 
431859279Selan #define SPELLING_STRING 1
431959279Selan #define SPELLING_MEMBER 2
432059279Selan #define SPELLING_BOUNDS 3
432159279Selan 
432259279Selan static struct spelling *spelling;	/* Next stack element (unused).  */
432359279Selan static struct spelling *spelling_base;	/* Spelling stack base.  */
432459279Selan static int spelling_size;		/* Size of the spelling stack.  */
432559279Selan 
432659279Selan /* Macros to save and restore the spelling stack around push_... functions.
432759279Selan    Alternative to SAVE_SPELLING_STACK.  */
432859279Selan 
432959279Selan #define SPELLING_DEPTH() (spelling - spelling_base)
433059279Selan #define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth)
433159279Selan 
433259279Selan /* Save and restore the spelling stack around arbitrary C code.  */
433359279Selan 
433459279Selan #define SAVE_SPELLING_DEPTH(code)		\
433559279Selan {						\
433659279Selan   int __depth = SPELLING_DEPTH ();		\
433759279Selan   code;						\
433859279Selan   RESTORE_SPELLING_DEPTH (__depth);		\
433959279Selan }
434059279Selan 
434159279Selan /* Push an element on the spelling stack with type KIND and assign VALUE
434259279Selan    to MEMBER.  */
434359279Selan 
434459279Selan #define PUSH_SPELLING(KIND, VALUE, MEMBER)				\
434559279Selan {									\
434659279Selan   int depth = SPELLING_DEPTH ();					\
434759279Selan 									\
434859279Selan   if (depth >= spelling_size)						\
434959279Selan     {									\
435059279Selan       spelling_size += 10;						\
435159279Selan       if (spelling_base == 0)						\
435259279Selan 	spelling_base							\
435359279Selan 	  = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling));	\
435459279Selan       else								\
435559279Selan         spelling_base							\
435659279Selan 	  = (struct spelling *) xrealloc (spelling_base,		\
435759279Selan 					  spelling_size * sizeof (struct spelling));	\
435859279Selan       RESTORE_SPELLING_DEPTH (depth);					\
435959279Selan     }									\
436059279Selan 									\
436159279Selan   spelling->kind = (KIND);						\
436259279Selan   spelling->MEMBER = (VALUE);						\
436359279Selan   spelling++;								\
436459279Selan }
436559279Selan 
436659279Selan /* Push STRING on the stack.  Printed literally.  */
436759279Selan 
436859279Selan static void
push_string(string)436959279Selan push_string (string)
437059279Selan      char *string;
437159279Selan {
437259279Selan   PUSH_SPELLING (SPELLING_STRING, string, u.s);
437359279Selan }
437459279Selan 
437559279Selan /* Push a member name on the stack.  Printed as '.' STRING.  */
437659279Selan 
437759279Selan static void
push_member_name(string)437859279Selan push_member_name (string)
437959279Selan      char *string;
438059279Selan {
438159279Selan   PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
438259279Selan }
438359279Selan 
438459279Selan /* Push an array bounds on the stack.  Printed as [BOUNDS].  */
438559279Selan 
438659279Selan static void
push_array_bounds(bounds)438759279Selan push_array_bounds (bounds)
438859279Selan      int bounds;
438959279Selan {
439059279Selan   PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
439159279Selan }
439259279Selan 
439359279Selan /* Compute the maximum size in bytes of the printed spelling.  */
439459279Selan 
439559279Selan static int
spelling_length()439659279Selan spelling_length ()
439759279Selan {
439859279Selan   register int size = 0;
439959279Selan   register struct spelling *p;
440059279Selan 
440159279Selan   for (p = spelling_base; p < spelling; p++)
440259279Selan     {
440359279Selan       if (p->kind == SPELLING_BOUNDS)
440459279Selan 	size += 25;
440559279Selan       else
440659279Selan 	size += strlen (p->u.s) + 1;
440759279Selan     }
440859279Selan 
440959279Selan   return size;
441059279Selan }
441159279Selan 
441259279Selan /* Print the spelling to BUFFER and return it.  */
441359279Selan 
441459279Selan static char *
print_spelling(buffer)441559279Selan print_spelling (buffer)
441659279Selan      register char *buffer;
441759279Selan {
441859279Selan   register char *d = buffer;
441959279Selan   register char *s;
442059279Selan   register struct spelling *p;
442159279Selan 
442259279Selan   for (p = spelling_base; p < spelling; p++)
442359279Selan     if (p->kind == SPELLING_BOUNDS)
442459279Selan       {
442559279Selan 	sprintf (d, "[%d]", p->u.i);
442659279Selan 	d += strlen (d);
442759279Selan       }
442859279Selan     else
442959279Selan       {
443059279Selan 	if (p->kind == SPELLING_MEMBER)
443159279Selan 	  *d++ = '.';
443259279Selan 	for (s = p->u.s; *d = *s++; d++)
443359279Selan 	  ;
443459279Selan       }
443559279Selan   *d++ = '\0';
443659279Selan   return buffer;
443759279Selan }
443859279Selan 
443959279Selan /* Provide a means to pass component names derived from the spelling stack.  */
444059279Selan 
444159279Selan char initialization_message;
444259279Selan 
444359279Selan /* Interpret the spelling of the given ERRTYPE message.  */
444459279Selan 
444559279Selan static char *
get_spelling(errtype)444659279Selan get_spelling (errtype)
444759279Selan      char *errtype;
444859279Selan {
444959279Selan   static char *buffer;
445059279Selan   static int size = -1;
445159279Selan 
445259279Selan   if (errtype == &initialization_message)
445359279Selan     {
445459279Selan       /* Avoid counting chars */
445559279Selan       static char message[] = "initialization of `%s'";
445659279Selan       register int needed = sizeof (message) + spelling_length () + 1;
445759279Selan       char *temp;
445859279Selan 
445959279Selan       if (size < 0)
446059279Selan 	buffer = (char *) xmalloc (size = needed);
446159279Selan       if (needed > size)
446259279Selan 	buffer = (char *) xrealloc (buffer, size = needed);
446359279Selan 
446459279Selan       temp = (char *) alloca (needed);
446559279Selan       sprintf (buffer, message, print_spelling (temp));
446659279Selan       return buffer;
446759279Selan     }
446859279Selan 
446959279Selan   return errtype;
447059279Selan }
447159279Selan 
447259279Selan /* Issue an error message for a bad initializer component.
447359279Selan    FORMAT describes the message.  OFWHAT is the name for the component.
447459279Selan    LOCAL is a format string for formatting the insertion of the name
447559279Selan    into the message.
447659279Selan 
447759279Selan    If OFWHAT is null, the component name is stored on the spelling stack.
447859279Selan    If the component name is a null string, then LOCAL is omitted entirely.  */
447959279Selan 
448059279Selan void
error_init(format,local,ofwhat)448159279Selan error_init (format, local, ofwhat)
448259279Selan      char *format, *local, *ofwhat;
448359279Selan {
448459279Selan   char *buffer;
448559279Selan 
448659279Selan   if (ofwhat == 0)
448759279Selan     ofwhat = print_spelling (alloca (spelling_length () + 1));
448859279Selan   buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
448959279Selan 
449059279Selan   if (*ofwhat)
449159279Selan     sprintf (buffer, local, ofwhat);
449259279Selan   else
449359279Selan     buffer[0] = 0;
449459279Selan 
449559279Selan   error (format, buffer);
449659279Selan }
449759279Selan 
449859279Selan /* Issue a pedantic warning for a bad initializer component.
449959279Selan    FORMAT describes the message.  OFWHAT is the name for the component.
450059279Selan    LOCAL is a format string for formatting the insertion of the name
450159279Selan    into the message.
450259279Selan 
450359279Selan    If OFWHAT is null, the component name is stored on the spelling stack.
450459279Selan    If the component name is a null string, then LOCAL is omitted entirely.  */
450559279Selan 
450659279Selan void
pedwarn_init(format,local,ofwhat)450759279Selan pedwarn_init (format, local, ofwhat)
450859279Selan      char *format, *local, *ofwhat;
450959279Selan {
451059279Selan   char *buffer;
451159279Selan 
451259279Selan   if (ofwhat == 0)
451359279Selan     ofwhat = print_spelling (alloca (spelling_length () + 1));
451459279Selan   buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2);
451559279Selan 
451659279Selan   if (*ofwhat)
451759279Selan     sprintf (buffer, local, ofwhat);
451859279Selan   else
451959279Selan     buffer[0] = 0;
452059279Selan 
452159279Selan   pedwarn (format, buffer);
452259279Selan }
452359279Selan 
4524*60373Selan /* Keep a pointer to the last free TREE_LIST node as we digest an initializer,
4525*60373Selan    so that we can reuse it.  This is set in digest_init, and used in
4526*60373Selan    process_init_constructor.
4527*60373Selan 
4528*60373Selan    We will never keep more than one free TREE_LIST node here.  This is for
4529*60373Selan    two main reasons.  First, we take elements off the old list and add them
4530*60373Selan    to the new list one at a time, thus there should never be more than
4531*60373Selan    one free TREE_LIST at a time, and thus even if there is, we will never
4532*60373Selan    need more than one.  Secondly, to avoid dangling pointers to freed obstacks,
4533*60373Selan    we want to always ensure that we have either a pointer to a valid TREE_LIST
4534*60373Selan    within the current initializer, or else a pointer to null.  */
4535*60373Selan 
4536*60373Selan static tree free_tree_list = NULL_TREE;
4537*60373Selan 
453859279Selan /* Digest the parser output INIT as an initializer for type TYPE.
453959279Selan    Return a C expression of type TYPE to represent the initial value.
454059279Selan 
454159279Selan    If TAIL is nonzero, it points to a variable holding a list of elements
454259279Selan    of which INIT is the first.  We update the list stored there by
454359279Selan    removing from the head all the elements that we use.
454459279Selan    Normally this is only one; we use more than one element only if
454559279Selan    TYPE is an aggregate and INIT is not a constructor.
454659279Selan 
454759279Selan    The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors
454859279Selan    if non-constant initializers or elements are seen.  CONSTRUCTOR_CONSTANT
454959279Selan    applies only to elements of constructors.
455059279Selan 
455159279Selan    If OFWHAT is nonnull, it specifies what we are initializing, for error
455259279Selan    messages.   Examples: variable name, variable.member, array[44].
455359279Selan    If OFWHAT is null, the component name is stored on the spelling stack.  */
455459279Selan 
455559279Selan tree
digest_init(type,init,tail,require_constant,constructor_constant,ofwhat)455659279Selan digest_init (type, init, tail, require_constant, constructor_constant, ofwhat)
455759279Selan      tree type, init, *tail;
455859279Selan      int require_constant, constructor_constant;
455959279Selan      char *ofwhat;
456059279Selan {
456159279Selan   enum tree_code code = TREE_CODE (type);
456259279Selan   tree element = 0;
456359279Selan   tree old_tail_contents;
456459279Selan   /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR
456559279Selan      tree node which has no TREE_TYPE.  */
456659279Selan   int raw_constructor
456759279Selan     = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0;
456859279Selan   tree inside_init = init;
456959279Selan 
457059279Selan   /* By default, assume we use one element from a list.
4571*60373Selan      We correct this later in the cases where it is not true.
457259279Selan 
4573*60373Selan      Thus, we update TAIL now to point to the next element, and save the
4574*60373Selan      old value in OLD_TAIL_CONTENTS.  If we didn't actually use the first
4575*60373Selan      element, then we will reset TAIL before proceeding.  FREE_TREE_LIST
4576*60373Selan      is handled similarly.  */
4577*60373Selan 
457859279Selan   if (tail)
457959279Selan     {
458059279Selan       old_tail_contents = *tail;
458159279Selan       *tail = TREE_CHAIN (*tail);
4582*60373Selan       free_tree_list = old_tail_contents;
458359279Selan     }
4584*60373Selan   else
4585*60373Selan     free_tree_list = 0;
458659279Selan 
458759279Selan   if (init == error_mark_node)
458859279Selan     return init;
458959279Selan 
459059279Selan   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
459159279Selan   /* Do not use STRIP_NOPS here.  We do not want an enumerator
459259279Selan      whose value is 0 to count as a null pointer constant.  */
459359279Selan   if (TREE_CODE (init) == NON_LVALUE_EXPR)
459459279Selan     inside_init = TREE_OPERAND (init, 0);
459559279Selan 
459659279Selan   if (inside_init && raw_constructor
459759279Selan       && CONSTRUCTOR_ELTS (inside_init) != 0
459859279Selan       && TREE_CHAIN (CONSTRUCTOR_ELTS (inside_init)) == 0)
459959279Selan     {
460059279Selan       element = TREE_VALUE (CONSTRUCTOR_ELTS (inside_init));
460159279Selan       /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
460259279Selan       if (element && TREE_CODE (element) == NON_LVALUE_EXPR)
460359279Selan 	element = TREE_OPERAND (element, 0);
460459279Selan     }
460559279Selan 
460659279Selan   /* Initialization of an array of chars from a string constant
460759279Selan      optionally enclosed in braces.  */
460859279Selan 
460959279Selan   if (code == ARRAY_TYPE)
461059279Selan     {
461159279Selan       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
461259279Selan       if ((typ1 == char_type_node
461359279Selan 	   || typ1 == signed_char_type_node
461459279Selan 	   || typ1 == unsigned_char_type_node
461559279Selan 	   || typ1 == unsigned_wchar_type_node
461659279Selan 	   || typ1 == signed_wchar_type_node)
461759279Selan 	  && ((inside_init && TREE_CODE (inside_init) == STRING_CST)
461859279Selan 	      || (element && TREE_CODE (element) == STRING_CST)))
461959279Selan 	{
462059279Selan 	  tree string = element ? element : inside_init;
462159279Selan 
462259279Selan 	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
462359279Selan 	       != char_type_node)
462459279Selan 	      && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
462559279Selan 	    {
462659279Selan 	      error_init ("char-array%s initialized from wide string",
462759279Selan 			  " `%s'", ofwhat);
462859279Selan 	      return error_mark_node;
462959279Selan 	    }
463059279Selan 	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string)))
463159279Selan 	       == char_type_node)
463259279Selan 	      && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
463359279Selan 	    {
463459279Selan 	      error_init ("int-array%s initialized from non-wide string",
463559279Selan 			  " `%s'", ofwhat);
463659279Selan 	      return error_mark_node;
463759279Selan 	    }
463859279Selan 
463959279Selan 	  TREE_TYPE (string) = type;
464059279Selan 	  if (TYPE_DOMAIN (type) != 0
464159279Selan 	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
464259279Selan 	    {
464359279Selan 	      register int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
464459279Selan 	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
464559279Selan 	      /* Subtract 1 because it's ok to ignore the terminating null char
464659279Selan 		 that is counted in the length of the constant.  */
464759279Selan 	      if (size < TREE_STRING_LENGTH (string) - 1)
464859279Selan 		pedwarn_init (
464959279Selan 		  "initializer-string for array of chars%s is too long",
465059279Selan 		  " `%s'", ofwhat);
465159279Selan 	    }
465259279Selan 	  return string;
465359279Selan 	}
465459279Selan     }
465559279Selan 
465659279Selan   /* Any type except an array can be initialized
465759279Selan      from an expression of the same type, optionally with braces.
465859279Selan      For an array, this is allowed only for a string constant.  */
465959279Selan 
466059279Selan   if (inside_init && TREE_TYPE (inside_init) != 0
466159279Selan       && ((TYPE_MAIN_VARIANT (TREE_TYPE (inside_init))
466259279Selan 	   == TYPE_MAIN_VARIANT (type))
466359279Selan 	  || (code == ARRAY_TYPE
466459279Selan 	      && comptypes (TREE_TYPE (inside_init), type))
466559279Selan 	  || (code == POINTER_TYPE
466659279Selan 	      && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
466759279Selan 		  || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
466859279Selan 	      && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
466959279Selan 			    TREE_TYPE (type)))))
467059279Selan     {
467159279Selan       if (code == POINTER_TYPE
467259279Selan 	  && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
467359279Selan 	      || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE))
467459279Selan 	inside_init = default_conversion (inside_init);
467559279Selan       else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST)
467659279Selan 	{
467759279Selan 	  error_init ("array%s initialized from non-constant array expression",
467859279Selan 		      " `%s'", ofwhat);
467959279Selan 	  return error_mark_node;
468059279Selan 	}
468159279Selan 
468259279Selan       if (optimize && TREE_READONLY (inside_init)
468359279Selan 	  && TREE_CODE (inside_init) == VAR_DECL)
468459279Selan 	inside_init = decl_constant_value (inside_init);
468559279Selan 
468659279Selan       if (require_constant && ! TREE_CONSTANT (inside_init))
468759279Selan 	{
468859279Selan 	  error_init ("initializer element%s is not constant",
468959279Selan 		      " for `%s'", ofwhat);
469059279Selan 	  inside_init = error_mark_node;
469159279Selan 	}
469259279Selan       else if (require_constant
469359279Selan 	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
469459279Selan 	{
469559279Selan 	  error_init ("initializer element%s is not computable at load time",
469659279Selan 		      " for `%s'", ofwhat);
469759279Selan 	  inside_init = error_mark_node;
469859279Selan 	}
469959279Selan 
470059279Selan       return inside_init;
470159279Selan     }
470259279Selan 
470359279Selan   if (element && (TREE_TYPE (element) == type
470459279Selan 		  || (code == ARRAY_TYPE && TREE_TYPE (element)
470559279Selan 		      && comptypes (TREE_TYPE (element), type))))
470659279Selan     {
470759279Selan       if (code == ARRAY_TYPE)
470859279Selan 	{
470959279Selan 	  error_init ("array%s initialized from non-constant array expression",
471059279Selan 		      " `%s'", ofwhat);
471159279Selan 	  return error_mark_node;
471259279Selan 	}
471359279Selan       if (pedantic && (code == RECORD_TYPE || code == UNION_TYPE))
471459279Selan 	pedwarn ("single-expression nonscalar initializer has braces");
471559279Selan       if (optimize && TREE_READONLY (element) && TREE_CODE (element) == VAR_DECL)
471659279Selan 	element = decl_constant_value (element);
471759279Selan 
471859279Selan       if (require_constant && ! TREE_CONSTANT (element))
471959279Selan 	{
472059279Selan 	  error_init ("initializer element%s is not constant",
472159279Selan 		      " for `%s'", ofwhat);
472259279Selan 	  element = error_mark_node;
472359279Selan 	}
472459279Selan       else if (require_constant
472559279Selan 	       && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0)
472659279Selan 	{
472759279Selan 	  error_init ("initializer element%s is not computable at load time",
472859279Selan 		      " for `%s'", ofwhat);
472959279Selan 	  element = error_mark_node;
473059279Selan 	}
473159279Selan 
473259279Selan       return element;
473359279Selan     }
473459279Selan 
473559279Selan   /* Check for initializing a union by its first field.
473659279Selan      Such an initializer must use braces.  */
473759279Selan 
473859279Selan   if (code == UNION_TYPE)
473959279Selan     {
474059279Selan       tree result;
474159279Selan       tree field = TYPE_FIELDS (type);
474259279Selan 
474359279Selan       /* Find the first named field.  ANSI decided in September 1990
474459279Selan 	 that only named fields count here.  */
474559279Selan       while (field && DECL_NAME (field) == 0)
474659279Selan 	field = TREE_CHAIN (field);
474759279Selan 
474859279Selan       if (field == 0)
474959279Selan 	{
475059279Selan 	  error_init ("union%s with no named members cannot be initialized",
475159279Selan 		      " `%s'", ofwhat);
475259279Selan 	  return error_mark_node;
475359279Selan 	}
475459279Selan 
475559279Selan       if (raw_constructor)
475659279Selan 	result = process_init_constructor (type, inside_init, NULL_PTR,
475759279Selan 					   require_constant,
475859279Selan 					   constructor_constant, ofwhat);
475959279Selan       else if (tail != 0)
476059279Selan 	{
476159279Selan 	  *tail = old_tail_contents;
4762*60373Selan 	  free_tree_list = NULL_TREE;
476359279Selan 	  result = process_init_constructor (type, NULL_TREE, tail,
476459279Selan 					     require_constant,
476559279Selan 					     constructor_constant, ofwhat);
476659279Selan 	}
476759279Selan       else
476859279Selan 	result = 0;
476959279Selan 
477059279Selan       if (result)
477159279Selan 	return result;
477259279Selan     }
477359279Selan 
477459279Selan   /* Handle scalar types, including conversions.  */
477559279Selan 
477659279Selan   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
477759279Selan       || code == ENUMERAL_TYPE)
477859279Selan     {
477959279Selan       if (raw_constructor)
478059279Selan 	{
478159279Selan 	  if (element == 0)
478259279Selan 	    {
478359279Selan 	      error_init (
478459279Selan 	 	  "initializer for scalar%s requires one element",
478559279Selan 		  " `%s'", ofwhat);
478659279Selan 	      return error_mark_node;
478759279Selan 	    }
478859279Selan 	  else
478959279Selan 	    {
479059279Selan 	      /* Deal with extra levels of {...}.  */
479159279Selan 	      if (TREE_CODE (element) == CONSTRUCTOR
479259279Selan 		  && TREE_TYPE (element) == 0)
479359279Selan 		{
479459279Selan 		  error_init (
479559279Selan 			      "initializer for scalar%s requires one element",
479659279Selan 			      " `%s'", ofwhat);
479759279Selan 		  return error_mark_node;
479859279Selan 		}
479959279Selan 	      inside_init = element;
480059279Selan 	    }
480159279Selan 	}
480259279Selan 
480359279Selan #if 0  /* A non-raw constructor is an actual expression.  */
480459279Selan       if (TREE_CODE (inside_init) == CONSTRUCTOR)
480559279Selan 	{
480659279Selan 	  error_init ("initializer for scalar%s has extra braces",
480759279Selan 		      " `%s'", ofwhat);
480859279Selan 	  return error_mark_node;
480959279Selan 	}
481059279Selan #endif
481159279Selan 
481259279Selan       SAVE_SPELLING_DEPTH
481359279Selan 	({
481459279Selan 	  if (ofwhat)
481559279Selan 	    push_string (ofwhat);
481659279Selan 	  inside_init
481759279Selan 	    = convert_for_assignment (type,
481859279Selan 				      default_conversion (raw_constructor
481959279Selan 							  ? inside_init
482059279Selan 							  : init),
482159279Selan 				      &initialization_message, NULL_TREE, 0);
482259279Selan 	});
482359279Selan 
482459279Selan       if (require_constant && ! TREE_CONSTANT (inside_init))
482559279Selan 	{
482659279Selan 	  error_init ("initializer element%s is not constant",
482759279Selan 		      " for `%s'", ofwhat);
482859279Selan 	  inside_init = error_mark_node;
482959279Selan 	}
483059279Selan       else if (require_constant
483159279Selan 	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
483259279Selan 	{
483359279Selan 	  error_init ("initializer element%s is not computable at load time",
483459279Selan 		      " for `%s'", ofwhat);
483559279Selan 	  inside_init = error_mark_node;
483659279Selan 	}
483759279Selan 
483859279Selan       return inside_init;
483959279Selan     }
484059279Selan 
484159279Selan   /* Come here only for records and arrays.  */
484259279Selan 
484359279Selan   if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
484459279Selan     {
484559279Selan       error_init ("variable-sized object%s may not be initialized",
484659279Selan 		  " `%s'", ofwhat);
484759279Selan       return error_mark_node;
484859279Selan     }
484959279Selan 
485059279Selan   if (code == ARRAY_TYPE || code == RECORD_TYPE)
485159279Selan     {
485259279Selan       if (raw_constructor)
485359279Selan 	return process_init_constructor (type, inside_init,
485459279Selan 					 NULL_PTR, constructor_constant,
485559279Selan 					 constructor_constant, ofwhat);
485659279Selan       else if (tail != 0)
485759279Selan 	{
485859279Selan 	  *tail = old_tail_contents;
4859*60373Selan 	  free_tree_list = NULL_TREE;
486059279Selan 	  return process_init_constructor (type, NULL_TREE, tail,
486159279Selan 					   constructor_constant,
486259279Selan 					   constructor_constant, ofwhat);
486359279Selan 	}
486459279Selan       else if (flag_traditional)
486559279Selan 	/* Traditionally one can say `char x[100] = 0;'.  */
486659279Selan 	return process_init_constructor (type,
486759279Selan 					 build_nt (CONSTRUCTOR, NULL_TREE,
486859279Selan 						   tree_cons (NULL_TREE,
486959279Selan 							      inside_init,
487059279Selan 							      NULL_TREE)),
487159279Selan 					 NULL_PTR, constructor_constant,
487259279Selan 					 constructor_constant, ofwhat);
487359279Selan     }
487459279Selan 
487559279Selan   error_init ("invalid initializer%s", " for `%s'", ofwhat);
487659279Selan   return error_mark_node;
487759279Selan }
487859279Selan 
487959279Selan /* Process a constructor for a variable of type TYPE.
488059279Selan    The constructor elements may be specified either with INIT or with ELTS,
488159279Selan    only one of which should be non-null.
488259279Selan 
488359279Selan    If INIT is specified, it is a CONSTRUCTOR node which is specifically
488459279Selan    and solely for initializing this datum.
488559279Selan 
488659279Selan    If ELTS is specified, it is the address of a variable containing
488759279Selan    a list of expressions.  We take as many elements as we need
488859279Selan    from the head of the list and update the list.
488959279Selan 
489059279Selan    In the resulting constructor, TREE_CONSTANT is set if all elts are
489159279Selan    constant, and TREE_STATIC is set if, in addition, all elts are simple enough
489259279Selan    constants that the assembler and linker can compute them.
489359279Selan 
489459279Selan    The argument CONSTANT_VALUE says to print an error if either the
489559279Selan    value or any element is not a constant.
489659279Selan 
489759279Selan    The argument CONSTANT_ELEMENT says to print an error if an element
489859279Selan    of an aggregate is not constant.  It does not apply to a value
489959279Selan    which is not a constructor.
490059279Selan 
490159279Selan    OFWHAT is a character string describing the object being initialized,
490259279Selan    for error messages.  It might be "variable" or "variable.member"
490359279Selan    or "variable[17].member[5]".  If OFWHAT is null, the description string
490459279Selan    is stored on the spelling stack.  */
490559279Selan 
490659279Selan static tree
process_init_constructor(type,init,elts,constant_value,constant_element,ofwhat)490759279Selan process_init_constructor (type, init, elts, constant_value, constant_element,
490859279Selan 			  ofwhat)
490959279Selan      tree type, init, *elts;
491059279Selan      int constant_value, constant_element;
491159279Selan      char *ofwhat;
491259279Selan {
491359279Selan   register tree tail;
491459279Selan   /* List of the elements of the result constructor,
491559279Selan      in reverse order.  */
491659279Selan   register tree members = NULL;
491759279Selan   tree result;
491859279Selan   int allconstant = 1;
491959279Selan   int allsimple = 1;
492059279Selan   int erroneous = 0;
492159279Selan   int depth = SPELLING_DEPTH ();
492259279Selan 
492359279Selan   if (ofwhat)
492459279Selan     push_string (ofwhat);
492559279Selan 
492659279Selan   /* Make TAIL be the list of elements to use for the initialization,
492759279Selan      no matter how the data was given to us.  */
492859279Selan 
492959279Selan   if (elts)
493059279Selan     {
493159279Selan       if (extra_warnings)
493259279Selan 	warning ("aggregate has a partly bracketed initializer");
493359279Selan       tail = *elts;
493459279Selan     }
493559279Selan   else
493659279Selan     tail = CONSTRUCTOR_ELTS (init);
493759279Selan 
493859279Selan   /* Gobble as many elements as needed, and make a constructor or initial value
493959279Selan      for each element of this aggregate.  Chain them together in result.
494059279Selan      If there are too few, use 0 for each scalar ultimate component.  */
494159279Selan 
494259279Selan   if (TREE_CODE (type) == ARRAY_TYPE)
494359279Selan     {
4944*60373Selan       tree min_index, max_index;
494559279Selan       /* These are non-zero only within a range initializer.  */
494659279Selan       tree start_index = 0, end_index = 0;
494759279Selan       /* Within a range, this is the value for the elts in the range.  */
494859279Selan       tree range_val = 0;
4949*60373Selan       /* Do arithmetic using double integers, but don't use fold/build,
4950*60373Selan 	 because these allocate a new tree object everytime they are called,
4951*60373Selan 	 thus resulting in gcc using too much memory for large
4952*60373Selan 	 initializers.  */
4953*60373Selan       union tree_node current_index_node, members_index_node;
4954*60373Selan       tree current_index = &current_index_node;
4955*60373Selan       tree members_index = &members_index_node;
4956*60373Selan       TREE_TYPE (current_index) = integer_type_node;
4957*60373Selan       TREE_TYPE (members_index) = integer_type_node;
495859279Selan 
495959279Selan       /* If we have array bounds, set our bounds from that.  Otherwise,
4960*60373Selan 	 we have a lower bound of zero and an unknown upper bound.  */
496159279Selan       if (TYPE_DOMAIN (type))
496259279Selan 	{
4963*60373Selan 	  min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
496459279Selan 	  max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
496559279Selan 	}
496659279Selan       else
496759279Selan 	{
4968*60373Selan 	  min_index = integer_zero_node;
496959279Selan 	  max_index = 0;
497059279Selan 	}
497159279Selan 
4972*60373Selan       TREE_INT_CST_LOW (members_index) = TREE_INT_CST_LOW (min_index);
4973*60373Selan       TREE_INT_CST_HIGH (members_index) = TREE_INT_CST_HIGH (min_index);
497459279Selan 
497559279Selan       /* Don't leave the loop based on index if the next item has an explicit
497659279Selan 	 index value that will override it. */
497759279Selan 
4978*60373Selan       for (TREE_INT_CST_LOW (current_index) = TREE_INT_CST_LOW (min_index),
4979*60373Selan 	   TREE_INT_CST_HIGH (current_index) = TREE_INT_CST_HIGH (min_index);
4980*60373Selan 	   tail != 0 || end_index;
4981*60373Selan 	   add_double (TREE_INT_CST_LOW (current_index),
4982*60373Selan 		       TREE_INT_CST_HIGH (current_index), 1, 0,
4983*60373Selan 		       &TREE_INT_CST_LOW (current_index),
4984*60373Selan 		       &TREE_INT_CST_HIGH (current_index)))
498559279Selan 	{
498659279Selan 	  register tree next1 = 0;
498759279Selan 
498859279Selan 	  /* Handle the case where we are inside of a range.
498959279Selan 	     current_index increments through the range,
499059279Selan 	     so just keep reusing the same element of TAIL
499159279Selan 	     until the end of the range.  */
499259279Selan 	  if (end_index != 0)
499359279Selan 	    {
499459279Selan 	      next1 = range_val;
499559279Selan 	      if (!tree_int_cst_lt (current_index, end_index))
499659279Selan 		end_index = 0;
499759279Selan 	    }
499859279Selan 
499959279Selan 	  /* If this element specifies an index,
500059279Selan 	     move to that index before storing it in the new list.  */
500159279Selan 	  else if (TREE_PURPOSE (tail) != 0)
500259279Selan 	    {
500359279Selan 	      int win = 0;
500459279Selan 	      tree index = TREE_PURPOSE (tail);
500559279Selan 
500659279Selan 	      if (index && (TREE_CODE (index) == NON_LVALUE_EXPR
500759279Selan 			    || TREE_CODE (index) == NOP_EXPR))
500859279Selan 		index = TREE_OPERAND (index, 0);
500959279Selan 
501059279Selan 	      /* Begin a range.  */
501159279Selan 	      if (TREE_CODE (index) == TREE_LIST)
501259279Selan 		{
501359279Selan 		  start_index = TREE_PURPOSE (index);
501459279Selan 		  end_index = TREE_PURPOSE (TREE_CHAIN (index));
501559279Selan 
501659279Selan 		  /* Expose constants.  It Doesn't matter if we change
501759279Selan 		     the mode.*/
501859279Selan 		  if (end_index
501959279Selan 		      && (TREE_CODE (end_index) == NON_LVALUE_EXPR
502059279Selan 			  || TREE_CODE (end_index) == NOP_EXPR))
502159279Selan 		    end_index = TREE_OPERAND (end_index, 0);
502259279Selan 		  if (start_index
502359279Selan 		      && (TREE_CODE (start_index) == NON_LVALUE_EXPR
502459279Selan 			  || TREE_CODE (start_index) == NOP_EXPR))
502559279Selan 		    start_index = TREE_OPERAND (start_index, 0);
502659279Selan 
502759279Selan 		  if ((TREE_CODE (start_index) == IDENTIFIER_NODE)
502859279Selan 		      || (TREE_CODE (end_index) == IDENTIFIER_NODE))
502959279Selan 		    error ("field name used as index in array initializer");
503059279Selan 		  else if ((TREE_CODE (start_index) != INTEGER_CST)
503159279Selan 			   || (TREE_CODE (end_index) != INTEGER_CST))
503259279Selan 		    error ("non-constant array index in initializer");
503359279Selan 		  else if (tree_int_cst_lt (start_index, min_index)
503459279Selan 			   || (max_index && tree_int_cst_lt (max_index, start_index))
503559279Selan 			   || tree_int_cst_lt (end_index, min_index)
503659279Selan 			   || (max_index && tree_int_cst_lt (max_index, end_index)))
503759279Selan 		    error ("array index out of range in initializer");
503859279Selan 		  else if (tree_int_cst_lt (end_index, start_index))
503959279Selan 		    {
504059279Selan 		      /* If the range is empty, don't initialize any elements,
504159279Selan 			 but do reset current_index for the next initializer
504259279Selan 			 element.  */
504359279Selan 		      warning ("empty array initializer range");
504459279Selan 		      tail = TREE_CHAIN (tail);
504559279Selan 		      current_index = end_index;
504659279Selan 		      continue;
504759279Selan 		    }
504859279Selan 		  else
504959279Selan 		    {
505059279Selan 		      current_index = start_index;
505159279Selan 		      win = 1;
505259279Selan 		      /* See if the first element is also the last.  */
505359279Selan 		      if (!tree_int_cst_lt (current_index, end_index))
505459279Selan 			end_index = 0;
505559279Selan 		    }
505659279Selan 		}
505759279Selan 	      else if (TREE_CODE (index) == IDENTIFIER_NODE)
505859279Selan 		error ("field name used as index in array initializer");
505959279Selan 	      else if (TREE_CODE (index) != INTEGER_CST)
506059279Selan 		error ("non-constant array index in initializer");
506159279Selan 	      else if (tree_int_cst_lt (index, min_index)
506259279Selan 		       || (max_index && tree_int_cst_lt (max_index, index)))
506359279Selan 		error ("array index out of range in initializer");
506459279Selan 	      else
506559279Selan 		current_index = index, win = 1;
506659279Selan 
506759279Selan 	      if (!win)
506859279Selan 		{
506959279Selan 		  /* If there was an error, end the current range.  */
507059279Selan 		  end_index = 0;
507159279Selan 		  TREE_VALUE (tail) = error_mark_node;
507259279Selan 		}
507359279Selan 	    }
507459279Selan 
507559279Selan 	  if (max_index && tree_int_cst_lt (max_index, current_index))
507659279Selan 	    break;  /* Stop if we've indeed run out of elements. */
507759279Selan 
507859279Selan 	  /* Now digest the value specified.  */
507959279Selan 	  if (next1 != 0)
508059279Selan 	    ;
508159279Selan 	  else if (TREE_VALUE (tail) != 0)
508259279Selan 	    {
508359279Selan 	      tree tail1 = tail;
508459279Selan 
508559279Selan 	      /* Build the element of this array, with "[]" notation.  For
508659279Selan 		 error messages, we assume that the index fits within a
508759279Selan 		 host int.  */
508859279Selan 	      SAVE_SPELLING_DEPTH
508959279Selan 		({
509059279Selan 		  push_array_bounds (TREE_INT_CST_LOW (current_index));
509159279Selan 		  next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
509259279Selan 				       TREE_VALUE (tail), &tail1,
509359279Selan 				       /* Both of these are the same because
509459279Selan 					  a value here is an elt overall.  */
509559279Selan 				       constant_element, constant_element,
509659279Selan 				       NULL_PTR);
509759279Selan 		});
509859279Selan 
509959279Selan 	      if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST)
510059279Selan 		abort ();
510159279Selan 	      if (tail == tail1 && TYPE_DOMAIN (type) == 0)
510259279Selan 		{
510359279Selan 		  error_init (
510459279Selan 		    "non-empty initializer for array%s of empty elements",
510559279Selan 		    " `%s'", NULL_PTR);
510659279Selan 		  /* Just ignore what we were supposed to use.  */
510759279Selan 		  tail1 = 0;
510859279Selan 		}
510959279Selan 	      tail = tail1;
511059279Selan 	    }
511159279Selan 	  else
511259279Selan 	    {
511359279Selan 	      next1 = error_mark_node;
511459279Selan 	      tail = TREE_CHAIN (tail);
511559279Selan 	    }
511659279Selan 
511759279Selan 	  if (end_index != 0)
511859279Selan 	    range_val = next1;
511959279Selan 
512059279Selan 	  if (next1 == error_mark_node)
512159279Selan 	    erroneous = 1;
512259279Selan 	  else if (!TREE_CONSTANT (next1))
512359279Selan 	    allconstant = 0;
512459279Selan 	  else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
512559279Selan 	    allsimple = 0;
512659279Selan 
512759279Selan 	  /* Now store NEXT1 in the list, I elements from the *end*.
512859279Selan 	     Make the list longer if necessary.  */
512959279Selan 	  while (! tree_int_cst_lt (current_index, members_index))
513059279Selan 	    {
5131*60373Selan 	      if (free_tree_list)
5132*60373Selan 		{
5133*60373Selan 		  TREE_CHAIN (free_tree_list) = members;
5134*60373Selan 		  TREE_PURPOSE (free_tree_list) = NULL_TREE;
5135*60373Selan 		  TREE_VALUE (free_tree_list) = NULL_TREE;
5136*60373Selan 		  members = free_tree_list;
5137*60373Selan 		  free_tree_list = NULL_TREE;
5138*60373Selan 		}
5139*60373Selan 	      else
5140*60373Selan 		members = tree_cons (NULL_TREE, NULL_TREE, members);
5141*60373Selan 	      add_double (TREE_INT_CST_LOW (members_index),
5142*60373Selan 			  TREE_INT_CST_HIGH (members_index), 1, 0,
5143*60373Selan 			  &TREE_INT_CST_LOW (members_index),
5144*60373Selan 			  &TREE_INT_CST_HIGH (members_index));
514559279Selan 	    }
514659279Selan 
514759279Selan 	  {
514859279Selan 	    tree temp;
5149*60373Selan 	    union tree_node idx_node;
5150*60373Selan 	    tree idx = &idx_node;
5151*60373Selan 	    TREE_TYPE (idx) = integer_type_node;
515259279Selan 
515359279Selan 	    temp = members;
5154*60373Selan 	    for (add_double (TREE_INT_CST_LOW (members_index),
5155*60373Selan 			     TREE_INT_CST_HIGH (members_index), -1, -1,
5156*60373Selan 			     &TREE_INT_CST_LOW (idx),
5157*60373Selan 			     &TREE_INT_CST_HIGH (idx));
515859279Selan 		 tree_int_cst_lt (current_index, idx);
5159*60373Selan 		 add_double (TREE_INT_CST_LOW (idx),
5160*60373Selan 			     TREE_INT_CST_HIGH (idx), -1, -1,
5161*60373Selan 			     &TREE_INT_CST_LOW (idx),
5162*60373Selan 			     &TREE_INT_CST_HIGH (idx)))
516359279Selan 	      temp = TREE_CHAIN (temp);
516459279Selan 	    TREE_VALUE (temp) = next1;
516559279Selan 	  }
516659279Selan 	}
516759279Selan     }
516859279Selan   if (TREE_CODE (type) == RECORD_TYPE)
516959279Selan     {
517059279Selan       register tree field;
517159279Selan       int members_length = 0;
517259279Selan       int i;
517359279Selan 
517459279Selan       /* Don't leave the loop based on field just yet; see if next item
517559279Selan 	 overrides the expected field first. */
517659279Selan 
517759279Selan       for (field = TYPE_FIELDS (type), i = 0; tail;
517859279Selan 	   field = TREE_CHAIN (field), i++)
517959279Selan 	{
518059279Selan 	  register tree next1;
518159279Selan 
518259279Selan 	  /* If this element specifies a field,
518359279Selan 	     move to that field before storing it in the new list.  */
518459279Selan 	  if (TREE_PURPOSE (tail) != 0)
518559279Selan 	    {
518659279Selan 	      int win = 0;
518759279Selan 
518859279Selan 	      if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE)
518959279Selan 		error ("index value instead of field name in structure initializer");
519059279Selan 	      else
519159279Selan 		{
519259279Selan 		  tree temp;
519359279Selan 		  int j;
519459279Selan 		  for (temp = TYPE_FIELDS (type), j = 0;
519559279Selan 		       temp;
519659279Selan 		       temp = TREE_CHAIN (temp), j++)
519759279Selan 		    if (DECL_NAME (temp) == TREE_PURPOSE (tail))
519859279Selan 		      break;
519959279Selan 		  if (temp)
520059279Selan 		    field = temp, i = j, win = 1;
520159279Selan 		  else
520259279Selan 		    error ("no field `%s' in structure being initialized",
520359279Selan 			   IDENTIFIER_POINTER (TREE_PURPOSE (tail)));
520459279Selan 		}
520559279Selan 	      if (!win)
520659279Selan 		TREE_VALUE (tail) = error_mark_node;
520759279Selan 	    }
520859279Selan 
520959279Selan 	  if (field == 0)
521059279Selan 	    break;  /* No more fields to init. */
521159279Selan 
521259279Selan 	  if (! DECL_NAME (field))
521359279Selan 	    {
521459279Selan 	      next1 = integer_zero_node;
521559279Selan 	    }
521659279Selan 	  else if (TREE_VALUE (tail) != 0)
521759279Selan 	    {
521859279Selan 	      tree tail1 = tail;
521959279Selan 
522059279Selan 	      /* Build the name of this member, with a "." for membership.  */
522159279Selan 	      SAVE_SPELLING_DEPTH
522259279Selan 		({
522359279Selan 		  push_member_name (IDENTIFIER_POINTER (DECL_NAME (field)));
522459279Selan 		  next1 = digest_init (TREE_TYPE (field),
522559279Selan 				       TREE_VALUE (tail), &tail1,
522659279Selan 				       constant_element, constant_element,
522759279Selan 				       NULL_PTR);
522859279Selan 		});
522959279Selan 	      if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST)
523059279Selan 		abort ();
523159279Selan 	      tail = tail1;
523259279Selan 	    }
523359279Selan 	  else
523459279Selan 	    {
523559279Selan 	      next1 = error_mark_node;
523659279Selan 	      tail = TREE_CHAIN (tail);
523759279Selan 	    }
523859279Selan 
523959279Selan 	  if (next1 == error_mark_node)
524059279Selan 	    erroneous = 1;
524159279Selan 	  else if (!TREE_CONSTANT (next1))
524259279Selan 	    allconstant = 0;
524359279Selan 	  else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
524459279Selan 	    allsimple = 0;
524559279Selan 
524659279Selan 	  /* Now store NEXT1 in the list, I elements from the *end*.
524759279Selan 	     Make the list longer if necessary.  */
524859279Selan 	  while (i >= members_length)
524959279Selan 	    {
5250*60373Selan 	      if (free_tree_list)
5251*60373Selan 		{
5252*60373Selan 		  TREE_CHAIN (free_tree_list) = members;
5253*60373Selan 		  TREE_PURPOSE (free_tree_list) = NULL_TREE;
5254*60373Selan 		  TREE_VALUE (free_tree_list) = NULL_TREE;
5255*60373Selan 		  members = free_tree_list;
5256*60373Selan 		  free_tree_list = NULL_TREE;
5257*60373Selan 		}
5258*60373Selan 	      else
5259*60373Selan 		members = tree_cons (NULL_TREE, NULL_TREE, members);
526059279Selan 	      members_length++;
526159279Selan 	    }
526259279Selan 	  {
526359279Selan 	    tree temp;
526459279Selan 	    int j;
526559279Selan 
526659279Selan 	    temp = members;
526759279Selan 	    for (j = members_length - 1; j > i; j--)
526859279Selan 	      temp = TREE_CHAIN (temp);
526959279Selan 	    TREE_VALUE (temp) = next1;
527059279Selan 	    TREE_PURPOSE (temp) = field;
527159279Selan 	  }
527259279Selan 	}
527359279Selan     }
527459279Selan   if (TREE_CODE (type) == UNION_TYPE)
527559279Selan     {
527659279Selan       register tree field = TYPE_FIELDS (type);
527759279Selan       register tree next1;
527859279Selan 
527959279Selan       /* Find the first named field.  ANSI decided in September 1990
528059279Selan 	 that only named fields count here.  */
528159279Selan       while (field && DECL_NAME (field) == 0)
528259279Selan 	field = TREE_CHAIN (field);
528359279Selan 
528459279Selan       /* For a union, get the initializer for 1 fld.  */
528559279Selan 
528659279Selan       if (tail == 0)
528759279Selan 	{
528859279Selan 	  error ("empty initializer for union");
528959279Selan 	  tail = build_tree_list (0, 0);
529059279Selan 	}
529159279Selan 
529259279Selan       /* If this element specifies a field, initialize via that field.  */
529359279Selan       if (TREE_PURPOSE (tail) != 0)
529459279Selan 	{
529559279Selan 	  int win = 0;
529659279Selan 
529759279Selan 	  if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL)
529859279Selan 	    /* Handle the case of a call by build_c_cast.  */
529959279Selan 	    field = TREE_PURPOSE (tail), win = 1;
530059279Selan 	  else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE)
530159279Selan 	    error ("index value instead of field name in union initializer");
530259279Selan 	  else
530359279Selan 	    {
530459279Selan 	      tree temp;
530559279Selan 	      for (temp = TYPE_FIELDS (type);
530659279Selan 		   temp;
530759279Selan 		   temp = TREE_CHAIN (temp))
530859279Selan 		if (DECL_NAME (temp) == TREE_PURPOSE (tail))
530959279Selan 		  break;
531059279Selan 	      if (temp)
531159279Selan 		field = temp, win = 1;
531259279Selan 	      else
531359279Selan 		error ("no field `%s' in union being initialized",
531459279Selan 		       IDENTIFIER_POINTER (TREE_PURPOSE (tail)));
531559279Selan 	    }
531659279Selan 	  if (!win)
531759279Selan 	    TREE_VALUE (tail) = error_mark_node;
531859279Selan 	}
531959279Selan 
532059279Selan       if (TREE_VALUE (tail) != 0)
532159279Selan 	{
532259279Selan 	  tree tail1 = tail;
532359279Selan 
532459279Selan 	  /* Build the name of this member, with a "." for membership.  */
532559279Selan 	  SAVE_SPELLING_DEPTH
532659279Selan 	    ({
532759279Selan 	      push_member_name (IDENTIFIER_POINTER (DECL_NAME (field)));
532859279Selan 	      next1 = digest_init (TREE_TYPE (field),
532959279Selan 				   TREE_VALUE (tail), &tail1,
533059279Selan 				   constant_value, constant_element, NULL_PTR);
533159279Selan 	    });
533259279Selan 	  if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST)
533359279Selan 	    abort ();
533459279Selan 	  tail = tail1;
533559279Selan 	}
533659279Selan       else
533759279Selan 	{
533859279Selan 	  next1 = error_mark_node;
533959279Selan 	  tail = TREE_CHAIN (tail);
534059279Selan 	}
534159279Selan 
534259279Selan       if (next1 == error_mark_node)
534359279Selan 	erroneous = 1;
534459279Selan       else if (!TREE_CONSTANT (next1))
534559279Selan 	allconstant = 0;
534659279Selan       else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
5347*60373Selan 	allsimple = 0;
5348*60373Selan      if (free_tree_list)
5349*60373Selan 	{
5350*60373Selan 	  TREE_CHAIN (free_tree_list) = members;
5351*60373Selan 	  TREE_PURPOSE (free_tree_list) = field;
5352*60373Selan 	  TREE_VALUE (free_tree_list) = next1;
5353*60373Selan 	  members = free_tree_list;
5354*60373Selan 	  free_tree_list = NULL_TREE;
5355*60373Selan 	}
5356*60373Selan       else
5357*60373Selan 	members = tree_cons (field, next1, members);
535859279Selan     }
535959279Selan 
536059279Selan   /* If arguments were specified as a list, just remove the ones we used.  */
536159279Selan   if (elts)
536259279Selan     *elts = tail;
536359279Selan   /* If arguments were specified as a constructor,
536459279Selan      complain unless we used all the elements of the constructor.  */
536559279Selan   else if (tail)
536659279Selan     {
536759279Selan       if (TREE_CODE (type) == UNION_TYPE)
536859279Selan 	{
536959279Selan 	  pedwarn_init ("excess elements in union initializer%s",
537059279Selan 			" after `%s'", NULL_PTR);
537159279Selan 	}
537259279Selan       else
537359279Selan 	{
537459279Selan 	  pedwarn_init ("excess elements in aggregate initializer%s",
537559279Selan 			" after `%s'", NULL_PTR);
537659279Selan 	}
537759279Selan     }
537859279Selan 
537959279Selan   /* It might be possible to use SAVE_SPELLING_DEPTH, but I suspect that
538059279Selan      some preprocessor somewhere won't accept that much text as an argument.
538159279Selan      It's also likely to make debugging difficult.  */
538259279Selan 
538359279Selan   RESTORE_SPELLING_DEPTH (depth);
538459279Selan 
538559279Selan   if (erroneous)
538659279Selan     return error_mark_node;
538759279Selan 
5388*60373Selan   if (elts)
5389*60373Selan     result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members));
5390*60373Selan   else
5391*60373Selan     {
5392*60373Selan       result = init;
5393*60373Selan       CONSTRUCTOR_ELTS (result) = nreverse (members);
5394*60373Selan       TREE_TYPE (result) = type;
5395*60373Selan       TREE_CONSTANT (result) = 0;
5396*60373Selan       TREE_STATIC (result) = 0;
5397*60373Selan     }
539859279Selan   if (allconstant) TREE_CONSTANT (result) = 1;
539959279Selan   if (allconstant && allsimple) TREE_STATIC (result) = 1;
540059279Selan   return result;
540159279Selan }
540259279Selan 
540359279Selan /* Expand an ASM statement with operands, handling output operands
540459279Selan    that are not variables or INDIRECT_REFS by transforming such
540559279Selan    cases into cases that expand_asm_operands can handle.
540659279Selan 
540759279Selan    Arguments are same as for expand_asm_operands.  */
540859279Selan 
540959279Selan void
c_expand_asm_operands(string,outputs,inputs,clobbers,vol,filename,line)541059279Selan c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
541159279Selan      tree string, outputs, inputs, clobbers;
541259279Selan      int vol;
541359279Selan      char *filename;
541459279Selan      int line;
541559279Selan {
541659279Selan   int noutputs = list_length (outputs);
541759279Selan   register int i;
541859279Selan   /* o[I] is the place that output number I should be written.  */
541959279Selan   register tree *o = (tree *) alloca (noutputs * sizeof (tree));
542059279Selan   register tree tail;
542159279Selan 
542259279Selan   if (TREE_CODE (string) == ADDR_EXPR)
542359279Selan     string = TREE_OPERAND (string, 0);
542459279Selan   if (TREE_CODE (string) != STRING_CST)
542559279Selan     {
542659279Selan       error ("asm template is not a string constant");
542759279Selan       return;
542859279Selan     }
542959279Selan 
543059279Selan   /* Record the contents of OUTPUTS before it is modified.  */
543159279Selan   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
543259279Selan     o[i] = TREE_VALUE (tail);
543359279Selan 
543459279Selan   /* Perform default conversions on array and function inputs.  */
543559279Selan   /* Don't do this for other types--
543659279Selan      it would screw up operands expected to be in memory.  */
543759279Selan   for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
543859279Selan     if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE
543959279Selan 	|| TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
544059279Selan       TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
544159279Selan 
544259279Selan   /* Generate the ASM_OPERANDS insn;
544359279Selan      store into the TREE_VALUEs of OUTPUTS some trees for
544459279Selan      where the values were actually stored.  */
544559279Selan   expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
544659279Selan 
544759279Selan   /* Copy all the intermediate outputs into the specified outputs.  */
544859279Selan   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
544959279Selan     {
545059279Selan       if (o[i] != TREE_VALUE (tail))
545159279Selan 	{
545259279Selan 	  expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
545359279Selan 		       0, VOIDmode, 0);
545459279Selan 	  free_temp_slots ();
545559279Selan 	}
545659279Selan       /* Detect modification of read-only values.
545759279Selan 	 (Otherwise done by build_modify_expr.)  */
545859279Selan       else
545959279Selan 	{
546059279Selan 	  tree type = TREE_TYPE (o[i]);
546159279Selan 	  if (TYPE_READONLY (type)
546259279Selan 	      || ((TREE_CODE (type) == RECORD_TYPE
546359279Selan 		   || TREE_CODE (type) == UNION_TYPE)
546459279Selan 		  && C_TYPE_FIELDS_READONLY (type)))
546559279Selan 	    readonly_warning (o[i], "modification by `asm'");
546659279Selan 	}
546759279Selan     }
546859279Selan 
546959279Selan   /* Those MODIFY_EXPRs could do autoincrements.  */
547059279Selan   emit_queue ();
547159279Selan }
547259279Selan 
547359279Selan /* Expand a C `return' statement.
547459279Selan    RETVAL is the expression for what to return,
547559279Selan    or a null pointer for `return;' with no value.  */
547659279Selan 
547759279Selan void
c_expand_return(retval)547859279Selan c_expand_return (retval)
547959279Selan      tree retval;
548059279Selan {
548159279Selan   tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
548259279Selan 
548359279Selan   if (TREE_THIS_VOLATILE (current_function_decl))
548459279Selan     warning ("function declared `volatile' has a `return' statement");
548559279Selan 
548659279Selan   if (!retval)
548759279Selan     {
548859279Selan       current_function_returns_null = 1;
548959279Selan       if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
549059279Selan 	warning ("`return' with no value, in function returning non-void");
549159279Selan       expand_null_return ();
549259279Selan     }
549359279Selan   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
549459279Selan     {
549559279Selan       current_function_returns_null = 1;
549659279Selan       if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
549759279Selan 	pedwarn ("`return' with a value, in function returning void");
549859279Selan       expand_return (retval);
549959279Selan     }
550059279Selan   else
550159279Selan     {
550259279Selan       tree t = convert_for_assignment (valtype, retval, "return",
550359279Selan 				       NULL_TREE, 0);
550459279Selan       tree res = DECL_RESULT (current_function_decl);
550559279Selan       t = build (MODIFY_EXPR, TREE_TYPE (res),
550659279Selan 		 res, convert (TREE_TYPE (res), t));
550759279Selan       expand_return (t);
550859279Selan       current_function_returns_value = 1;
550959279Selan     }
551059279Selan }
551159279Selan 
551259279Selan /* Start a C switch statement, testing expression EXP.
551359279Selan    Return EXP if it is valid, an error node otherwise.  */
551459279Selan 
551559279Selan tree
c_expand_start_case(exp)551659279Selan c_expand_start_case (exp)
551759279Selan      tree exp;
551859279Selan {
551959279Selan   register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
552059279Selan   tree type = TREE_TYPE (exp);
552159279Selan 
552259279Selan   if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
552359279Selan     {
552459279Selan       error ("switch quantity not an integer");
552559279Selan       exp = error_mark_node;
552659279Selan     }
552759279Selan   else
552859279Selan     {
552959279Selan       tree index;
553059279Selan       type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
553159279Selan 
553259279Selan       if (warn_traditional
553359279Selan 	  && (type == long_integer_type_node
553459279Selan 	      || type == long_unsigned_type_node))
553559279Selan 	pedwarn ("`long' switch expression not converted to `int' in ANSI C");
553659279Selan 
553759279Selan       exp = default_conversion (exp);
553859279Selan       type = TREE_TYPE (exp);
553959279Selan       index = get_unwidened (exp, NULL_TREE);
554059279Selan       /* We can't strip a conversion from a signed type to an unsigned,
554159279Selan 	 because if we did, int_fits_type_p would do the wrong thing
554259279Selan 	 when checking case values for being in range,
554359279Selan 	 and it's too hard to do the right thing.  */
554459279Selan       if (TREE_UNSIGNED (TREE_TYPE (exp))
554559279Selan 	  == TREE_UNSIGNED (TREE_TYPE (index)))
554659279Selan 	exp = index;
554759279Selan     }
554859279Selan 
554959279Selan   expand_start_case (1, exp, type, "switch statement");
555059279Selan 
555159279Selan   return exp;
555259279Selan }
5553