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