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