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 = ¤t_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