c-typeck.c revision 96263
118334Speter/* Build expressions with type checking for C compiler. 290075Sobrien Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 390075Sobrien 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2090075Sobrien02111-1307, USA. */ 2118334Speter 2218334Speter 2318334Speter/* This file is part of the C front end. 2418334Speter It contains routines to build C expressions given their operands, 2518334Speter including computing the types of the result, C-specific error checks, 2618334Speter and some optimization. 2718334Speter 2818334Speter There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, 2918334Speter and to process initializations in declarations (since they work 3018334Speter like a strange sort of assignment). */ 3118334Speter 3218334Speter#include "config.h" 3350397Sobrien#include "system.h" 3490075Sobrien#include "rtl.h" 3518334Speter#include "tree.h" 3618334Speter#include "c-tree.h" 3790075Sobrien#include "tm_p.h" 3818334Speter#include "flags.h" 3918334Speter#include "output.h" 4050397Sobrien#include "expr.h" 4150397Sobrien#include "toplev.h" 4252284Sobrien#include "intl.h" 4390075Sobrien#include "ggc.h" 4490075Sobrien#include "target.h" 4518334Speter 4618334Speter/* Nonzero if we've already printed a "missing braces around initializer" 4718334Speter message within this initializer. */ 4818334Speterstatic int missing_braces_mentioned; 4918334Speter 5090075Sobrien/* 1 if we explained undeclared var errors. */ 5190075Sobrienstatic int undeclared_variable_notice; 5290075Sobrien 5390075Sobrienstatic tree qualify_type PARAMS ((tree, tree)); 5490075Sobrienstatic int comp_target_types PARAMS ((tree, tree)); 5590075Sobrienstatic int function_types_compatible_p PARAMS ((tree, tree)); 5690075Sobrienstatic int type_lists_compatible_p PARAMS ((tree, tree)); 5790075Sobrienstatic tree decl_constant_value_for_broken_optimization PARAMS ((tree)); 5890075Sobrienstatic tree default_function_array_conversion PARAMS ((tree)); 5990075Sobrienstatic tree lookup_field PARAMS ((tree, tree)); 6090075Sobrienstatic tree convert_arguments PARAMS ((tree, tree, tree, tree)); 6190075Sobrienstatic tree pointer_diff PARAMS ((tree, tree)); 6290075Sobrienstatic tree unary_complex_lvalue PARAMS ((enum tree_code, tree, int)); 6390075Sobrienstatic void pedantic_lvalue_warning PARAMS ((enum tree_code)); 6490075Sobrienstatic tree internal_build_compound_expr PARAMS ((tree, int)); 6590075Sobrienstatic tree convert_for_assignment PARAMS ((tree, tree, const char *, 6690075Sobrien tree, tree, int)); 6790075Sobrienstatic void warn_for_assignment PARAMS ((const char *, const char *, 6890075Sobrien tree, int)); 6990075Sobrienstatic tree valid_compound_expr_initializer PARAMS ((tree, tree)); 7090075Sobrienstatic void push_string PARAMS ((const char *)); 7190075Sobrienstatic void push_member_name PARAMS ((tree)); 7290075Sobrienstatic void push_array_bounds PARAMS ((int)); 7390075Sobrienstatic int spelling_length PARAMS ((void)); 7490075Sobrienstatic char *print_spelling PARAMS ((char *)); 7590075Sobrienstatic void warning_init PARAMS ((const char *)); 7690075Sobrienstatic tree digest_init PARAMS ((tree, tree, int, int)); 7790075Sobrienstatic void output_init_element PARAMS ((tree, tree, tree, int)); 7890075Sobrienstatic void output_pending_init_elements PARAMS ((int)); 7990075Sobrienstatic int set_designator PARAMS ((int)); 8090075Sobrienstatic void push_range_stack PARAMS ((tree)); 8190075Sobrienstatic void add_pending_init PARAMS ((tree, tree)); 8290075Sobrienstatic void set_nonincremental_init PARAMS ((void)); 8390075Sobrienstatic void set_nonincremental_init_from_string PARAMS ((tree)); 8490075Sobrienstatic tree find_init_member PARAMS ((tree)); 8518334Speter 8618334Speter/* Do `exp = require_complete_type (exp);' to make sure exp 8718334Speter does not have an incomplete type. (That includes void types.) */ 8818334Speter 8918334Spetertree 9018334Speterrequire_complete_type (value) 9118334Speter tree value; 9218334Speter{ 9318334Speter tree type = TREE_TYPE (value); 9418334Speter 9590075Sobrien if (value == error_mark_node || type == error_mark_node) 9652284Sobrien return error_mark_node; 9752284Sobrien 9818334Speter /* First, detect a valid value with a complete type. */ 9990075Sobrien if (COMPLETE_TYPE_P (type)) 10018334Speter return value; 10118334Speter 10218334Speter incomplete_type_error (value, type); 10318334Speter return error_mark_node; 10418334Speter} 10518334Speter 10618334Speter/* Print an error message for invalid use of an incomplete type. 10718334Speter VALUE is the expression that was used (or 0 if that isn't known) 10818334Speter and TYPE is the type that was invalid. */ 10918334Speter 11018334Spetervoid 11118334Speterincomplete_type_error (value, type) 11218334Speter tree value; 11318334Speter tree type; 11418334Speter{ 11552284Sobrien const char *type_code_string; 11618334Speter 11718334Speter /* Avoid duplicate error message. */ 11818334Speter if (TREE_CODE (type) == ERROR_MARK) 11918334Speter return; 12018334Speter 12118334Speter if (value != 0 && (TREE_CODE (value) == VAR_DECL 12218334Speter || TREE_CODE (value) == PARM_DECL)) 12318334Speter error ("`%s' has an incomplete type", 12418334Speter IDENTIFIER_POINTER (DECL_NAME (value))); 12518334Speter else 12618334Speter { 12718334Speter retry: 12818334Speter /* We must print an error message. Be clever about what it says. */ 12918334Speter 13018334Speter switch (TREE_CODE (type)) 13118334Speter { 13218334Speter case RECORD_TYPE: 13352284Sobrien type_code_string = "struct"; 13418334Speter break; 13518334Speter 13618334Speter case UNION_TYPE: 13752284Sobrien type_code_string = "union"; 13818334Speter break; 13918334Speter 14018334Speter case ENUMERAL_TYPE: 14152284Sobrien type_code_string = "enum"; 14218334Speter break; 14318334Speter 14418334Speter case VOID_TYPE: 14518334Speter error ("invalid use of void expression"); 14618334Speter return; 14718334Speter 14818334Speter case ARRAY_TYPE: 14918334Speter if (TYPE_DOMAIN (type)) 15018334Speter { 15196263Sobrien if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL) 15296263Sobrien { 15396263Sobrien error ("invalid use of flexible array member"); 15496263Sobrien return; 15596263Sobrien } 15618334Speter type = TREE_TYPE (type); 15718334Speter goto retry; 15818334Speter } 15918334Speter error ("invalid use of array with unspecified bounds"); 16018334Speter return; 16118334Speter 16218334Speter default: 16318334Speter abort (); 16418334Speter } 16518334Speter 16618334Speter if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 16752284Sobrien error ("invalid use of undefined type `%s %s'", 16852284Sobrien type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type))); 16918334Speter else 17018334Speter /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ 17118334Speter error ("invalid use of incomplete typedef `%s'", 17218334Speter IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); 17318334Speter } 17418334Speter} 17518334Speter 17618334Speter/* Return a variant of TYPE which has all the type qualifiers of LIKE 17718334Speter as well as those of TYPE. */ 17818334Speter 17918334Speterstatic tree 18018334Speterqualify_type (type, like) 18118334Speter tree type, like; 18218334Speter{ 18352750Sobrien return c_build_qualified_type (type, 18452750Sobrien TYPE_QUALS (type) | TYPE_QUALS (like)); 18518334Speter} 18618334Speter 18718334Speter/* Return the common type of two types. 18818334Speter We assume that comptypes has already been done and returned 1; 18918334Speter if that isn't so, this may crash. In particular, we assume that qualifiers 19018334Speter match. 19118334Speter 19218334Speter This is the type for the result of most arithmetic operations 19318334Speter if the operands have the given two types. */ 19418334Speter 19518334Spetertree 19618334Spetercommon_type (t1, t2) 19718334Speter tree t1, t2; 19818334Speter{ 19990075Sobrien enum tree_code code1; 20090075Sobrien enum tree_code code2; 20118334Speter tree attributes; 20218334Speter 20318334Speter /* Save time if the two types are the same. */ 20418334Speter 20518334Speter if (t1 == t2) return t1; 20618334Speter 20718334Speter /* If one type is nonsense, use the other. */ 20818334Speter if (t1 == error_mark_node) 20918334Speter return t2; 21018334Speter if (t2 == error_mark_node) 21118334Speter return t1; 21218334Speter 21350397Sobrien /* Merge the attributes. */ 21490075Sobrien attributes = (*targetm.merge_type_attributes) (t1, t2); 21518334Speter 21618334Speter /* Treat an enum type as the unsigned integer type of the same width. */ 21718334Speter 21818334Speter if (TREE_CODE (t1) == ENUMERAL_TYPE) 21918334Speter t1 = type_for_size (TYPE_PRECISION (t1), 1); 22018334Speter if (TREE_CODE (t2) == ENUMERAL_TYPE) 22118334Speter t2 = type_for_size (TYPE_PRECISION (t2), 1); 22218334Speter 22318334Speter code1 = TREE_CODE (t1); 22418334Speter code2 = TREE_CODE (t2); 22518334Speter 22618334Speter /* If one type is complex, form the common type of the non-complex 22718334Speter components, then make that complex. Use T1 or T2 if it is the 22818334Speter required type. */ 22918334Speter if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) 23018334Speter { 23118334Speter tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; 23218334Speter tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; 23318334Speter tree subtype = common_type (subtype1, subtype2); 23418334Speter 23518334Speter if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) 23618334Speter return build_type_attribute_variant (t1, attributes); 23718334Speter else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) 23818334Speter return build_type_attribute_variant (t2, attributes); 23918334Speter else 24018334Speter return build_type_attribute_variant (build_complex_type (subtype), 24118334Speter attributes); 24218334Speter } 24318334Speter 24418334Speter switch (code1) 24518334Speter { 24618334Speter case INTEGER_TYPE: 24718334Speter case REAL_TYPE: 24818334Speter /* If only one is real, use it as the result. */ 24918334Speter 25018334Speter if (code1 == REAL_TYPE && code2 != REAL_TYPE) 25118334Speter return build_type_attribute_variant (t1, attributes); 25218334Speter 25318334Speter if (code2 == REAL_TYPE && code1 != REAL_TYPE) 25418334Speter return build_type_attribute_variant (t2, attributes); 25518334Speter 25618334Speter /* Both real or both integers; use the one with greater precision. */ 25718334Speter 25818334Speter if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) 25918334Speter return build_type_attribute_variant (t1, attributes); 26018334Speter else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) 26118334Speter return build_type_attribute_variant (t2, attributes); 26218334Speter 26318334Speter /* Same precision. Prefer longs to ints even when same size. */ 26418334Speter 26518334Speter if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node 26618334Speter || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) 26718334Speter return build_type_attribute_variant (long_unsigned_type_node, 26818334Speter attributes); 26918334Speter 27018334Speter if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node 27118334Speter || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) 27218334Speter { 27318334Speter /* But preserve unsignedness from the other type, 27418334Speter since long cannot hold all the values of an unsigned int. */ 27518334Speter if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) 27618334Speter t1 = long_unsigned_type_node; 27718334Speter else 27818334Speter t1 = long_integer_type_node; 27918334Speter return build_type_attribute_variant (t1, attributes); 28018334Speter } 28118334Speter 28250397Sobrien /* Likewise, prefer long double to double even if same size. */ 28350397Sobrien if (TYPE_MAIN_VARIANT (t1) == long_double_type_node 28450397Sobrien || TYPE_MAIN_VARIANT (t2) == long_double_type_node) 28550397Sobrien return build_type_attribute_variant (long_double_type_node, 28650397Sobrien attributes); 28750397Sobrien 28818334Speter /* Otherwise prefer the unsigned one. */ 28918334Speter 29018334Speter if (TREE_UNSIGNED (t1)) 29118334Speter return build_type_attribute_variant (t1, attributes); 29218334Speter else 29318334Speter return build_type_attribute_variant (t2, attributes); 29418334Speter 29518334Speter case POINTER_TYPE: 29618334Speter /* For two pointers, do this recursively on the target type, 29718334Speter and combine the qualifiers of the two types' targets. */ 29818334Speter /* This code was turned off; I don't know why. 29918334Speter But ANSI C specifies doing this with the qualifiers. 30018334Speter So I turned it on again. */ 30118334Speter { 30252284Sobrien tree pointed_to_1 = TREE_TYPE (t1); 30352284Sobrien tree pointed_to_2 = TREE_TYPE (t2); 30452284Sobrien tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1), 30552284Sobrien TYPE_MAIN_VARIANT (pointed_to_2)); 30652284Sobrien t1 = build_pointer_type (c_build_qualified_type 30752284Sobrien (target, 30852284Sobrien TYPE_QUALS (pointed_to_1) | 30952284Sobrien TYPE_QUALS (pointed_to_2))); 31018334Speter return build_type_attribute_variant (t1, attributes); 31118334Speter } 31218334Speter#if 0 31318334Speter t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); 31418334Speter return build_type_attribute_variant (t1, attributes); 31518334Speter#endif 31618334Speter 31718334Speter case ARRAY_TYPE: 31818334Speter { 31918334Speter tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); 32018334Speter /* Save space: see if the result is identical to one of the args. */ 32118334Speter if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) 32218334Speter return build_type_attribute_variant (t1, attributes); 32318334Speter if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) 32418334Speter return build_type_attribute_variant (t2, attributes); 32518334Speter /* Merge the element types, and have a size if either arg has one. */ 32618334Speter t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); 32718334Speter return build_type_attribute_variant (t1, attributes); 32818334Speter } 32918334Speter 33018334Speter case FUNCTION_TYPE: 33118334Speter /* Function types: prefer the one that specified arg types. 33218334Speter If both do, merge the arg types. Also merge the return types. */ 33318334Speter { 33418334Speter tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); 33518334Speter tree p1 = TYPE_ARG_TYPES (t1); 33618334Speter tree p2 = TYPE_ARG_TYPES (t2); 33718334Speter int len; 33818334Speter tree newargs, n; 33918334Speter int i; 34018334Speter 34118334Speter /* Save space: see if the result is identical to one of the args. */ 34218334Speter if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2)) 34318334Speter return build_type_attribute_variant (t1, attributes); 34418334Speter if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) 34518334Speter return build_type_attribute_variant (t2, attributes); 34618334Speter 34718334Speter /* Simple way if one arg fails to specify argument types. */ 34818334Speter if (TYPE_ARG_TYPES (t1) == 0) 34918334Speter { 35018334Speter t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); 35118334Speter return build_type_attribute_variant (t1, attributes); 35218334Speter } 35318334Speter if (TYPE_ARG_TYPES (t2) == 0) 35418334Speter { 35518334Speter t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); 35618334Speter return build_type_attribute_variant (t1, attributes); 35718334Speter } 35818334Speter 35918334Speter /* If both args specify argument types, we must merge the two 36018334Speter lists, argument by argument. */ 36118334Speter 36290075Sobrien pushlevel (0); 36390075Sobrien declare_parm_level (1); 36490075Sobrien 36518334Speter len = list_length (p1); 36618334Speter newargs = 0; 36718334Speter 36818334Speter for (i = 0; i < len; i++) 36918334Speter newargs = tree_cons (NULL_TREE, NULL_TREE, newargs); 37018334Speter 37118334Speter n = newargs; 37218334Speter 37318334Speter for (; p1; 37418334Speter p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n)) 37518334Speter { 37618334Speter /* A null type means arg type is not specified. 37718334Speter Take whatever the other function type has. */ 37818334Speter if (TREE_VALUE (p1) == 0) 37918334Speter { 38018334Speter TREE_VALUE (n) = TREE_VALUE (p2); 38118334Speter goto parm_done; 38218334Speter } 38318334Speter if (TREE_VALUE (p2) == 0) 38418334Speter { 38518334Speter TREE_VALUE (n) = TREE_VALUE (p1); 38618334Speter goto parm_done; 38718334Speter } 38818334Speter 38918334Speter /* Given wait (union {union wait *u; int *i} *) 39018334Speter and wait (union wait *), 39118334Speter prefer union wait * as type of parm. */ 39218334Speter if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE 39318334Speter && TREE_VALUE (p1) != TREE_VALUE (p2)) 39418334Speter { 39518334Speter tree memb; 39618334Speter for (memb = TYPE_FIELDS (TREE_VALUE (p1)); 39718334Speter memb; memb = TREE_CHAIN (memb)) 39818334Speter if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2))) 39918334Speter { 40018334Speter TREE_VALUE (n) = TREE_VALUE (p2); 40118334Speter if (pedantic) 40290075Sobrien pedwarn ("function types not truly compatible in ISO C"); 40318334Speter goto parm_done; 40418334Speter } 40518334Speter } 40618334Speter if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE 40718334Speter && TREE_VALUE (p2) != TREE_VALUE (p1)) 40818334Speter { 40918334Speter tree memb; 41018334Speter for (memb = TYPE_FIELDS (TREE_VALUE (p2)); 41118334Speter memb; memb = TREE_CHAIN (memb)) 41218334Speter if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1))) 41318334Speter { 41418334Speter TREE_VALUE (n) = TREE_VALUE (p1); 41518334Speter if (pedantic) 41690075Sobrien pedwarn ("function types not truly compatible in ISO C"); 41718334Speter goto parm_done; 41818334Speter } 41918334Speter } 42018334Speter TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); 42118334Speter parm_done: ; 42218334Speter } 42318334Speter 42490075Sobrien poplevel (0, 0, 0); 42590075Sobrien 42618334Speter t1 = build_function_type (valtype, newargs); 42750397Sobrien /* ... falls through ... */ 42818334Speter } 42918334Speter 43018334Speter default: 43118334Speter return build_type_attribute_variant (t1, attributes); 43218334Speter } 43318334Speter 43418334Speter} 43518334Speter 43618334Speter/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment 43718334Speter or various other operations. Return 2 if they are compatible 43818334Speter but a warning may be needed if you use them together. */ 43918334Speter 44018334Speterint 44118334Spetercomptypes (type1, type2) 44218334Speter tree type1, type2; 44318334Speter{ 44490075Sobrien tree t1 = type1; 44590075Sobrien tree t2 = type2; 44618334Speter int attrval, val; 44718334Speter 44818334Speter /* Suppress errors caused by previously reported errors. */ 44918334Speter 45050397Sobrien if (t1 == t2 || !t1 || !t2 45150397Sobrien || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK) 45218334Speter return 1; 45318334Speter 45490075Sobrien /* If either type is the internal version of sizetype, return the 45590075Sobrien language version. */ 45690075Sobrien if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1) 45790075Sobrien && TYPE_DOMAIN (t1) != 0) 45890075Sobrien t1 = TYPE_DOMAIN (t1); 45990075Sobrien 46090075Sobrien if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2) 46190075Sobrien && TYPE_DOMAIN (t2) != 0) 46290075Sobrien t2 = TYPE_DOMAIN (t2); 46390075Sobrien 46418334Speter /* Treat an enum type as the integer type of the same width and 46518334Speter signedness. */ 46618334Speter 46718334Speter if (TREE_CODE (t1) == ENUMERAL_TYPE) 46818334Speter t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1)); 46918334Speter if (TREE_CODE (t2) == ENUMERAL_TYPE) 47018334Speter t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2)); 47118334Speter 47218334Speter if (t1 == t2) 47318334Speter return 1; 47418334Speter 47518334Speter /* Different classes of types can't be compatible. */ 47618334Speter 47718334Speter if (TREE_CODE (t1) != TREE_CODE (t2)) return 0; 47818334Speter 47918334Speter /* Qualifiers must match. */ 48018334Speter 48152284Sobrien if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) 48218334Speter return 0; 48318334Speter 48418334Speter /* Allow for two different type nodes which have essentially the same 48518334Speter definition. Note that we already checked for equality of the type 48650397Sobrien qualifiers (just above). */ 48718334Speter 48818334Speter if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) 48918334Speter return 1; 49018334Speter 49118334Speter /* 1 if no need for warning yet, 2 if warning cause has been seen. */ 49290075Sobrien if (! (attrval = (*targetm.comp_type_attributes) (t1, t2))) 49318334Speter return 0; 49418334Speter 49518334Speter /* 1 if no need for warning yet, 2 if warning cause has been seen. */ 49618334Speter val = 0; 49718334Speter 49818334Speter switch (TREE_CODE (t1)) 49918334Speter { 50018334Speter case POINTER_TYPE: 50118334Speter val = (TREE_TYPE (t1) == TREE_TYPE (t2) 50218334Speter ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); 50318334Speter break; 50418334Speter 50518334Speter case FUNCTION_TYPE: 50618334Speter val = function_types_compatible_p (t1, t2); 50718334Speter break; 50818334Speter 50918334Speter case ARRAY_TYPE: 51018334Speter { 51118334Speter tree d1 = TYPE_DOMAIN (t1); 51218334Speter tree d2 = TYPE_DOMAIN (t2); 51390075Sobrien bool d1_variable, d2_variable; 51490075Sobrien bool d1_zero, d2_zero; 51518334Speter val = 1; 51618334Speter 51718334Speter /* Target types must match incl. qualifiers. */ 51818334Speter if (TREE_TYPE (t1) != TREE_TYPE (t2) 51918334Speter && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))) 52018334Speter return 0; 52118334Speter 52218334Speter /* Sizes must match unless one is missing or variable. */ 52390075Sobrien if (d1 == 0 || d2 == 0 || d1 == d2) 52418334Speter break; 52518334Speter 52690075Sobrien d1_zero = ! TYPE_MAX_VALUE (d1); 52790075Sobrien d2_zero = ! TYPE_MAX_VALUE (d2); 52890075Sobrien 52990075Sobrien d1_variable = (! d1_zero 53090075Sobrien && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST 53190075Sobrien || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST)); 53290075Sobrien d2_variable = (! d2_zero 53390075Sobrien && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST 53490075Sobrien || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)); 53590075Sobrien 53690075Sobrien if (d1_variable || d2_variable) 53790075Sobrien break; 53890075Sobrien if (d1_zero && d2_zero) 53990075Sobrien break; 54090075Sobrien if (d1_zero || d2_zero 54190075Sobrien || ! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)) 54290075Sobrien || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2))) 54390075Sobrien val = 0; 54490075Sobrien 54518334Speter break; 54618334Speter } 54718334Speter 54818334Speter case RECORD_TYPE: 54918334Speter if (maybe_objc_comptypes (t1, t2, 0) == 1) 55018334Speter val = 1; 55118334Speter break; 55250397Sobrien 55350397Sobrien default: 55450397Sobrien break; 55518334Speter } 55618334Speter return attrval == 2 && val == 1 ? 2 : val; 55718334Speter} 55818334Speter 55918334Speter/* Return 1 if TTL and TTR are pointers to types that are equivalent, 56018334Speter ignoring their qualifiers. */ 56118334Speter 56218334Speterstatic int 56318334Spetercomp_target_types (ttl, ttr) 56418334Speter tree ttl, ttr; 56518334Speter{ 56618334Speter int val; 56718334Speter 56818334Speter /* Give maybe_objc_comptypes a crack at letting these types through. */ 56950397Sobrien if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0) 57018334Speter return val; 57118334Speter 57218334Speter val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)), 57318334Speter TYPE_MAIN_VARIANT (TREE_TYPE (ttr))); 57418334Speter 57518334Speter if (val == 2 && pedantic) 57618334Speter pedwarn ("types are not quite compatible"); 57718334Speter return val; 57818334Speter} 57918334Speter 58018334Speter/* Subroutines of `comptypes'. */ 58118334Speter 58218334Speter/* Return 1 if two function types F1 and F2 are compatible. 58318334Speter If either type specifies no argument types, 58418334Speter the other must specify a fixed number of self-promoting arg types. 58518334Speter Otherwise, if one type specifies only the number of arguments, 58618334Speter the other must specify that number of self-promoting arg types. 58718334Speter Otherwise, the argument types must match. */ 58818334Speter 58918334Speterstatic int 59018334Speterfunction_types_compatible_p (f1, f2) 59118334Speter tree f1, f2; 59218334Speter{ 59318334Speter tree args1, args2; 59418334Speter /* 1 if no need for warning yet, 2 if warning cause has been seen. */ 59518334Speter int val = 1; 59618334Speter int val1; 59718334Speter 59818334Speter if (!(TREE_TYPE (f1) == TREE_TYPE (f2) 59918334Speter || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2))))) 60018334Speter return 0; 60118334Speter 60218334Speter args1 = TYPE_ARG_TYPES (f1); 60318334Speter args2 = TYPE_ARG_TYPES (f2); 60418334Speter 60518334Speter /* An unspecified parmlist matches any specified parmlist 60618334Speter whose argument types don't need default promotions. */ 60718334Speter 60818334Speter if (args1 == 0) 60918334Speter { 61018334Speter if (!self_promoting_args_p (args2)) 61118334Speter return 0; 61218334Speter /* If one of these types comes from a non-prototype fn definition, 61318334Speter compare that with the other type's arglist. 61418334Speter If they don't match, ask for a warning (but no error). */ 61518334Speter if (TYPE_ACTUAL_ARG_TYPES (f1) 61618334Speter && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1))) 61718334Speter val = 2; 61818334Speter return val; 61918334Speter } 62018334Speter if (args2 == 0) 62118334Speter { 62218334Speter if (!self_promoting_args_p (args1)) 62318334Speter return 0; 62418334Speter if (TYPE_ACTUAL_ARG_TYPES (f2) 62518334Speter && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2))) 62618334Speter val = 2; 62718334Speter return val; 62818334Speter } 62918334Speter 63018334Speter /* Both types have argument lists: compare them and propagate results. */ 63118334Speter val1 = type_lists_compatible_p (args1, args2); 63218334Speter return val1 != 1 ? val1 : val; 63318334Speter} 63418334Speter 63518334Speter/* Check two lists of types for compatibility, 63618334Speter returning 0 for incompatible, 1 for compatible, 63718334Speter or 2 for compatible with warning. */ 63818334Speter 63918334Speterstatic int 64018334Spetertype_lists_compatible_p (args1, args2) 64118334Speter tree args1, args2; 64218334Speter{ 64318334Speter /* 1 if no need for warning yet, 2 if warning cause has been seen. */ 64418334Speter int val = 1; 64518334Speter int newval = 0; 64618334Speter 64718334Speter while (1) 64818334Speter { 64918334Speter if (args1 == 0 && args2 == 0) 65018334Speter return val; 65118334Speter /* If one list is shorter than the other, 65218334Speter they fail to match. */ 65318334Speter if (args1 == 0 || args2 == 0) 65418334Speter return 0; 65518334Speter /* A null pointer instead of a type 65618334Speter means there is supposed to be an argument 65718334Speter but nothing is specified about what type it has. 65818334Speter So match anything that self-promotes. */ 65918334Speter if (TREE_VALUE (args1) == 0) 66018334Speter { 66190075Sobrien if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE) 66218334Speter return 0; 66318334Speter } 66418334Speter else if (TREE_VALUE (args2) == 0) 66518334Speter { 66690075Sobrien if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE) 66718334Speter return 0; 66818334Speter } 66990075Sobrien else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)), 67090075Sobrien TYPE_MAIN_VARIANT (TREE_VALUE (args2))))) 67118334Speter { 67218334Speter /* Allow wait (union {union wait *u; int *i} *) 67318334Speter and wait (union wait *) to be compatible. */ 67418334Speter if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE 67518334Speter && (TYPE_NAME (TREE_VALUE (args1)) == 0 67618334Speter || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1))) 67718334Speter && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST 67818334Speter && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)), 67918334Speter TYPE_SIZE (TREE_VALUE (args2)))) 68018334Speter { 68118334Speter tree memb; 68218334Speter for (memb = TYPE_FIELDS (TREE_VALUE (args1)); 68318334Speter memb; memb = TREE_CHAIN (memb)) 68418334Speter if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2))) 68518334Speter break; 68618334Speter if (memb == 0) 68718334Speter return 0; 68818334Speter } 68918334Speter else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE 69018334Speter && (TYPE_NAME (TREE_VALUE (args2)) == 0 69118334Speter || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2))) 69218334Speter && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST 69318334Speter && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)), 69418334Speter TYPE_SIZE (TREE_VALUE (args1)))) 69518334Speter { 69618334Speter tree memb; 69718334Speter for (memb = TYPE_FIELDS (TREE_VALUE (args2)); 69818334Speter memb; memb = TREE_CHAIN (memb)) 69918334Speter if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1))) 70018334Speter break; 70118334Speter if (memb == 0) 70218334Speter return 0; 70318334Speter } 70418334Speter else 70518334Speter return 0; 70618334Speter } 70718334Speter 70818334Speter /* comptypes said ok, but record if it said to warn. */ 70918334Speter if (newval > val) 71018334Speter val = newval; 71118334Speter 71218334Speter args1 = TREE_CHAIN (args1); 71318334Speter args2 = TREE_CHAIN (args2); 71418334Speter } 71518334Speter} 71618334Speter 71718334Speter/* Compute the value of the `sizeof' operator. */ 71818334Speter 71918334Spetertree 72018334Speterc_sizeof (type) 72118334Speter tree type; 72218334Speter{ 72318334Speter enum tree_code code = TREE_CODE (type); 72490075Sobrien tree size; 72518334Speter 72618334Speter if (code == FUNCTION_TYPE) 72718334Speter { 72818334Speter if (pedantic || warn_pointer_arith) 72918334Speter pedwarn ("sizeof applied to a function type"); 73090075Sobrien size = size_one_node; 73118334Speter } 73290075Sobrien else if (code == VOID_TYPE) 73318334Speter { 73418334Speter if (pedantic || warn_pointer_arith) 73518334Speter pedwarn ("sizeof applied to a void type"); 73690075Sobrien size = size_one_node; 73718334Speter } 73890075Sobrien else if (code == ERROR_MARK) 73990075Sobrien size = size_one_node; 74090075Sobrien else if (!COMPLETE_TYPE_P (type)) 74118334Speter { 74218334Speter error ("sizeof applied to an incomplete type"); 74390075Sobrien size = size_zero_node; 74418334Speter } 74590075Sobrien else 74690075Sobrien /* Convert in case a char is more than one unit. */ 74790075Sobrien size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), 74890075Sobrien size_int (TYPE_PRECISION (char_type_node) 74990075Sobrien / BITS_PER_UNIT)); 75018334Speter 75190075Sobrien /* SIZE will have an integer type with TYPE_IS_SIZETYPE set. 75290075Sobrien TYPE_IS_SIZETYPE means that certain things (like overflow) will 75390075Sobrien never happen. However, this node should really have type 75490075Sobrien `size_t', which is just a typedef for an ordinary integer type. */ 75590075Sobrien return fold (build1 (NOP_EXPR, c_size_type_node, size)); 75618334Speter} 75718334Speter 75818334Spetertree 75918334Speterc_sizeof_nowarn (type) 76018334Speter tree type; 76118334Speter{ 76218334Speter enum tree_code code = TREE_CODE (type); 76390075Sobrien tree size; 76418334Speter 76590075Sobrien if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) 76690075Sobrien size = size_one_node; 76790075Sobrien else if (!COMPLETE_TYPE_P (type)) 76890075Sobrien size = size_zero_node; 76990075Sobrien else 77090075Sobrien /* Convert in case a char is more than one unit. */ 77190075Sobrien size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), 77290075Sobrien size_int (TYPE_PRECISION (char_type_node) 77390075Sobrien / BITS_PER_UNIT)); 77418334Speter 77590075Sobrien /* SIZE will have an integer type with TYPE_IS_SIZETYPE set. 77690075Sobrien TYPE_IS_SIZETYPE means that certain things (like overflow) will 77790075Sobrien never happen. However, this node should really have type 77890075Sobrien `size_t', which is just a typedef for an ordinary integer type. */ 77990075Sobrien return fold (build1 (NOP_EXPR, c_size_type_node, size)); 78018334Speter} 78118334Speter 78218334Speter/* Compute the size to increment a pointer by. */ 78318334Speter 78418334Spetertree 78518334Speterc_size_in_bytes (type) 78618334Speter tree type; 78718334Speter{ 78818334Speter enum tree_code code = TREE_CODE (type); 78918334Speter 79090075Sobrien if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) 79190075Sobrien return size_one_node; 79290075Sobrien 79390075Sobrien if (!COMPLETE_OR_VOID_TYPE_P (type)) 79418334Speter { 79518334Speter error ("arithmetic on pointer to an incomplete type"); 79690075Sobrien return size_one_node; 79718334Speter } 79818334Speter 79918334Speter /* Convert in case a char is more than one unit. */ 80090075Sobrien return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), 80190075Sobrien size_int (TYPE_PRECISION (char_type_node) 80290075Sobrien / BITS_PER_UNIT)); 80318334Speter} 80418334Speter 80590075Sobrien/* Return either DECL or its known constant value (if it has one). */ 80618334Speter 80718334Spetertree 80818334Speterdecl_constant_value (decl) 80918334Speter tree decl; 81018334Speter{ 81150397Sobrien if (/* Don't change a variable array bound or initial value to a constant 81218334Speter in a place where a variable is invalid. */ 81350397Sobrien current_function_decl != 0 81418334Speter && ! TREE_THIS_VOLATILE (decl) 81590075Sobrien && TREE_READONLY (decl) 81618334Speter && DECL_INITIAL (decl) != 0 81718334Speter && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK 81818334Speter /* This is invalid if initial value is not constant. 81918334Speter If it has either a function call, a memory reference, 82018334Speter or a variable, then re-evaluating it could give different results. */ 82118334Speter && TREE_CONSTANT (DECL_INITIAL (decl)) 82218334Speter /* Check for cases where this is sub-optimal, even though valid. */ 82390075Sobrien && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) 82418334Speter return DECL_INITIAL (decl); 82518334Speter return decl; 82618334Speter} 82718334Speter 82890075Sobrien/* Return either DECL or its known constant value (if it has one), but 82990075Sobrien return DECL if pedantic or DECL has mode BLKmode. This is for 83090075Sobrien bug-compatibility with the old behavior of decl_constant_value 83190075Sobrien (before GCC 3.0); every use of this function is a bug and it should 83290075Sobrien be removed before GCC 3.1. It is not appropriate to use pedantic 83390075Sobrien in a way that affects optimization, and BLKmode is probably not the 83490075Sobrien right test for avoiding misoptimizations either. */ 83518334Speter 83690075Sobrienstatic tree 83790075Sobriendecl_constant_value_for_broken_optimization (decl) 83890075Sobrien tree decl; 83918334Speter{ 84090075Sobrien if (pedantic || DECL_MODE (decl) == BLKmode) 84190075Sobrien return decl; 84290075Sobrien else 84390075Sobrien return decl_constant_value (decl); 84490075Sobrien} 84518334Speter 84618334Speter 84790075Sobrien/* Perform the default conversion of arrays and functions to pointers. 84890075Sobrien Return the result of converting EXP. For any other expression, just 84990075Sobrien return EXP. */ 85018334Speter 85190075Sobrienstatic tree 85290075Sobriendefault_function_array_conversion (exp) 85390075Sobrien tree exp; 85490075Sobrien{ 85590075Sobrien tree orig_exp; 85690075Sobrien tree type = TREE_TYPE (exp); 85790075Sobrien enum tree_code code = TREE_CODE (type); 85890075Sobrien int not_lvalue = 0; 85990075Sobrien 86018334Speter /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as 86190075Sobrien an lvalue. 86290075Sobrien 86390075Sobrien Do not use STRIP_NOPS here! It will remove conversions from pointer 86418334Speter to integer and cause infinite recursion. */ 86590075Sobrien orig_exp = exp; 86618334Speter while (TREE_CODE (exp) == NON_LVALUE_EXPR 86718334Speter || (TREE_CODE (exp) == NOP_EXPR 86818334Speter && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp))) 86918334Speter { 87090075Sobrien if (TREE_CODE (exp) == NON_LVALUE_EXPR) 87190075Sobrien not_lvalue = 1; 87290075Sobrien exp = TREE_OPERAND (exp, 0); 87318334Speter } 87418334Speter 87590075Sobrien /* Preserve the original expression code. */ 87690075Sobrien if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp)))) 87790075Sobrien C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp)); 87850397Sobrien 87918334Speter if (code == FUNCTION_TYPE) 88018334Speter { 88118334Speter return build_unary_op (ADDR_EXPR, exp, 0); 88218334Speter } 88318334Speter if (code == ARRAY_TYPE) 88418334Speter { 88590075Sobrien tree adr; 88618334Speter tree restype = TREE_TYPE (type); 88718334Speter tree ptrtype; 88818334Speter int constp = 0; 88918334Speter int volatilep = 0; 89090075Sobrien int lvalue_array_p; 89118334Speter 89290075Sobrien if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r' || DECL_P (exp)) 89318334Speter { 89418334Speter constp = TREE_READONLY (exp); 89518334Speter volatilep = TREE_THIS_VOLATILE (exp); 89618334Speter } 89718334Speter 89852284Sobrien if (TYPE_QUALS (type) || constp || volatilep) 89952284Sobrien restype 90052284Sobrien = c_build_qualified_type (restype, 90152284Sobrien TYPE_QUALS (type) 90252284Sobrien | (constp * TYPE_QUAL_CONST) 90352284Sobrien | (volatilep * TYPE_QUAL_VOLATILE)); 90418334Speter 90518334Speter if (TREE_CODE (exp) == INDIRECT_REF) 90618334Speter return convert (TYPE_POINTER_TO (restype), 90718334Speter TREE_OPERAND (exp, 0)); 90818334Speter 90918334Speter if (TREE_CODE (exp) == COMPOUND_EXPR) 91018334Speter { 91118334Speter tree op1 = default_conversion (TREE_OPERAND (exp, 1)); 91218334Speter return build (COMPOUND_EXPR, TREE_TYPE (op1), 91318334Speter TREE_OPERAND (exp, 0), op1); 91418334Speter } 91518334Speter 91690075Sobrien lvalue_array_p = !not_lvalue && lvalue_p (exp); 91790075Sobrien if (!flag_isoc99 && !lvalue_array_p) 91818334Speter { 91990075Sobrien /* Before C99, non-lvalue arrays do not decay to pointers. 92090075Sobrien Normally, using such an array would be invalid; but it can 92190075Sobrien be used correctly inside sizeof or as a statement expression. 92290075Sobrien Thus, do not give an error here; an error will result later. */ 92390075Sobrien return exp; 92418334Speter } 92518334Speter 92618334Speter ptrtype = build_pointer_type (restype); 92718334Speter 92818334Speter if (TREE_CODE (exp) == VAR_DECL) 92918334Speter { 93018334Speter /* ??? This is not really quite correct 93118334Speter in that the type of the operand of ADDR_EXPR 93218334Speter is not the target type of the type of the ADDR_EXPR itself. 93318334Speter Question is, can this lossage be avoided? */ 93418334Speter adr = build1 (ADDR_EXPR, ptrtype, exp); 93518334Speter if (mark_addressable (exp) == 0) 93618334Speter return error_mark_node; 93718334Speter TREE_CONSTANT (adr) = staticp (exp); 93818334Speter TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ 93918334Speter return adr; 94018334Speter } 94118334Speter /* This way is better for a COMPONENT_REF since it can 94218334Speter simplify the offset for a component. */ 94318334Speter adr = build_unary_op (ADDR_EXPR, exp, 1); 94418334Speter return convert (ptrtype, adr); 94518334Speter } 94618334Speter return exp; 94718334Speter} 94890075Sobrien 94990075Sobrien/* Perform default promotions for C data used in expressions. 95090075Sobrien Arrays and functions are converted to pointers; 95190075Sobrien enumeral types or short or char, to int. 95290075Sobrien In addition, manifest constants symbols are replaced by their values. */ 95390075Sobrien 95490075Sobrientree 95590075Sobriendefault_conversion (exp) 95690075Sobrien tree exp; 95790075Sobrien{ 95890075Sobrien tree orig_exp; 95990075Sobrien tree type = TREE_TYPE (exp); 96090075Sobrien enum tree_code code = TREE_CODE (type); 96190075Sobrien 96290075Sobrien if (code == FUNCTION_TYPE || code == ARRAY_TYPE) 96390075Sobrien return default_function_array_conversion (exp); 96490075Sobrien 96590075Sobrien /* Constants can be used directly unless they're not loadable. */ 96690075Sobrien if (TREE_CODE (exp) == CONST_DECL) 96790075Sobrien exp = DECL_INITIAL (exp); 96890075Sobrien 96990075Sobrien /* Replace a nonvolatile const static variable with its value unless 97090075Sobrien it is an array, in which case we must be sure that taking the 97190075Sobrien address of the array produces consistent results. */ 97290075Sobrien else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE) 97390075Sobrien { 97490075Sobrien exp = decl_constant_value_for_broken_optimization (exp); 97590075Sobrien type = TREE_TYPE (exp); 97690075Sobrien } 97790075Sobrien 97890075Sobrien /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as 97990075Sobrien an lvalue. 98090075Sobrien 98190075Sobrien Do not use STRIP_NOPS here! It will remove conversions from pointer 98290075Sobrien to integer and cause infinite recursion. */ 98390075Sobrien orig_exp = exp; 98490075Sobrien while (TREE_CODE (exp) == NON_LVALUE_EXPR 98590075Sobrien || (TREE_CODE (exp) == NOP_EXPR 98690075Sobrien && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp))) 98790075Sobrien exp = TREE_OPERAND (exp, 0); 98890075Sobrien 98990075Sobrien /* Preserve the original expression code. */ 99090075Sobrien if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp)))) 99190075Sobrien C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp)); 99290075Sobrien 99390075Sobrien /* Normally convert enums to int, 99490075Sobrien but convert wide enums to something wider. */ 99590075Sobrien if (code == ENUMERAL_TYPE) 99690075Sobrien { 99790075Sobrien type = type_for_size (MAX (TYPE_PRECISION (type), 99890075Sobrien TYPE_PRECISION (integer_type_node)), 99990075Sobrien ((flag_traditional 100090075Sobrien || (TYPE_PRECISION (type) 100190075Sobrien >= TYPE_PRECISION (integer_type_node))) 100290075Sobrien && TREE_UNSIGNED (type))); 100390075Sobrien 100490075Sobrien return convert (type, exp); 100590075Sobrien } 100690075Sobrien 100790075Sobrien if (TREE_CODE (exp) == COMPONENT_REF 100890075Sobrien && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)) 100990075Sobrien /* If it's thinner than an int, promote it like a 101090075Sobrien c_promoting_integer_type_p, otherwise leave it alone. */ 101190075Sobrien && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)), 101290075Sobrien TYPE_PRECISION (integer_type_node))) 101390075Sobrien return convert (flag_traditional && TREE_UNSIGNED (type) 101490075Sobrien ? unsigned_type_node : integer_type_node, 101590075Sobrien exp); 101690075Sobrien 101790075Sobrien if (c_promoting_integer_type_p (type)) 101890075Sobrien { 101990075Sobrien /* Traditionally, unsignedness is preserved in default promotions. 102090075Sobrien Also preserve unsignedness if not really getting any wider. */ 102190075Sobrien if (TREE_UNSIGNED (type) 102290075Sobrien && (flag_traditional 102390075Sobrien || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))) 102490075Sobrien return convert (unsigned_type_node, exp); 102590075Sobrien 102690075Sobrien return convert (integer_type_node, exp); 102790075Sobrien } 102890075Sobrien 102990075Sobrien if (flag_traditional && !flag_allow_single_precision 103090075Sobrien && TYPE_MAIN_VARIANT (type) == float_type_node) 103190075Sobrien return convert (double_type_node, exp); 103290075Sobrien 103390075Sobrien if (code == VOID_TYPE) 103490075Sobrien { 103590075Sobrien error ("void value not ignored as it ought to be"); 103690075Sobrien return error_mark_node; 103790075Sobrien } 103890075Sobrien return exp; 103990075Sobrien} 104018334Speter 104190075Sobrien/* Look up COMPONENT in a structure or union DECL. 104218334Speter 104390075Sobrien If the component name is not found, returns NULL_TREE. Otherwise, 104490075Sobrien the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL 104590075Sobrien stepping down the chain to the component, which is in the last 104690075Sobrien TREE_VALUE of the list. Normally the list is of length one, but if 104790075Sobrien the component is embedded within (nested) anonymous structures or 104890075Sobrien unions, the list steps down the chain to the component. */ 104918334Speter 105018334Speterstatic tree 105190075Sobrienlookup_field (decl, component) 105290075Sobrien tree decl, component; 105318334Speter{ 105490075Sobrien tree type = TREE_TYPE (decl); 105518334Speter tree field; 105618334Speter 105718334Speter /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers 105818334Speter to the field elements. Use a binary search on this array to quickly 105918334Speter find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC 106018334Speter will always be set for structures which have many elements. */ 106118334Speter 106218334Speter if (TYPE_LANG_SPECIFIC (type)) 106318334Speter { 106418334Speter int bot, top, half; 106518334Speter tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0]; 106618334Speter 106718334Speter field = TYPE_FIELDS (type); 106818334Speter bot = 0; 106918334Speter top = TYPE_LANG_SPECIFIC (type)->len; 107018334Speter while (top - bot > 1) 107118334Speter { 107218334Speter half = (top - bot + 1) >> 1; 107318334Speter field = field_array[bot+half]; 107418334Speter 107518334Speter if (DECL_NAME (field) == NULL_TREE) 107618334Speter { 107718334Speter /* Step through all anon unions in linear fashion. */ 107818334Speter while (DECL_NAME (field_array[bot]) == NULL_TREE) 107918334Speter { 108018334Speter field = field_array[bot++]; 108150397Sobrien if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE 108250397Sobrien || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) 108390075Sobrien { 108490075Sobrien tree anon = lookup_field (field, component); 108550397Sobrien 108690075Sobrien if (anon) 108790075Sobrien return tree_cons (NULL_TREE, field, anon); 108890075Sobrien } 108918334Speter } 109018334Speter 109118334Speter /* Entire record is only anon unions. */ 109218334Speter if (bot > top) 109318334Speter return NULL_TREE; 109418334Speter 109518334Speter /* Restart the binary search, with new lower bound. */ 109618334Speter continue; 109718334Speter } 109818334Speter 109918334Speter if (DECL_NAME (field) == component) 110018334Speter break; 110118334Speter if (DECL_NAME (field) < component) 110218334Speter bot += half; 110318334Speter else 110418334Speter top = bot + half; 110518334Speter } 110618334Speter 110718334Speter if (DECL_NAME (field_array[bot]) == component) 110818334Speter field = field_array[bot]; 110918334Speter else if (DECL_NAME (field) != component) 111090075Sobrien return NULL_TREE; 111118334Speter } 111218334Speter else 111318334Speter { 111418334Speter for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 111518334Speter { 111690075Sobrien if (DECL_NAME (field) == NULL_TREE 111790075Sobrien && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE 111890075Sobrien || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)) 111918334Speter { 112090075Sobrien tree anon = lookup_field (field, component); 112150397Sobrien 112290075Sobrien if (anon) 112390075Sobrien return tree_cons (NULL_TREE, field, anon); 112418334Speter } 112518334Speter 112618334Speter if (DECL_NAME (field) == component) 112718334Speter break; 112818334Speter } 112990075Sobrien 113090075Sobrien if (field == NULL_TREE) 113190075Sobrien return NULL_TREE; 113218334Speter } 113318334Speter 113490075Sobrien return tree_cons (NULL_TREE, field, NULL_TREE); 113518334Speter} 113618334Speter 113718334Speter/* Make an expression to refer to the COMPONENT field of 113818334Speter structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */ 113918334Speter 114018334Spetertree 114118334Speterbuild_component_ref (datum, component) 114218334Speter tree datum, component; 114318334Speter{ 114490075Sobrien tree type = TREE_TYPE (datum); 114590075Sobrien enum tree_code code = TREE_CODE (type); 114690075Sobrien tree field = NULL; 114790075Sobrien tree ref; 114818334Speter 114990075Sobrien /* If DATUM is a COMPOUND_EXPR, move our reference inside it. 115090075Sobrien If pedantic ensure that the arguments are not lvalues; otherwise, 115190075Sobrien if the component is an array, it would wrongly decay to a pointer in 115290075Sobrien C89 mode. 115390075Sobrien We cannot do this with a COND_EXPR, because in a conditional expression 115490075Sobrien the default promotions are applied to both sides, and this would yield 115590075Sobrien the wrong type of the result; for example, if the components have 115690075Sobrien type "char". */ 115718334Speter switch (TREE_CODE (datum)) 115818334Speter { 115918334Speter case COMPOUND_EXPR: 116018334Speter { 116118334Speter tree value = build_component_ref (TREE_OPERAND (datum, 1), component); 116218334Speter return build (COMPOUND_EXPR, TREE_TYPE (value), 116390075Sobrien TREE_OPERAND (datum, 0), pedantic_non_lvalue (value)); 116418334Speter } 116550397Sobrien default: 116650397Sobrien break; 116718334Speter } 116818334Speter 116918334Speter /* See if there is a field or component with name COMPONENT. */ 117018334Speter 117118334Speter if (code == RECORD_TYPE || code == UNION_TYPE) 117218334Speter { 117390075Sobrien if (!COMPLETE_TYPE_P (type)) 117418334Speter { 117518334Speter incomplete_type_error (NULL_TREE, type); 117618334Speter return error_mark_node; 117718334Speter } 117818334Speter 117990075Sobrien field = lookup_field (datum, component); 118018334Speter 118118334Speter if (!field) 118218334Speter { 118390075Sobrien error ("%s has no member named `%s'", 118490075Sobrien code == RECORD_TYPE ? "structure" : "union", 118518334Speter IDENTIFIER_POINTER (component)); 118618334Speter return error_mark_node; 118718334Speter } 118818334Speter 118990075Sobrien /* Chain the COMPONENT_REFs if necessary down to the FIELD. 119090075Sobrien This might be better solved in future the way the C++ front 119190075Sobrien end does it - by giving the anonymous entities each a 119290075Sobrien separate name and type, and then have build_component_ref 119390075Sobrien recursively call itself. We can't do that here. */ 119490075Sobrien for (; field; field = TREE_CHAIN (field)) 119518334Speter { 119690075Sobrien tree subdatum = TREE_VALUE (field); 119790075Sobrien 119890075Sobrien if (TREE_TYPE (subdatum) == error_mark_node) 119990075Sobrien return error_mark_node; 120090075Sobrien 120190075Sobrien ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum); 120290075Sobrien if (TREE_READONLY (datum) || TREE_READONLY (subdatum)) 120318334Speter TREE_READONLY (ref) = 1; 120490075Sobrien if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (subdatum)) 120518334Speter TREE_THIS_VOLATILE (ref) = 1; 120690075Sobrien 120790075Sobrien if (TREE_DEPRECATED (subdatum)) 120890075Sobrien warn_deprecated_use (subdatum); 120990075Sobrien 121018334Speter datum = ref; 121118334Speter } 121218334Speter 121318334Speter return ref; 121418334Speter } 121518334Speter else if (code != ERROR_MARK) 121618334Speter error ("request for member `%s' in something not a structure or union", 121718334Speter IDENTIFIER_POINTER (component)); 121818334Speter 121918334Speter return error_mark_node; 122018334Speter} 122118334Speter 122218334Speter/* Given an expression PTR for a pointer, return an expression 122318334Speter for the value pointed to. 122418334Speter ERRORSTRING is the name of the operator to appear in error messages. */ 122518334Speter 122618334Spetertree 122718334Speterbuild_indirect_ref (ptr, errorstring) 122818334Speter tree ptr; 122952284Sobrien const char *errorstring; 123018334Speter{ 123190075Sobrien tree pointer = default_conversion (ptr); 123290075Sobrien tree type = TREE_TYPE (pointer); 123318334Speter 123418334Speter if (TREE_CODE (type) == POINTER_TYPE) 123518334Speter { 123618334Speter if (TREE_CODE (pointer) == ADDR_EXPR 123718334Speter && !flag_volatile 123818334Speter && (TREE_TYPE (TREE_OPERAND (pointer, 0)) 123918334Speter == TREE_TYPE (type))) 124018334Speter return TREE_OPERAND (pointer, 0); 124118334Speter else 124218334Speter { 124318334Speter tree t = TREE_TYPE (type); 124490075Sobrien tree ref = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (t), pointer); 124518334Speter 124690075Sobrien if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE) 124718334Speter { 124818334Speter error ("dereferencing pointer to incomplete type"); 124918334Speter return error_mark_node; 125018334Speter } 125190075Sobrien if (VOID_TYPE_P (t) && skip_evaluation == 0) 125218334Speter warning ("dereferencing `void *' pointer"); 125318334Speter 125418334Speter /* We *must* set TREE_READONLY when dereferencing a pointer to const, 125518334Speter so that we get the proper error message if the result is used 125618334Speter to assign to. Also, &* is supposed to be a no-op. 125718334Speter And ANSI C seems to specify that the type of the result 125818334Speter should be the const type. */ 125918334Speter /* A de-reference of a pointer to const is not a const. It is valid 126018334Speter to change it via some other pointer. */ 126118334Speter TREE_READONLY (ref) = TYPE_READONLY (t); 126218334Speter TREE_SIDE_EFFECTS (ref) 126318334Speter = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; 126418334Speter TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); 126518334Speter return ref; 126618334Speter } 126718334Speter } 126818334Speter else if (TREE_CODE (pointer) != ERROR_MARK) 126918334Speter error ("invalid type argument of `%s'", errorstring); 127018334Speter return error_mark_node; 127118334Speter} 127218334Speter 127318334Speter/* This handles expressions of the form "a[i]", which denotes 127418334Speter an array reference. 127518334Speter 127618334Speter This is logically equivalent in C to *(a+i), but we may do it differently. 127718334Speter If A is a variable or a member, we generate a primitive ARRAY_REF. 127818334Speter This avoids forcing the array out of registers, and can work on 127918334Speter arrays that are not lvalues (for example, members of structures returned 128018334Speter by functions). */ 128118334Speter 128218334Spetertree 128318334Speterbuild_array_ref (array, index) 128418334Speter tree array, index; 128518334Speter{ 128618334Speter if (index == 0) 128718334Speter { 128818334Speter error ("subscript missing in array reference"); 128918334Speter return error_mark_node; 129018334Speter } 129118334Speter 129218334Speter if (TREE_TYPE (array) == error_mark_node 129318334Speter || TREE_TYPE (index) == error_mark_node) 129418334Speter return error_mark_node; 129518334Speter 129618334Speter if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE 129718334Speter && TREE_CODE (array) != INDIRECT_REF) 129818334Speter { 129918334Speter tree rval, type; 130018334Speter 130118334Speter /* Subscripting with type char is likely to lose 130218334Speter on a machine where chars are signed. 130318334Speter So warn on any machine, but optionally. 130418334Speter Don't warn for unsigned char since that type is safe. 130518334Speter Don't warn for signed char because anyone who uses that 130618334Speter must have done so deliberately. */ 130718334Speter if (warn_char_subscripts 130818334Speter && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) 130918334Speter warning ("array subscript has type `char'"); 131018334Speter 131118334Speter /* Apply default promotions *after* noticing character types. */ 131218334Speter index = default_conversion (index); 131318334Speter 131418334Speter /* Require integer *after* promotion, for sake of enums. */ 131518334Speter if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE) 131618334Speter { 131718334Speter error ("array subscript is not an integer"); 131818334Speter return error_mark_node; 131918334Speter } 132018334Speter 132118334Speter /* An array that is indexed by a non-constant 132218334Speter cannot be stored in a register; we must be able to do 132318334Speter address arithmetic on its address. 132418334Speter Likewise an array of elements of variable size. */ 132518334Speter if (TREE_CODE (index) != INTEGER_CST 132690075Sobrien || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array))) 132718334Speter && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) 132818334Speter { 132918334Speter if (mark_addressable (array) == 0) 133018334Speter return error_mark_node; 133118334Speter } 133218334Speter /* An array that is indexed by a constant value which is not within 133318334Speter the array bounds cannot be stored in a register either; because we 133418334Speter would get a crash in store_bit_field/extract_bit_field when trying 133518334Speter to access a non-existent part of the register. */ 133618334Speter if (TREE_CODE (index) == INTEGER_CST 133718334Speter && TYPE_VALUES (TREE_TYPE (array)) 133818334Speter && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array)))) 133918334Speter { 134018334Speter if (mark_addressable (array) == 0) 134118334Speter return error_mark_node; 134218334Speter } 134318334Speter 134418334Speter if (pedantic) 134518334Speter { 134618334Speter tree foo = array; 134718334Speter while (TREE_CODE (foo) == COMPONENT_REF) 134818334Speter foo = TREE_OPERAND (foo, 0); 134918334Speter if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) 135090075Sobrien pedwarn ("ISO C forbids subscripting `register' array"); 135190075Sobrien else if (! flag_isoc99 && ! lvalue_p (foo)) 135290075Sobrien pedwarn ("ISO C89 forbids subscripting non-lvalue array"); 135318334Speter } 135418334Speter 135518334Speter type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array))); 135618334Speter rval = build (ARRAY_REF, type, array, index); 135718334Speter /* Array ref is const/volatile if the array elements are 135818334Speter or if the array is. */ 135918334Speter TREE_READONLY (rval) 136018334Speter |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array))) 136118334Speter | TREE_READONLY (array)); 136218334Speter TREE_SIDE_EFFECTS (rval) 136318334Speter |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) 136418334Speter | TREE_SIDE_EFFECTS (array)); 136518334Speter TREE_THIS_VOLATILE (rval) 136618334Speter |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array))) 136718334Speter /* This was added by rms on 16 Nov 91. 136818334Speter It fixes vol struct foo *a; a->elts[1] 136918334Speter in an inline function. 137018334Speter Hope it doesn't break something else. */ 137118334Speter | TREE_THIS_VOLATILE (array)); 137218334Speter return require_complete_type (fold (rval)); 137318334Speter } 137418334Speter 137518334Speter { 137618334Speter tree ar = default_conversion (array); 137718334Speter tree ind = default_conversion (index); 137818334Speter 137950397Sobrien /* Do the same warning check as above, but only on the part that's 138050397Sobrien syntactically the index and only if it is also semantically 138150397Sobrien the index. */ 138250397Sobrien if (warn_char_subscripts 138350397Sobrien && TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE 138450397Sobrien && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node) 138550397Sobrien warning ("subscript has type `char'"); 138650397Sobrien 138718334Speter /* Put the integer in IND to simplify error checking. */ 138818334Speter if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE) 138918334Speter { 139018334Speter tree temp = ar; 139118334Speter ar = ind; 139218334Speter ind = temp; 139318334Speter } 139418334Speter 139518334Speter if (ar == error_mark_node) 139618334Speter return ar; 139718334Speter 139850397Sobrien if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE 139950397Sobrien || TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE) 140018334Speter { 140118334Speter error ("subscripted value is neither array nor pointer"); 140218334Speter return error_mark_node; 140318334Speter } 140418334Speter if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) 140518334Speter { 140618334Speter error ("array subscript is not an integer"); 140718334Speter return error_mark_node; 140818334Speter } 140918334Speter 141018334Speter return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0), 141118334Speter "array indexing"); 141218334Speter } 141318334Speter} 141418334Speter 141590075Sobrien/* Build an external reference to identifier ID. FUN indicates 141690075Sobrien whether this will be used for a function call. */ 141790075Sobrientree 141890075Sobrienbuild_external_ref (id, fun) 141990075Sobrien tree id; 142090075Sobrien int fun; 142190075Sobrien{ 142290075Sobrien tree ref; 142390075Sobrien tree decl = lookup_name (id); 142490075Sobrien tree objc_ivar = lookup_objc_ivar (id); 142590075Sobrien 142690075Sobrien if (decl && TREE_DEPRECATED (decl)) 142790075Sobrien warn_deprecated_use (decl); 142890075Sobrien 142990075Sobrien if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl)) 143090075Sobrien { 143190075Sobrien if (objc_ivar) 143290075Sobrien ref = objc_ivar; 143390075Sobrien else if (fun) 143490075Sobrien { 143590075Sobrien if (!decl || decl == error_mark_node) 143690075Sobrien /* Ordinary implicit function declaration. */ 143790075Sobrien ref = implicitly_declare (id); 143890075Sobrien else 143990075Sobrien { 144090075Sobrien /* Implicit declaration of built-in function. Don't 144190075Sobrien change the built-in declaration, but don't let this 144290075Sobrien go by silently, either. */ 144390075Sobrien implicit_decl_warning (id); 144490075Sobrien 144590075Sobrien /* only issue this warning once */ 144690075Sobrien C_DECL_ANTICIPATED (decl) = 0; 144790075Sobrien ref = decl; 144890075Sobrien } 144990075Sobrien } 145090075Sobrien else 145190075Sobrien { 145290075Sobrien /* Reference to undeclared variable, including reference to 145390075Sobrien builtin outside of function-call context. */ 145490075Sobrien if (current_function_decl == 0) 145590075Sobrien error ("`%s' undeclared here (not in a function)", 145690075Sobrien IDENTIFIER_POINTER (id)); 145790075Sobrien else 145890075Sobrien { 145990075Sobrien if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node 146090075Sobrien || IDENTIFIER_ERROR_LOCUS (id) != current_function_decl) 146190075Sobrien { 146290075Sobrien error ("`%s' undeclared (first use in this function)", 146390075Sobrien IDENTIFIER_POINTER (id)); 146490075Sobrien 146590075Sobrien if (! undeclared_variable_notice) 146690075Sobrien { 146790075Sobrien error ("(Each undeclared identifier is reported only once"); 146890075Sobrien error ("for each function it appears in.)"); 146990075Sobrien undeclared_variable_notice = 1; 147090075Sobrien } 147190075Sobrien } 147290075Sobrien IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node; 147390075Sobrien IDENTIFIER_ERROR_LOCUS (id) = current_function_decl; 147490075Sobrien } 147590075Sobrien return error_mark_node; 147690075Sobrien } 147790075Sobrien } 147890075Sobrien else 147990075Sobrien { 148090075Sobrien /* Properly declared variable or function reference. */ 148190075Sobrien if (!objc_ivar) 148290075Sobrien ref = decl; 148390075Sobrien else if (decl != objc_ivar && IDENTIFIER_LOCAL_VALUE (id)) 148490075Sobrien { 148590075Sobrien warning ("local declaration of `%s' hides instance variable", 148690075Sobrien IDENTIFIER_POINTER (id)); 148790075Sobrien ref = decl; 148890075Sobrien } 148990075Sobrien else 149090075Sobrien ref = objc_ivar; 149190075Sobrien } 149290075Sobrien 149390075Sobrien if (TREE_TYPE (ref) == error_mark_node) 149490075Sobrien return error_mark_node; 149590075Sobrien 149690075Sobrien assemble_external (ref); 149790075Sobrien TREE_USED (ref) = 1; 149890075Sobrien 149990075Sobrien if (TREE_CODE (ref) == CONST_DECL) 150090075Sobrien { 150190075Sobrien ref = DECL_INITIAL (ref); 150290075Sobrien TREE_CONSTANT (ref) = 1; 150390075Sobrien } 150490075Sobrien 150590075Sobrien return ref; 150690075Sobrien} 150790075Sobrien 150818334Speter/* Build a function call to function FUNCTION with parameters PARAMS. 150918334Speter PARAMS is a list--a chain of TREE_LIST nodes--in which the 151018334Speter TREE_VALUE of each node is a parameter-expression. 151118334Speter FUNCTION's data type may be a function type or a pointer-to-function. */ 151218334Speter 151318334Spetertree 151418334Speterbuild_function_call (function, params) 151518334Speter tree function, params; 151618334Speter{ 151790075Sobrien tree fntype, fundecl = 0; 151890075Sobrien tree coerced_params; 151990075Sobrien tree name = NULL_TREE, assembler_name = NULL_TREE, result; 152018334Speter 152118334Speter /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ 152218334Speter STRIP_TYPE_NOPS (function); 152318334Speter 152418334Speter /* Convert anything with function type to a pointer-to-function. */ 152518334Speter if (TREE_CODE (function) == FUNCTION_DECL) 152618334Speter { 152718334Speter name = DECL_NAME (function); 152818334Speter assembler_name = DECL_ASSEMBLER_NAME (function); 152918334Speter 153018334Speter /* Differs from default_conversion by not setting TREE_ADDRESSABLE 153118334Speter (because calling an inline function does not mean the function 153218334Speter needs to be separately compiled). */ 153318334Speter fntype = build_type_variant (TREE_TYPE (function), 153418334Speter TREE_READONLY (function), 153518334Speter TREE_THIS_VOLATILE (function)); 153618334Speter fundecl = function; 153718334Speter function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); 153818334Speter } 153918334Speter else 154018334Speter function = default_conversion (function); 154118334Speter 154218334Speter fntype = TREE_TYPE (function); 154318334Speter 154418334Speter if (TREE_CODE (fntype) == ERROR_MARK) 154518334Speter return error_mark_node; 154618334Speter 154718334Speter if (!(TREE_CODE (fntype) == POINTER_TYPE 154818334Speter && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) 154918334Speter { 155018334Speter error ("called object is not a function"); 155118334Speter return error_mark_node; 155218334Speter } 155318334Speter 155496263Sobrien if (fundecl && TREE_THIS_VOLATILE (fundecl)) 155596263Sobrien current_function_returns_abnormally = 1; 155696263Sobrien 155718334Speter /* fntype now gets the type of function pointed to. */ 155818334Speter fntype = TREE_TYPE (fntype); 155918334Speter 156018334Speter /* Convert the parameters to the types declared in the 156118334Speter function prototype, or apply default promotions. */ 156218334Speter 156318334Speter coerced_params 156418334Speter = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl); 156518334Speter 156618334Speter /* Check for errors in format strings. */ 156718334Speter 156890075Sobrien if (warn_format) 156990075Sobrien check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params); 157018334Speter 157118334Speter /* Recognize certain built-in functions so we can make tree-codes 157218334Speter other than CALL_EXPR. We do this when it enables fold-const.c 157318334Speter to do something useful. */ 157418334Speter 157518334Speter if (TREE_CODE (function) == ADDR_EXPR 157618334Speter && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL 157718334Speter && DECL_BUILT_IN (TREE_OPERAND (function, 0))) 157890075Sobrien { 157990075Sobrien result = expand_tree_builtin (TREE_OPERAND (function, 0), 158090075Sobrien params, coerced_params); 158190075Sobrien if (result) 158290075Sobrien return result; 158390075Sobrien } 158418334Speter 158590075Sobrien result = build (CALL_EXPR, TREE_TYPE (fntype), 158690075Sobrien function, coerced_params, NULL_TREE); 158790075Sobrien TREE_SIDE_EFFECTS (result) = 1; 158890075Sobrien result = fold (result); 158918334Speter 159090075Sobrien if (VOID_TYPE_P (TREE_TYPE (result))) 159190075Sobrien return result; 159290075Sobrien return require_complete_type (result); 159318334Speter} 159418334Speter 159518334Speter/* Convert the argument expressions in the list VALUES 159618334Speter to the types in the list TYPELIST. The result is a list of converted 159718334Speter argument expressions. 159818334Speter 159918334Speter If TYPELIST is exhausted, or when an element has NULL as its type, 160018334Speter perform the default conversions. 160118334Speter 160218334Speter PARMLIST is the chain of parm decls for the function being called. 160318334Speter It may be 0, if that info is not available. 160418334Speter It is used only for generating error messages. 160518334Speter 160618334Speter NAME is an IDENTIFIER_NODE or 0. It is used only for error messages. 160718334Speter 160818334Speter This is also where warnings about wrong number of args are generated. 160918334Speter 161018334Speter Both VALUES and the returned value are chains of TREE_LIST nodes 161118334Speter with the elements of the list in the TREE_VALUE slots of those nodes. */ 161218334Speter 161318334Speterstatic tree 161418334Speterconvert_arguments (typelist, values, name, fundecl) 161518334Speter tree typelist, values, name, fundecl; 161618334Speter{ 161790075Sobrien tree typetail, valtail; 161890075Sobrien tree result = NULL; 161918334Speter int parmnum; 162018334Speter 162118334Speter /* Scan the given expressions and types, producing individual 162218334Speter converted arguments and pushing them on RESULT in reverse order. */ 162318334Speter 162418334Speter for (valtail = values, typetail = typelist, parmnum = 0; 162518334Speter valtail; 162618334Speter valtail = TREE_CHAIN (valtail), parmnum++) 162718334Speter { 162890075Sobrien tree type = typetail ? TREE_VALUE (typetail) : 0; 162990075Sobrien tree val = TREE_VALUE (valtail); 163018334Speter 163118334Speter if (type == void_type_node) 163218334Speter { 163318334Speter if (name) 163418334Speter error ("too many arguments to function `%s'", 163518334Speter IDENTIFIER_POINTER (name)); 163618334Speter else 163718334Speter error ("too many arguments to function"); 163818334Speter break; 163918334Speter } 164018334Speter 164118334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 164218334Speter /* Do not use STRIP_NOPS here! We do not want an enumerator with value 0 164318334Speter to convert automatically to a pointer. */ 164418334Speter if (TREE_CODE (val) == NON_LVALUE_EXPR) 164518334Speter val = TREE_OPERAND (val, 0); 164618334Speter 164790075Sobrien val = default_function_array_conversion (val); 164818334Speter 164918334Speter val = require_complete_type (val); 165018334Speter 165118334Speter if (type != 0) 165218334Speter { 165318334Speter /* Formal parm type is specified by a function prototype. */ 165418334Speter tree parmval; 165518334Speter 165690075Sobrien if (!COMPLETE_TYPE_P (type)) 165718334Speter { 165818334Speter error ("type of formal parameter %d is incomplete", parmnum + 1); 165918334Speter parmval = val; 166018334Speter } 166118334Speter else 166218334Speter { 166318334Speter /* Optionally warn about conversions that 166418334Speter differ from the default conversions. */ 166590075Sobrien if (warn_conversion || warn_traditional) 166618334Speter { 166718334Speter int formal_prec = TYPE_PRECISION (type); 166818334Speter 166918334Speter if (INTEGRAL_TYPE_P (type) 167018334Speter && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) 167118334Speter warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1); 167290075Sobrien if (INTEGRAL_TYPE_P (type) 167390075Sobrien && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE) 167490075Sobrien warn_for_assignment ("%s as integer rather than complex due to prototype", (char *) 0, name, parmnum + 1); 167518334Speter else if (TREE_CODE (type) == COMPLEX_TYPE 167618334Speter && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) 167718334Speter warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1); 167818334Speter else if (TREE_CODE (type) == REAL_TYPE 167918334Speter && INTEGRAL_TYPE_P (TREE_TYPE (val))) 168018334Speter warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1); 168190075Sobrien else if (TREE_CODE (type) == COMPLEX_TYPE 168290075Sobrien && INTEGRAL_TYPE_P (TREE_TYPE (val))) 168390075Sobrien warn_for_assignment ("%s as complex rather than integer due to prototype", (char *) 0, name, parmnum + 1); 168418334Speter else if (TREE_CODE (type) == REAL_TYPE 168518334Speter && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE) 168618334Speter warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1); 168718334Speter /* ??? At some point, messages should be written about 168818334Speter conversions between complex types, but that's too messy 168918334Speter to do now. */ 169018334Speter else if (TREE_CODE (type) == REAL_TYPE 169118334Speter && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE) 169218334Speter { 169318334Speter /* Warn if any argument is passed as `float', 169418334Speter since without a prototype it would be `double'. */ 169518334Speter if (formal_prec == TYPE_PRECISION (float_type_node)) 169618334Speter warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1); 169718334Speter } 169890075Sobrien /* Detect integer changing in width or signedness. 169990075Sobrien These warnings are only activated with 170090075Sobrien -Wconversion, not with -Wtraditional. */ 170190075Sobrien else if (warn_conversion && INTEGRAL_TYPE_P (type) 170218334Speter && INTEGRAL_TYPE_P (TREE_TYPE (val))) 170318334Speter { 170418334Speter tree would_have_been = default_conversion (val); 170518334Speter tree type1 = TREE_TYPE (would_have_been); 170618334Speter 170718334Speter if (TREE_CODE (type) == ENUMERAL_TYPE 170890075Sobrien && (TYPE_MAIN_VARIANT (type) 170990075Sobrien == TYPE_MAIN_VARIANT (TREE_TYPE (val)))) 171018334Speter /* No warning if function asks for enum 171118334Speter and the actual arg is that enum type. */ 171218334Speter ; 171318334Speter else if (formal_prec != TYPE_PRECISION (type1)) 171418334Speter warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1); 171518334Speter else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1)) 171618334Speter ; 171718334Speter /* Don't complain if the formal parameter type 171818334Speter is an enum, because we can't tell now whether 171918334Speter the value was an enum--even the same enum. */ 172018334Speter else if (TREE_CODE (type) == ENUMERAL_TYPE) 172118334Speter ; 172218334Speter else if (TREE_CODE (val) == INTEGER_CST 172318334Speter && int_fits_type_p (val, type)) 172418334Speter /* Change in signedness doesn't matter 172518334Speter if a constant value is unaffected. */ 172618334Speter ; 172718334Speter /* Likewise for a constant in a NOP_EXPR. */ 172818334Speter else if (TREE_CODE (val) == NOP_EXPR 172918334Speter && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST 173018334Speter && int_fits_type_p (TREE_OPERAND (val, 0), type)) 173118334Speter ; 173218334Speter#if 0 /* We never get such tree structure here. */ 173318334Speter else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE 173418334Speter && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type) 173518334Speter && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type)) 173618334Speter /* Change in signedness doesn't matter 173718334Speter if an enum value is unaffected. */ 173818334Speter ; 173918334Speter#endif 174018334Speter /* If the value is extended from a narrower 174118334Speter unsigned type, it doesn't matter whether we 174218334Speter pass it as signed or unsigned; the value 174318334Speter certainly is the same either way. */ 174418334Speter else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type) 174518334Speter && TREE_UNSIGNED (TREE_TYPE (val))) 174618334Speter ; 174718334Speter else if (TREE_UNSIGNED (type)) 174818334Speter warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1); 174918334Speter else 175018334Speter warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1); 175118334Speter } 175218334Speter } 175318334Speter 175418334Speter parmval = convert_for_assignment (type, val, 175550397Sobrien (char *) 0, /* arg passing */ 175618334Speter fundecl, name, parmnum + 1); 175718334Speter 175890075Sobrien if (PROMOTE_PROTOTYPES 175990075Sobrien && INTEGRAL_TYPE_P (type) 176018334Speter && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) 176118334Speter parmval = default_conversion (parmval); 176218334Speter } 176318334Speter result = tree_cons (NULL_TREE, parmval, result); 176418334Speter } 176518334Speter else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE 176618334Speter && (TYPE_PRECISION (TREE_TYPE (val)) 176718334Speter < TYPE_PRECISION (double_type_node))) 176818334Speter /* Convert `float' to `double'. */ 176918334Speter result = tree_cons (NULL_TREE, convert (double_type_node, val), result); 177018334Speter else 177118334Speter /* Convert `short' and `char' to full-size `int'. */ 177218334Speter result = tree_cons (NULL_TREE, default_conversion (val), result); 177318334Speter 177418334Speter if (typetail) 177518334Speter typetail = TREE_CHAIN (typetail); 177618334Speter } 177718334Speter 177818334Speter if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) 177918334Speter { 178018334Speter if (name) 178118334Speter error ("too few arguments to function `%s'", 178218334Speter IDENTIFIER_POINTER (name)); 178318334Speter else 178418334Speter error ("too few arguments to function"); 178518334Speter } 178618334Speter 178718334Speter return nreverse (result); 178818334Speter} 178918334Speter 179018334Speter/* This is the entry point used by the parser 179118334Speter for binary operators in the input. 179218334Speter In addition to constructing the expression, 179318334Speter we check for operands that were written with other binary operators 179418334Speter in a way that is likely to confuse the user. */ 179518334Speter 179618334Spetertree 179718334Speterparser_build_binary_op (code, arg1, arg2) 179818334Speter enum tree_code code; 179918334Speter tree arg1, arg2; 180018334Speter{ 180118334Speter tree result = build_binary_op (code, arg1, arg2, 1); 180218334Speter 180318334Speter char class; 180418334Speter char class1 = TREE_CODE_CLASS (TREE_CODE (arg1)); 180518334Speter char class2 = TREE_CODE_CLASS (TREE_CODE (arg2)); 180618334Speter enum tree_code code1 = ERROR_MARK; 180718334Speter enum tree_code code2 = ERROR_MARK; 180818334Speter 180990075Sobrien if (TREE_CODE (result) == ERROR_MARK) 181090075Sobrien return error_mark_node; 181190075Sobrien 181290075Sobrien if (IS_EXPR_CODE_CLASS (class1)) 181318334Speter code1 = C_EXP_ORIGINAL_CODE (arg1); 181490075Sobrien if (IS_EXPR_CODE_CLASS (class2)) 181518334Speter code2 = C_EXP_ORIGINAL_CODE (arg2); 181618334Speter 181718334Speter /* Check for cases such as x+y<<z which users are likely 181818334Speter to misinterpret. If parens are used, C_EXP_ORIGINAL_CODE 181918334Speter is cleared to prevent these warnings. */ 182018334Speter if (warn_parentheses) 182118334Speter { 182218334Speter if (code == LSHIFT_EXPR || code == RSHIFT_EXPR) 182318334Speter { 182418334Speter if (code1 == PLUS_EXPR || code1 == MINUS_EXPR 182518334Speter || code2 == PLUS_EXPR || code2 == MINUS_EXPR) 182618334Speter warning ("suggest parentheses around + or - inside shift"); 182718334Speter } 182818334Speter 182918334Speter if (code == TRUTH_ORIF_EXPR) 183018334Speter { 183118334Speter if (code1 == TRUTH_ANDIF_EXPR 183218334Speter || code2 == TRUTH_ANDIF_EXPR) 183318334Speter warning ("suggest parentheses around && within ||"); 183418334Speter } 183518334Speter 183618334Speter if (code == BIT_IOR_EXPR) 183718334Speter { 183818334Speter if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR 183918334Speter || code1 == PLUS_EXPR || code1 == MINUS_EXPR 184018334Speter || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR 184118334Speter || code2 == PLUS_EXPR || code2 == MINUS_EXPR) 184218334Speter warning ("suggest parentheses around arithmetic in operand of |"); 184318334Speter /* Check cases like x|y==z */ 184418334Speter if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<') 184518334Speter warning ("suggest parentheses around comparison in operand of |"); 184618334Speter } 184718334Speter 184818334Speter if (code == BIT_XOR_EXPR) 184918334Speter { 185018334Speter if (code1 == BIT_AND_EXPR 185118334Speter || code1 == PLUS_EXPR || code1 == MINUS_EXPR 185218334Speter || code2 == BIT_AND_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_AND_EXPR) 186118334Speter { 186218334Speter if (code1 == PLUS_EXPR || code1 == MINUS_EXPR 186318334Speter || code2 == PLUS_EXPR || code2 == MINUS_EXPR) 186418334Speter warning ("suggest parentheses around + or - in operand of &"); 186518334Speter /* Check cases like x&y==z */ 186618334Speter if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<') 186718334Speter warning ("suggest parentheses around comparison in operand of &"); 186818334Speter } 186918334Speter } 187018334Speter 187118334Speter /* Similarly, check for cases like 1<=i<=10 that are probably errors. */ 187218334Speter if (TREE_CODE_CLASS (code) == '<' && extra_warnings 187318334Speter && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')) 187418334Speter warning ("comparisons like X<=Y<=Z do not have their mathematical meaning"); 187518334Speter 187618334Speter unsigned_conversion_warning (result, arg1); 187718334Speter unsigned_conversion_warning (result, arg2); 187818334Speter overflow_warning (result); 187918334Speter 188018334Speter class = TREE_CODE_CLASS (TREE_CODE (result)); 188118334Speter 188218334Speter /* Record the code that was specified in the source, 188318334Speter for the sake of warnings about confusing nesting. */ 188490075Sobrien if (IS_EXPR_CODE_CLASS (class)) 188518334Speter C_SET_EXP_ORIGINAL_CODE (result, code); 188618334Speter else 188718334Speter { 188818334Speter int flag = TREE_CONSTANT (result); 188918334Speter /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR 189018334Speter so that convert_for_assignment wouldn't strip it. 189118334Speter That way, we got warnings for things like p = (1 - 1). 189218334Speter But it turns out we should not get those warnings. */ 189318334Speter result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result); 189418334Speter C_SET_EXP_ORIGINAL_CODE (result, code); 189518334Speter TREE_CONSTANT (result) = flag; 189618334Speter } 189718334Speter 189818334Speter return result; 189918334Speter} 190018334Speter 190118334Speter/* Build a binary-operation expression without default conversions. 190218334Speter CODE is the kind of expression to build. 190318334Speter This function differs from `build' in several ways: 190418334Speter the data type of the result is computed and recorded in it, 190518334Speter warnings are generated if arg data types are invalid, 190618334Speter special handling for addition and subtraction of pointers is known, 190718334Speter and some optimization is done (operations on narrow ints 190818334Speter are done in the narrower type when that gives the same result). 190918334Speter Constant folding is also done before the result is returned. 191018334Speter 191118334Speter Note that the operands will never have enumeral types, or function 191218334Speter or array types, because either they will have the default conversions 191318334Speter performed or they have both just been converted to some other type in which 191418334Speter the arithmetic is to be done. */ 191518334Speter 191618334Spetertree 191718334Speterbuild_binary_op (code, orig_op0, orig_op1, convert_p) 191818334Speter enum tree_code code; 191918334Speter tree orig_op0, orig_op1; 192018334Speter int convert_p; 192118334Speter{ 192218334Speter tree type0, type1; 192390075Sobrien enum tree_code code0, code1; 192418334Speter tree op0, op1; 192518334Speter 192618334Speter /* Expression code to give to the expression when it is built. 192718334Speter Normally this is CODE, which is what the caller asked for, 192818334Speter but in some special cases we change it. */ 192990075Sobrien enum tree_code resultcode = code; 193018334Speter 193118334Speter /* Data type in which the computation is to be performed. 193218334Speter In the simplest cases this is the common type of the arguments. */ 193390075Sobrien tree result_type = NULL; 193418334Speter 193518334Speter /* Nonzero means operands have already been type-converted 193618334Speter in whatever way is necessary. 193718334Speter Zero means they need to be converted to RESULT_TYPE. */ 193818334Speter int converted = 0; 193918334Speter 194018334Speter /* Nonzero means create the expression with this type, rather than 194118334Speter RESULT_TYPE. */ 194218334Speter tree build_type = 0; 194318334Speter 194418334Speter /* Nonzero means after finally constructing the expression 194518334Speter convert it to this type. */ 194618334Speter tree final_type = 0; 194718334Speter 194818334Speter /* Nonzero if this is an operation like MIN or MAX which can 194918334Speter safely be computed in short if both args are promoted shorts. 195018334Speter Also implies COMMON. 195118334Speter -1 indicates a bitwise operation; this makes a difference 195218334Speter in the exact conditions for when it is safe to do the operation 195318334Speter in a narrower mode. */ 195418334Speter int shorten = 0; 195518334Speter 195618334Speter /* Nonzero if this is a comparison operation; 195718334Speter if both args are promoted shorts, compare the original shorts. 195818334Speter Also implies COMMON. */ 195918334Speter int short_compare = 0; 196018334Speter 196118334Speter /* Nonzero if this is a right-shift operation, which can be computed on the 196218334Speter original short and then promoted if the operand is a promoted short. */ 196318334Speter int short_shift = 0; 196418334Speter 196518334Speter /* Nonzero means set RESULT_TYPE to the common type of the args. */ 196618334Speter int common = 0; 196718334Speter 196818334Speter if (convert_p) 196918334Speter { 197018334Speter op0 = default_conversion (orig_op0); 197118334Speter op1 = default_conversion (orig_op1); 197218334Speter } 197318334Speter else 197418334Speter { 197518334Speter op0 = orig_op0; 197618334Speter op1 = orig_op1; 197718334Speter } 197818334Speter 197918334Speter type0 = TREE_TYPE (op0); 198018334Speter type1 = TREE_TYPE (op1); 198118334Speter 198218334Speter /* The expression codes of the data types of the arguments tell us 198318334Speter whether the arguments are integers, floating, pointers, etc. */ 198418334Speter code0 = TREE_CODE (type0); 198518334Speter code1 = TREE_CODE (type1); 198618334Speter 198718334Speter /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ 198818334Speter STRIP_TYPE_NOPS (op0); 198918334Speter STRIP_TYPE_NOPS (op1); 199018334Speter 199118334Speter /* If an error was already reported for one of the arguments, 199218334Speter avoid reporting another error. */ 199318334Speter 199418334Speter if (code0 == ERROR_MARK || code1 == ERROR_MARK) 199518334Speter return error_mark_node; 199618334Speter 199718334Speter switch (code) 199818334Speter { 199918334Speter case PLUS_EXPR: 200018334Speter /* Handle the pointer + int case. */ 200118334Speter if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) 200218334Speter return pointer_int_sum (PLUS_EXPR, op0, op1); 200318334Speter else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) 200418334Speter return pointer_int_sum (PLUS_EXPR, op1, op0); 200518334Speter else 200618334Speter common = 1; 200718334Speter break; 200818334Speter 200918334Speter case MINUS_EXPR: 201018334Speter /* Subtraction of two similar pointers. 201118334Speter We must subtract them as integers, then divide by object size. */ 201218334Speter if (code0 == POINTER_TYPE && code1 == POINTER_TYPE 201318334Speter && comp_target_types (type0, type1)) 201418334Speter return pointer_diff (op0, op1); 201518334Speter /* Handle pointer minus int. Just like pointer plus int. */ 201618334Speter else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) 201718334Speter return pointer_int_sum (MINUS_EXPR, op0, op1); 201818334Speter else 201918334Speter common = 1; 202018334Speter break; 202118334Speter 202218334Speter case MULT_EXPR: 202318334Speter common = 1; 202418334Speter break; 202518334Speter 202618334Speter case TRUNC_DIV_EXPR: 202718334Speter case CEIL_DIV_EXPR: 202818334Speter case FLOOR_DIV_EXPR: 202918334Speter case ROUND_DIV_EXPR: 203018334Speter case EXACT_DIV_EXPR: 203190075Sobrien /* Floating point division by zero is a legitimate way to obtain 203290075Sobrien infinities and NaNs. */ 203390075Sobrien if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) 203490075Sobrien warning ("division by zero"); 203590075Sobrien 203618334Speter if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE 203718334Speter || code0 == COMPLEX_TYPE) 203818334Speter && (code1 == INTEGER_TYPE || code1 == REAL_TYPE 203918334Speter || code1 == COMPLEX_TYPE)) 204018334Speter { 204118334Speter if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)) 204218334Speter resultcode = RDIV_EXPR; 204318334Speter else 204490075Sobrien /* Although it would be tempting to shorten always here, that 204590075Sobrien loses on some targets, since the modulo instruction is 204690075Sobrien undefined if the quotient can't be represented in the 204790075Sobrien computation mode. We shorten only if unsigned or if 204890075Sobrien dividing by something we know != -1. */ 204990075Sobrien shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0)) 205090075Sobrien || (TREE_CODE (op1) == INTEGER_CST 205190075Sobrien && ! integer_all_onesp (op1))); 205218334Speter common = 1; 205318334Speter } 205418334Speter break; 205518334Speter 205618334Speter case BIT_AND_EXPR: 205718334Speter case BIT_ANDTC_EXPR: 205818334Speter case BIT_IOR_EXPR: 205918334Speter case BIT_XOR_EXPR: 206018334Speter if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 206118334Speter shorten = -1; 206218334Speter break; 206318334Speter 206418334Speter case TRUNC_MOD_EXPR: 206518334Speter case FLOOR_MOD_EXPR: 206690075Sobrien if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1)) 206790075Sobrien warning ("division by zero"); 206890075Sobrien 206918334Speter if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 207018334Speter { 207118334Speter /* Although it would be tempting to shorten always here, that loses 207218334Speter on some targets, since the modulo instruction is undefined if the 207318334Speter quotient can't be represented in the computation mode. We shorten 207418334Speter only if unsigned or if dividing by something we know != -1. */ 207518334Speter shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0)) 207618334Speter || (TREE_CODE (op1) == INTEGER_CST 207790075Sobrien && ! integer_all_onesp (op1))); 207818334Speter common = 1; 207918334Speter } 208018334Speter break; 208118334Speter 208218334Speter case TRUTH_ANDIF_EXPR: 208318334Speter case TRUTH_ORIF_EXPR: 208418334Speter case TRUTH_AND_EXPR: 208518334Speter case TRUTH_OR_EXPR: 208618334Speter case TRUTH_XOR_EXPR: 208718334Speter if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE 208818334Speter || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) 208918334Speter && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE 209018334Speter || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) 209118334Speter { 209218334Speter /* Result of these operations is always an int, 209318334Speter but that does not mean the operands should be 209418334Speter converted to ints! */ 209518334Speter result_type = integer_type_node; 209618334Speter op0 = truthvalue_conversion (op0); 209718334Speter op1 = truthvalue_conversion (op1); 209818334Speter converted = 1; 209918334Speter } 210018334Speter break; 210118334Speter 210218334Speter /* Shift operations: result has same type as first operand; 210318334Speter always convert second operand to int. 210418334Speter Also set SHORT_SHIFT if shifting rightward. */ 210518334Speter 210618334Speter case RSHIFT_EXPR: 210718334Speter if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 210818334Speter { 210950397Sobrien if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0) 211018334Speter { 211118334Speter if (tree_int_cst_sgn (op1) < 0) 211218334Speter warning ("right shift count is negative"); 211318334Speter else 211418334Speter { 211590075Sobrien if (! integer_zerop (op1)) 211618334Speter short_shift = 1; 211790075Sobrien 211890075Sobrien if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) 211918334Speter warning ("right shift count >= width of type"); 212018334Speter } 212118334Speter } 212290075Sobrien 212318334Speter /* Use the type of the value to be shifted. 212418334Speter This is what most traditional C compilers do. */ 212518334Speter result_type = type0; 212618334Speter /* Unless traditional, convert the shift-count to an integer, 212718334Speter regardless of size of value being shifted. */ 212818334Speter if (! flag_traditional) 212918334Speter { 213018334Speter if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) 213118334Speter op1 = convert (integer_type_node, op1); 213218334Speter /* Avoid converting op1 to result_type later. */ 213318334Speter converted = 1; 213418334Speter } 213518334Speter } 213618334Speter break; 213718334Speter 213818334Speter case LSHIFT_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 ("left shift count is negative"); 214590075Sobrien 214690075Sobrien else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) 214718334Speter warning ("left shift count >= width of type"); 214818334Speter } 214990075Sobrien 215018334Speter /* Use the type of the value to be shifted. 215118334Speter This is what most traditional C compilers do. */ 215218334Speter result_type = type0; 215318334Speter /* Unless traditional, convert the shift-count to an integer, 215418334Speter regardless of size of value being shifted. */ 215518334Speter if (! flag_traditional) 215618334Speter { 215718334Speter if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) 215818334Speter op1 = convert (integer_type_node, op1); 215918334Speter /* Avoid converting op1 to result_type later. */ 216018334Speter converted = 1; 216118334Speter } 216218334Speter } 216318334Speter break; 216418334Speter 216518334Speter case RROTATE_EXPR: 216618334Speter case LROTATE_EXPR: 216718334Speter if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) 216818334Speter { 216950397Sobrien if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0) 217018334Speter { 217118334Speter if (tree_int_cst_sgn (op1) < 0) 217218334Speter warning ("shift count is negative"); 217390075Sobrien else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) 217418334Speter warning ("shift count >= width of type"); 217518334Speter } 217690075Sobrien 217718334Speter /* Use the type of the value to be shifted. 217818334Speter This is what most traditional C compilers do. */ 217918334Speter result_type = type0; 218018334Speter /* Unless traditional, convert the shift-count to an integer, 218118334Speter regardless of size of value being shifted. */ 218218334Speter if (! flag_traditional) 218318334Speter { 218418334Speter if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) 218518334Speter op1 = convert (integer_type_node, op1); 218618334Speter /* Avoid converting op1 to result_type later. */ 218718334Speter converted = 1; 218818334Speter } 218918334Speter } 219018334Speter break; 219118334Speter 219218334Speter case EQ_EXPR: 219318334Speter case NE_EXPR: 219490075Sobrien if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE)) 219590075Sobrien warning ("comparing floating point with == or != is unsafe"); 219618334Speter /* Result of comparison is always int, 219718334Speter but don't convert the args to int! */ 219818334Speter build_type = integer_type_node; 219918334Speter if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE 220018334Speter || code0 == COMPLEX_TYPE) 220118334Speter && (code1 == INTEGER_TYPE || code1 == REAL_TYPE 220218334Speter || code1 == COMPLEX_TYPE)) 220318334Speter short_compare = 1; 220418334Speter else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) 220518334Speter { 220690075Sobrien tree tt0 = TREE_TYPE (type0); 220790075Sobrien tree tt1 = TREE_TYPE (type1); 220818334Speter /* Anything compares with void *. void * compares with anything. 220918334Speter Otherwise, the targets must be compatible 221018334Speter and both must be object or both incomplete. */ 221118334Speter if (comp_target_types (type0, type1)) 221218334Speter result_type = common_type (type0, type1); 221390075Sobrien else if (VOID_TYPE_P (tt0)) 221418334Speter { 221518334Speter /* op0 != orig_op0 detects the case of something 221618334Speter whose value is 0 but which isn't a valid null ptr const. */ 221718334Speter if (pedantic && (!integer_zerop (op0) || op0 != orig_op0) 221818334Speter && TREE_CODE (tt1) == FUNCTION_TYPE) 221990075Sobrien pedwarn ("ISO C forbids comparison of `void *' with function pointer"); 222018334Speter } 222190075Sobrien else if (VOID_TYPE_P (tt1)) 222218334Speter { 222318334Speter if (pedantic && (!integer_zerop (op1) || op1 != orig_op1) 222418334Speter && TREE_CODE (tt0) == FUNCTION_TYPE) 222590075Sobrien pedwarn ("ISO C forbids comparison of `void *' with function pointer"); 222618334Speter } 222718334Speter else 222818334Speter pedwarn ("comparison of distinct pointer types lacks a cast"); 222918334Speter 223018334Speter if (result_type == NULL_TREE) 223118334Speter result_type = ptr_type_node; 223218334Speter } 223318334Speter else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST 223418334Speter && integer_zerop (op1)) 223518334Speter result_type = type0; 223618334Speter else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST 223718334Speter && integer_zerop (op0)) 223818334Speter result_type = type1; 223918334Speter else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) 224018334Speter { 224118334Speter result_type = type0; 224218334Speter if (! flag_traditional) 224318334Speter pedwarn ("comparison between pointer and integer"); 224418334Speter } 224518334Speter else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) 224618334Speter { 224718334Speter result_type = type1; 224818334Speter if (! flag_traditional) 224918334Speter pedwarn ("comparison between pointer and integer"); 225018334Speter } 225118334Speter break; 225218334Speter 225318334Speter case MAX_EXPR: 225418334Speter case MIN_EXPR: 225518334Speter if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) 225618334Speter && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) 225718334Speter shorten = 1; 225818334Speter else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) 225918334Speter { 226018334Speter if (comp_target_types (type0, type1)) 226118334Speter { 226218334Speter result_type = common_type (type0, type1); 226318334Speter if (pedantic 226418334Speter && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) 226590075Sobrien pedwarn ("ISO C forbids ordered comparisons of pointers to functions"); 226618334Speter } 226718334Speter else 226818334Speter { 226918334Speter result_type = ptr_type_node; 227018334Speter pedwarn ("comparison of distinct pointer types lacks a cast"); 227118334Speter } 227218334Speter } 227318334Speter break; 227418334Speter 227518334Speter case LE_EXPR: 227618334Speter case GE_EXPR: 227718334Speter case LT_EXPR: 227818334Speter case GT_EXPR: 227918334Speter build_type = integer_type_node; 228018334Speter if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) 228118334Speter && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) 228218334Speter short_compare = 1; 228318334Speter else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) 228418334Speter { 228518334Speter if (comp_target_types (type0, type1)) 228618334Speter { 228718334Speter result_type = common_type (type0, type1); 228890075Sobrien if (!COMPLETE_TYPE_P (TREE_TYPE (type0)) 228990075Sobrien != !COMPLETE_TYPE_P (TREE_TYPE (type1))) 229018334Speter pedwarn ("comparison of complete and incomplete pointers"); 229118334Speter else if (pedantic 229218334Speter && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) 229390075Sobrien pedwarn ("ISO C forbids ordered comparisons of pointers to functions"); 229418334Speter } 229518334Speter else 229618334Speter { 229718334Speter result_type = ptr_type_node; 229818334Speter pedwarn ("comparison of distinct pointer types lacks a cast"); 229918334Speter } 230018334Speter } 230118334Speter else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST 230218334Speter && integer_zerop (op1)) 230318334Speter { 230418334Speter result_type = type0; 230518334Speter if (pedantic || extra_warnings) 230618334Speter pedwarn ("ordered comparison of pointer with integer zero"); 230718334Speter } 230818334Speter else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST 230918334Speter && integer_zerop (op0)) 231018334Speter { 231118334Speter result_type = type1; 231218334Speter if (pedantic) 231318334Speter pedwarn ("ordered comparison of pointer with integer zero"); 231418334Speter } 231518334Speter else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) 231618334Speter { 231718334Speter result_type = type0; 231818334Speter if (! flag_traditional) 231918334Speter pedwarn ("comparison between pointer and integer"); 232018334Speter } 232118334Speter else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) 232218334Speter { 232318334Speter result_type = type1; 232418334Speter if (! flag_traditional) 232518334Speter pedwarn ("comparison between pointer and integer"); 232618334Speter } 232718334Speter break; 232890075Sobrien 232990075Sobrien case UNORDERED_EXPR: 233090075Sobrien case ORDERED_EXPR: 233190075Sobrien case UNLT_EXPR: 233290075Sobrien case UNLE_EXPR: 233390075Sobrien case UNGT_EXPR: 233490075Sobrien case UNGE_EXPR: 233590075Sobrien case UNEQ_EXPR: 233690075Sobrien build_type = integer_type_node; 233790075Sobrien if (code0 != REAL_TYPE || code1 != REAL_TYPE) 233890075Sobrien { 233990075Sobrien error ("unordered comparison on non-floating point argument"); 234090075Sobrien return error_mark_node; 234190075Sobrien } 234290075Sobrien common = 1; 234390075Sobrien break; 234490075Sobrien 234550397Sobrien default: 234650397Sobrien break; 234718334Speter } 234818334Speter 234918334Speter if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) 235018334Speter && 235118334Speter (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) 235218334Speter { 235318334Speter int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); 235418334Speter 235518334Speter if (shorten || common || short_compare) 235618334Speter result_type = common_type (type0, type1); 235718334Speter 235818334Speter /* For certain operations (which identify themselves by shorten != 0) 235918334Speter if both args were extended from the same smaller type, 236018334Speter do the arithmetic in that type and then extend. 236118334Speter 236218334Speter shorten !=0 and !=1 indicates a bitwise operation. 236318334Speter For them, this optimization is safe only if 236418334Speter both args are zero-extended or both are sign-extended. 236518334Speter Otherwise, we might change the result. 236618334Speter Eg, (short)-1 | (unsigned short)-1 is (int)-1 236718334Speter but calculated in (unsigned short) it would be (unsigned short)-1. */ 236818334Speter 236918334Speter if (shorten && none_complex) 237018334Speter { 237118334Speter int unsigned0, unsigned1; 237218334Speter tree arg0 = get_narrower (op0, &unsigned0); 237318334Speter tree arg1 = get_narrower (op1, &unsigned1); 237418334Speter /* UNS is 1 if the operation to be done is an unsigned one. */ 237518334Speter int uns = TREE_UNSIGNED (result_type); 237618334Speter tree type; 237718334Speter 237818334Speter final_type = result_type; 237918334Speter 238018334Speter /* Handle the case that OP0 (or OP1) does not *contain* a conversion 238118334Speter but it *requires* conversion to FINAL_TYPE. */ 238218334Speter 238318334Speter if ((TYPE_PRECISION (TREE_TYPE (op0)) 238418334Speter == TYPE_PRECISION (TREE_TYPE (arg0))) 238518334Speter && TREE_TYPE (op0) != final_type) 238618334Speter unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0)); 238718334Speter if ((TYPE_PRECISION (TREE_TYPE (op1)) 238818334Speter == TYPE_PRECISION (TREE_TYPE (arg1))) 238918334Speter && TREE_TYPE (op1) != final_type) 239018334Speter unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1)); 239118334Speter 239218334Speter /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ 239318334Speter 239418334Speter /* For bitwise operations, signedness of nominal type 239518334Speter does not matter. Consider only how operands were extended. */ 239618334Speter if (shorten == -1) 239718334Speter uns = unsigned0; 239818334Speter 239918334Speter /* Note that in all three cases below we refrain from optimizing 240018334Speter an unsigned operation on sign-extended args. 240118334Speter That would not be valid. */ 240218334Speter 240318334Speter /* Both args variable: if both extended in same way 240418334Speter from same width, do it in that width. 240518334Speter Do it unsigned if args were zero-extended. */ 240618334Speter if ((TYPE_PRECISION (TREE_TYPE (arg0)) 240718334Speter < TYPE_PRECISION (result_type)) 240818334Speter && (TYPE_PRECISION (TREE_TYPE (arg1)) 240918334Speter == TYPE_PRECISION (TREE_TYPE (arg0))) 241018334Speter && unsigned0 == unsigned1 241118334Speter && (unsigned0 || !uns)) 241218334Speter result_type 241318334Speter = signed_or_unsigned_type (unsigned0, 241418334Speter common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); 241518334Speter else if (TREE_CODE (arg0) == INTEGER_CST 241618334Speter && (unsigned1 || !uns) 241718334Speter && (TYPE_PRECISION (TREE_TYPE (arg1)) 241818334Speter < TYPE_PRECISION (result_type)) 241918334Speter && (type = signed_or_unsigned_type (unsigned1, 242018334Speter TREE_TYPE (arg1)), 242118334Speter int_fits_type_p (arg0, type))) 242218334Speter result_type = type; 242318334Speter else if (TREE_CODE (arg1) == INTEGER_CST 242418334Speter && (unsigned0 || !uns) 242518334Speter && (TYPE_PRECISION (TREE_TYPE (arg0)) 242618334Speter < TYPE_PRECISION (result_type)) 242718334Speter && (type = signed_or_unsigned_type (unsigned0, 242818334Speter TREE_TYPE (arg0)), 242918334Speter int_fits_type_p (arg1, type))) 243018334Speter result_type = type; 243118334Speter } 243218334Speter 243318334Speter /* Shifts can be shortened if shifting right. */ 243418334Speter 243518334Speter if (short_shift) 243618334Speter { 243718334Speter int unsigned_arg; 243818334Speter tree arg0 = get_narrower (op0, &unsigned_arg); 243918334Speter 244018334Speter final_type = result_type; 244118334Speter 244218334Speter if (arg0 == op0 && final_type == TREE_TYPE (op0)) 244318334Speter unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0)); 244418334Speter 244518334Speter if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) 244618334Speter /* We can shorten only if the shift count is less than the 244718334Speter number of bits in the smaller type size. */ 244890075Sobrien && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0 244990075Sobrien /* We cannot drop an unsigned shift after sign-extension. */ 245090075Sobrien && (!TREE_UNSIGNED (final_type) || unsigned_arg)) 245118334Speter { 245218334Speter /* Do an unsigned shift if the operand was zero-extended. */ 245318334Speter result_type 245490075Sobrien = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0)); 245518334Speter /* Convert value-to-be-shifted to that type. */ 245618334Speter if (TREE_TYPE (op0) != result_type) 245718334Speter op0 = convert (result_type, op0); 245818334Speter converted = 1; 245918334Speter } 246018334Speter } 246118334Speter 246218334Speter /* Comparison operations are shortened too but differently. 246318334Speter They identify themselves by setting short_compare = 1. */ 246418334Speter 246518334Speter if (short_compare) 246618334Speter { 246718334Speter /* Don't write &op0, etc., because that would prevent op0 246818334Speter from being kept in a register. 246918334Speter Instead, make copies of the our local variables and 247018334Speter pass the copies by reference, then copy them back afterward. */ 247118334Speter tree xop0 = op0, xop1 = op1, xresult_type = result_type; 247218334Speter enum tree_code xresultcode = resultcode; 247318334Speter tree val 247418334Speter = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); 247590075Sobrien 247618334Speter if (val != 0) 247718334Speter return val; 247890075Sobrien 247918334Speter op0 = xop0, op1 = xop1; 248018334Speter converted = 1; 248118334Speter resultcode = xresultcode; 248218334Speter 248350397Sobrien if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0) 248450397Sobrien && skip_evaluation == 0) 248518334Speter { 248618334Speter int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0)); 248718334Speter int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1)); 248818334Speter int unsignedp0, unsignedp1; 248918334Speter tree primop0 = get_narrower (op0, &unsignedp0); 249018334Speter tree primop1 = get_narrower (op1, &unsignedp1); 249118334Speter 249218334Speter xop0 = orig_op0; 249318334Speter xop1 = orig_op1; 249418334Speter STRIP_TYPE_NOPS (xop0); 249518334Speter STRIP_TYPE_NOPS (xop1); 249618334Speter 249718334Speter /* Give warnings for comparisons between signed and unsigned 249890075Sobrien quantities that may fail. 249918334Speter 250090075Sobrien Do the checking based on the original operand trees, so that 250190075Sobrien casts will be considered, but default promotions won't be. 250290075Sobrien 250390075Sobrien Do not warn if the comparison is being done in a signed type, 250418334Speter since the signed type will only be chosen if it can represent 250518334Speter all the values of the unsigned type. */ 250618334Speter if (! TREE_UNSIGNED (result_type)) 250718334Speter /* OK */; 250890075Sobrien /* Do not warn if both operands are the same signedness. */ 250918334Speter else if (op0_signed == op1_signed) 251018334Speter /* OK */; 251118334Speter else 251290075Sobrien { 251390075Sobrien tree sop, uop; 251418334Speter 251590075Sobrien if (op0_signed) 251690075Sobrien sop = xop0, uop = xop1; 251790075Sobrien else 251890075Sobrien sop = xop1, uop = xop0; 251990075Sobrien 252090075Sobrien /* Do not warn if the signed quantity is an 252190075Sobrien unsuffixed integer literal (or some static 252290075Sobrien constant expression involving such literals or a 252390075Sobrien conditional expression involving such literals) 252490075Sobrien and it is non-negative. */ 252590075Sobrien if (tree_expr_nonnegative_p (sop)) 252690075Sobrien /* OK */; 252790075Sobrien /* Do not warn if the comparison is an equality operation, 252890075Sobrien the unsigned quantity is an integral constant, and it 252990075Sobrien would fit in the result if the result were signed. */ 253090075Sobrien else if (TREE_CODE (uop) == INTEGER_CST 253190075Sobrien && (resultcode == EQ_EXPR || resultcode == NE_EXPR) 253290075Sobrien && int_fits_type_p (uop, signed_type (result_type))) 253390075Sobrien /* OK */; 253490075Sobrien /* Do not warn if the unsigned quantity is an enumeration 253590075Sobrien constant and its maximum value would fit in the result 253690075Sobrien if the result were signed. */ 253790075Sobrien else if (TREE_CODE (uop) == INTEGER_CST 253890075Sobrien && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE 253990075Sobrien && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE(uop)), 254090075Sobrien signed_type (result_type))) 254190075Sobrien /* OK */; 254290075Sobrien else 254390075Sobrien warning ("comparison between signed and unsigned"); 254490075Sobrien } 254590075Sobrien 254618334Speter /* Warn if two unsigned values are being compared in a size 254718334Speter larger than their original size, and one (and only one) is the 254818334Speter result of a `~' operator. This comparison will always fail. 254918334Speter 255018334Speter Also warn if one operand is a constant, and the constant 255118334Speter does not have all bits set that are set in the ~ operand 255218334Speter when it is extended. */ 255318334Speter 255418334Speter if ((TREE_CODE (primop0) == BIT_NOT_EXPR) 255518334Speter != (TREE_CODE (primop1) == BIT_NOT_EXPR)) 255618334Speter { 255718334Speter if (TREE_CODE (primop0) == BIT_NOT_EXPR) 255818334Speter primop0 = get_narrower (TREE_OPERAND (primop0, 0), 255918334Speter &unsignedp0); 256018334Speter else 256118334Speter primop1 = get_narrower (TREE_OPERAND (primop1, 0), 256218334Speter &unsignedp1); 256318334Speter 256490075Sobrien if (host_integerp (primop0, 0) || host_integerp (primop1, 0)) 256518334Speter { 256618334Speter tree primop; 256790075Sobrien HOST_WIDE_INT constant, mask; 256818334Speter int unsignedp, bits; 256918334Speter 257090075Sobrien if (host_integerp (primop0, 0)) 257118334Speter { 257218334Speter primop = primop1; 257318334Speter unsignedp = unsignedp1; 257490075Sobrien constant = tree_low_cst (primop0, 0); 257518334Speter } 257618334Speter else 257718334Speter { 257818334Speter primop = primop0; 257918334Speter unsignedp = unsignedp0; 258090075Sobrien constant = tree_low_cst (primop1, 0); 258118334Speter } 258218334Speter 258318334Speter bits = TYPE_PRECISION (TREE_TYPE (primop)); 258418334Speter if (bits < TYPE_PRECISION (result_type) 258590075Sobrien && bits < HOST_BITS_PER_WIDE_INT && unsignedp) 258618334Speter { 258790075Sobrien mask = (~ (HOST_WIDE_INT) 0) << bits; 258818334Speter if ((mask & constant) != mask) 258918334Speter warning ("comparison of promoted ~unsigned with constant"); 259018334Speter } 259118334Speter } 259218334Speter else if (unsignedp0 && unsignedp1 259318334Speter && (TYPE_PRECISION (TREE_TYPE (primop0)) 259418334Speter < TYPE_PRECISION (result_type)) 259518334Speter && (TYPE_PRECISION (TREE_TYPE (primop1)) 259618334Speter < TYPE_PRECISION (result_type))) 259718334Speter warning ("comparison of promoted ~unsigned with unsigned"); 259818334Speter } 259918334Speter } 260018334Speter } 260118334Speter } 260218334Speter 260318334Speter /* At this point, RESULT_TYPE must be nonzero to avoid an error message. 260418334Speter If CONVERTED is zero, both args will be converted to type RESULT_TYPE. 260518334Speter Then the expression will be built. 260618334Speter It will be given type FINAL_TYPE if that is nonzero; 260718334Speter otherwise, it will be given type RESULT_TYPE. */ 260818334Speter 260918334Speter if (!result_type) 261018334Speter { 261118334Speter binary_op_error (code); 261218334Speter return error_mark_node; 261318334Speter } 261418334Speter 261518334Speter if (! converted) 261618334Speter { 261718334Speter if (TREE_TYPE (op0) != result_type) 261818334Speter op0 = convert (result_type, op0); 261918334Speter if (TREE_TYPE (op1) != result_type) 262018334Speter op1 = convert (result_type, op1); 262118334Speter } 262218334Speter 262318334Speter if (build_type == NULL_TREE) 262418334Speter build_type = result_type; 262518334Speter 262618334Speter { 262790075Sobrien tree result = build (resultcode, build_type, op0, op1); 262890075Sobrien tree folded; 262918334Speter 263018334Speter folded = fold (result); 263118334Speter if (folded == result) 263218334Speter TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); 263318334Speter if (final_type != 0) 263418334Speter return convert (final_type, folded); 263518334Speter return folded; 263618334Speter } 263718334Speter} 263818334Speter 263918334Speter/* Return a tree for the difference of pointers OP0 and OP1. 264018334Speter The resulting tree has type int. */ 264118334Speter 264218334Speterstatic tree 264318334Speterpointer_diff (op0, op1) 264490075Sobrien tree op0, op1; 264518334Speter{ 264690075Sobrien tree result, folded; 264718334Speter tree restype = ptrdiff_type_node; 264818334Speter 264918334Speter tree target_type = TREE_TYPE (TREE_TYPE (op0)); 265090075Sobrien tree con0, con1, lit0, lit1; 265190075Sobrien tree orig_op1 = op1; 265218334Speter 265318334Speter if (pedantic || warn_pointer_arith) 265418334Speter { 265518334Speter if (TREE_CODE (target_type) == VOID_TYPE) 265618334Speter pedwarn ("pointer of type `void *' used in subtraction"); 265718334Speter if (TREE_CODE (target_type) == FUNCTION_TYPE) 265818334Speter pedwarn ("pointer to a function used in subtraction"); 265918334Speter } 266018334Speter 266190075Sobrien /* If the conversion to ptrdiff_type does anything like widening or 266290075Sobrien converting a partial to an integral mode, we get a convert_expression 266390075Sobrien that is in the way to do any simplifications. 266490075Sobrien (fold-const.c doesn't know that the extra bits won't be needed. 266590075Sobrien split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a 266690075Sobrien different mode in place.) 266790075Sobrien So first try to find a common term here 'by hand'; we want to cover 266890075Sobrien at least the cases that occur in legal static initializers. */ 266990075Sobrien con0 = TREE_CODE (op0) == NOP_EXPR ? TREE_OPERAND (op0, 0) : op0; 267090075Sobrien con1 = TREE_CODE (op1) == NOP_EXPR ? TREE_OPERAND (op1, 0) : op1; 267190075Sobrien 267290075Sobrien if (TREE_CODE (con0) == PLUS_EXPR) 267390075Sobrien { 267490075Sobrien lit0 = TREE_OPERAND (con0, 1); 267590075Sobrien con0 = TREE_OPERAND (con0, 0); 267690075Sobrien } 267790075Sobrien else 267890075Sobrien lit0 = integer_zero_node; 267990075Sobrien 268090075Sobrien if (TREE_CODE (con1) == PLUS_EXPR) 268190075Sobrien { 268290075Sobrien lit1 = TREE_OPERAND (con1, 1); 268390075Sobrien con1 = TREE_OPERAND (con1, 0); 268490075Sobrien } 268590075Sobrien else 268690075Sobrien lit1 = integer_zero_node; 268790075Sobrien 268890075Sobrien if (operand_equal_p (con0, con1, 0)) 268990075Sobrien { 269090075Sobrien op0 = lit0; 269190075Sobrien op1 = lit1; 269290075Sobrien } 269390075Sobrien 269490075Sobrien 269518334Speter /* First do the subtraction as integers; 269650397Sobrien then drop through to build the divide operator. 269750397Sobrien Do not do default conversions on the minus operator 269850397Sobrien in case restype is a short type. */ 269918334Speter 270018334Speter op0 = build_binary_op (MINUS_EXPR, convert (restype, op0), 270150397Sobrien convert (restype, op1), 0); 270218334Speter /* This generates an error if op1 is pointer to incomplete type. */ 270390075Sobrien if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1)))) 270418334Speter error ("arithmetic on pointer to an incomplete type"); 270518334Speter 270618334Speter /* This generates an error if op0 is pointer to incomplete type. */ 270718334Speter op1 = c_size_in_bytes (target_type); 270818334Speter 270918334Speter /* Divide by the size, in easiest possible way. */ 271018334Speter 271118334Speter result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1)); 271218334Speter 271318334Speter folded = fold (result); 271418334Speter if (folded == result) 271518334Speter TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); 271618334Speter return folded; 271718334Speter} 271818334Speter 271918334Speter/* Construct and perhaps optimize a tree representation 272018334Speter for a unary operation. CODE, a tree_code, specifies the operation 272190075Sobrien and XARG is the operand. 272290075Sobrien For any CODE other than ADDR_EXPR, FLAG nonzero suppresses 272390075Sobrien the default promotions (such as from short to int). 272490075Sobrien For ADDR_EXPR, the default promotions are not applied; FLAG nonzero 272590075Sobrien allows non-lvalues; this is only used to handle conversion of non-lvalue 272690075Sobrien arrays to pointers in C99. */ 272718334Speter 272818334Spetertree 272990075Sobrienbuild_unary_op (code, xarg, flag) 273018334Speter enum tree_code code; 273118334Speter tree xarg; 273290075Sobrien int flag; 273318334Speter{ 273418334Speter /* No default_conversion here. It causes trouble for ADDR_EXPR. */ 273590075Sobrien tree arg = xarg; 273690075Sobrien tree argtype = 0; 273790075Sobrien enum tree_code typecode = TREE_CODE (TREE_TYPE (arg)); 273818334Speter tree val; 273990075Sobrien int noconvert = flag; 274018334Speter 274118334Speter if (typecode == ERROR_MARK) 274218334Speter return error_mark_node; 274390075Sobrien if (typecode == ENUMERAL_TYPE || typecode == BOOLEAN_TYPE) 274418334Speter typecode = INTEGER_TYPE; 274518334Speter 274618334Speter switch (code) 274718334Speter { 274818334Speter case CONVERT_EXPR: 274918334Speter /* This is used for unary plus, because a CONVERT_EXPR 275018334Speter is enough to prevent anybody from looking inside for 275118334Speter associativity, but won't generate any code. */ 275218334Speter if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE 275318334Speter || typecode == COMPLEX_TYPE)) 275452284Sobrien { 275552284Sobrien error ("wrong type argument to unary plus"); 275652284Sobrien return error_mark_node; 275752284Sobrien } 275818334Speter else if (!noconvert) 275918334Speter arg = default_conversion (arg); 276018334Speter break; 276118334Speter 276218334Speter case NEGATE_EXPR: 276318334Speter if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE 276418334Speter || typecode == COMPLEX_TYPE)) 276552284Sobrien { 276652284Sobrien error ("wrong type argument to unary minus"); 276752284Sobrien return error_mark_node; 276852284Sobrien } 276918334Speter else if (!noconvert) 277018334Speter arg = default_conversion (arg); 277118334Speter break; 277218334Speter 277318334Speter case BIT_NOT_EXPR: 277418334Speter if (typecode == COMPLEX_TYPE) 277518334Speter { 277618334Speter code = CONJ_EXPR; 277790075Sobrien if (pedantic) 277890075Sobrien pedwarn ("ISO C does not support `~' for complex conjugation"); 277918334Speter if (!noconvert) 278018334Speter arg = default_conversion (arg); 278118334Speter } 278218334Speter else if (typecode != INTEGER_TYPE) 278352284Sobrien { 278452284Sobrien error ("wrong type argument to bit-complement"); 278552284Sobrien return error_mark_node; 278652284Sobrien } 278718334Speter else if (!noconvert) 278818334Speter arg = default_conversion (arg); 278918334Speter break; 279018334Speter 279118334Speter case ABS_EXPR: 279218334Speter if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE 279318334Speter || typecode == COMPLEX_TYPE)) 279452284Sobrien { 279552284Sobrien error ("wrong type argument to abs"); 279652284Sobrien return error_mark_node; 279752284Sobrien } 279818334Speter else if (!noconvert) 279918334Speter arg = default_conversion (arg); 280018334Speter break; 280118334Speter 280218334Speter case CONJ_EXPR: 280318334Speter /* Conjugating a real value is a no-op, but allow it anyway. */ 280418334Speter if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE 280518334Speter || typecode == COMPLEX_TYPE)) 280652284Sobrien { 280752284Sobrien error ("wrong type argument to conjugation"); 280852284Sobrien return error_mark_node; 280952284Sobrien } 281018334Speter else if (!noconvert) 281118334Speter arg = default_conversion (arg); 281218334Speter break; 281318334Speter 281418334Speter case TRUTH_NOT_EXPR: 281518334Speter if (typecode != INTEGER_TYPE 281618334Speter && typecode != REAL_TYPE && typecode != POINTER_TYPE 281718334Speter && typecode != COMPLEX_TYPE 281818334Speter /* These will convert to a pointer. */ 281918334Speter && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) 282018334Speter { 282152284Sobrien error ("wrong type argument to unary exclamation mark"); 282252284Sobrien return error_mark_node; 282318334Speter } 282418334Speter arg = truthvalue_conversion (arg); 282518334Speter return invert_truthvalue (arg); 282618334Speter 282718334Speter case NOP_EXPR: 282818334Speter break; 282918334Speter 283018334Speter case REALPART_EXPR: 283118334Speter if (TREE_CODE (arg) == COMPLEX_CST) 283218334Speter return TREE_REALPART (arg); 283318334Speter else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) 283418334Speter return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); 283518334Speter else 283618334Speter return arg; 283718334Speter 283818334Speter case IMAGPART_EXPR: 283918334Speter if (TREE_CODE (arg) == COMPLEX_CST) 284018334Speter return TREE_IMAGPART (arg); 284118334Speter else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) 284218334Speter return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); 284318334Speter else 284418334Speter return convert (TREE_TYPE (arg), integer_zero_node); 284518334Speter 284618334Speter case PREINCREMENT_EXPR: 284718334Speter case POSTINCREMENT_EXPR: 284818334Speter case PREDECREMENT_EXPR: 284918334Speter case POSTDECREMENT_EXPR: 285018334Speter /* Handle complex lvalues (when permitted) 285118334Speter by reduction to simpler cases. */ 285218334Speter 285390075Sobrien val = unary_complex_lvalue (code, arg, 0); 285418334Speter if (val != 0) 285518334Speter return val; 285618334Speter 285718334Speter /* Increment or decrement the real part of the value, 285818334Speter and don't change the imaginary part. */ 285918334Speter if (typecode == COMPLEX_TYPE) 286018334Speter { 286118334Speter tree real, imag; 286218334Speter 286390075Sobrien if (pedantic) 286490075Sobrien pedwarn ("ISO C does not support `++' and `--' on complex types"); 286590075Sobrien 286618334Speter arg = stabilize_reference (arg); 286718334Speter real = build_unary_op (REALPART_EXPR, arg, 1); 286818334Speter imag = build_unary_op (IMAGPART_EXPR, arg, 1); 286918334Speter return build (COMPLEX_EXPR, TREE_TYPE (arg), 287018334Speter build_unary_op (code, real, 1), imag); 287118334Speter } 287218334Speter 287318334Speter /* Report invalid types. */ 287418334Speter 287518334Speter if (typecode != POINTER_TYPE 287618334Speter && typecode != INTEGER_TYPE && typecode != REAL_TYPE) 287718334Speter { 287890075Sobrien if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) 287990075Sobrien error ("wrong type argument to increment"); 288090075Sobrien else 288190075Sobrien error ("wrong type argument to decrement"); 288290075Sobrien 288352284Sobrien return error_mark_node; 288418334Speter } 288518334Speter 288618334Speter { 288790075Sobrien tree inc; 288818334Speter tree result_type = TREE_TYPE (arg); 288918334Speter 289018334Speter arg = get_unwidened (arg, 0); 289118334Speter argtype = TREE_TYPE (arg); 289218334Speter 289318334Speter /* Compute the increment. */ 289418334Speter 289518334Speter if (typecode == POINTER_TYPE) 289618334Speter { 289718334Speter /* If pointer target is an undefined struct, 289818334Speter we just cannot know how to do the arithmetic. */ 289990075Sobrien if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type))) 290090075Sobrien { 290190075Sobrien if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) 290290075Sobrien error ("increment of pointer to unknown structure"); 290390075Sobrien else 290490075Sobrien error ("decrement of pointer to unknown structure"); 290590075Sobrien } 290618334Speter else if ((pedantic || warn_pointer_arith) 290718334Speter && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE 290818334Speter || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) 290990075Sobrien { 291090075Sobrien if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) 291190075Sobrien pedwarn ("wrong type argument to increment"); 291290075Sobrien else 291390075Sobrien pedwarn ("wrong type argument to decrement"); 291490075Sobrien } 291590075Sobrien 291618334Speter inc = c_size_in_bytes (TREE_TYPE (result_type)); 291718334Speter } 291818334Speter else 291918334Speter inc = integer_one_node; 292018334Speter 292118334Speter inc = convert (argtype, inc); 292218334Speter 292318334Speter /* Handle incrementing a cast-expression. */ 292418334Speter 292518334Speter while (1) 292618334Speter switch (TREE_CODE (arg)) 292718334Speter { 292818334Speter case NOP_EXPR: 292918334Speter case CONVERT_EXPR: 293018334Speter case FLOAT_EXPR: 293118334Speter case FIX_TRUNC_EXPR: 293218334Speter case FIX_FLOOR_EXPR: 293318334Speter case FIX_ROUND_EXPR: 293418334Speter case FIX_CEIL_EXPR: 293518334Speter pedantic_lvalue_warning (CONVERT_EXPR); 293618334Speter /* If the real type has the same machine representation 293718334Speter as the type it is cast to, we can make better output 293818334Speter by adding directly to the inside of the cast. */ 293918334Speter if ((TREE_CODE (TREE_TYPE (arg)) 294018334Speter == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0)))) 294118334Speter && (TYPE_MODE (TREE_TYPE (arg)) 294218334Speter == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0))))) 294318334Speter arg = TREE_OPERAND (arg, 0); 294418334Speter else 294518334Speter { 294618334Speter tree incremented, modify, value; 294790075Sobrien if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE) 294890075Sobrien value = boolean_increment (code, arg); 294918334Speter else 295090075Sobrien { 295190075Sobrien arg = stabilize_reference (arg); 295290075Sobrien if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) 295390075Sobrien value = arg; 295490075Sobrien else 295590075Sobrien value = save_expr (arg); 295690075Sobrien incremented = build (((code == PREINCREMENT_EXPR 295790075Sobrien || code == POSTINCREMENT_EXPR) 295890075Sobrien ? PLUS_EXPR : MINUS_EXPR), 295990075Sobrien argtype, value, inc); 296090075Sobrien TREE_SIDE_EFFECTS (incremented) = 1; 296190075Sobrien modify = build_modify_expr (arg, NOP_EXPR, incremented); 296290075Sobrien value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); 296390075Sobrien } 296418334Speter TREE_USED (value) = 1; 296518334Speter return value; 296618334Speter } 296718334Speter break; 296818334Speter 296918334Speter default: 297018334Speter goto give_up; 297118334Speter } 297218334Speter give_up: 297318334Speter 297418334Speter /* Complain about anything else that is not a true lvalue. */ 297518334Speter if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR 297618334Speter || code == POSTINCREMENT_EXPR) 297752284Sobrien ? "invalid lvalue in increment" 297852284Sobrien : "invalid lvalue in decrement"))) 297918334Speter return error_mark_node; 298018334Speter 298118334Speter /* Report a read-only lvalue. */ 298218334Speter if (TREE_READONLY (arg)) 298318334Speter readonly_warning (arg, 298418334Speter ((code == PREINCREMENT_EXPR 298518334Speter || code == POSTINCREMENT_EXPR) 298618334Speter ? "increment" : "decrement")); 298718334Speter 298890075Sobrien if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE) 298990075Sobrien val = boolean_increment (code, arg); 299090075Sobrien else 299190075Sobrien val = build (code, TREE_TYPE (arg), arg, inc); 299218334Speter TREE_SIDE_EFFECTS (val) = 1; 299318334Speter val = convert (result_type, val); 299418334Speter if (TREE_CODE (val) != code) 299518334Speter TREE_NO_UNUSED_WARNING (val) = 1; 299618334Speter return val; 299718334Speter } 299818334Speter 299918334Speter case ADDR_EXPR: 300090075Sobrien /* Note that this operation never does default_conversion. */ 300118334Speter 300218334Speter /* Let &* cancel out to simplify resulting code. */ 300318334Speter if (TREE_CODE (arg) == INDIRECT_REF) 300418334Speter { 300518334Speter /* Don't let this be an lvalue. */ 300618334Speter if (lvalue_p (TREE_OPERAND (arg, 0))) 300718334Speter return non_lvalue (TREE_OPERAND (arg, 0)); 300818334Speter return TREE_OPERAND (arg, 0); 300918334Speter } 301018334Speter 301118334Speter /* For &x[y], return x+y */ 301218334Speter if (TREE_CODE (arg) == ARRAY_REF) 301318334Speter { 301418334Speter if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) 301518334Speter return error_mark_node; 301618334Speter return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), 301718334Speter TREE_OPERAND (arg, 1), 1); 301818334Speter } 301918334Speter 302018334Speter /* Handle complex lvalues (when permitted) 302118334Speter by reduction to simpler cases. */ 302290075Sobrien val = unary_complex_lvalue (code, arg, flag); 302318334Speter if (val != 0) 302418334Speter return val; 302518334Speter 302618334Speter#if 0 /* Turned off because inconsistent; 302718334Speter float f; *&(int)f = 3.4 stores in int format 302818334Speter whereas (int)f = 3.4 stores in float format. */ 302918334Speter /* Address of a cast is just a cast of the address 303018334Speter of the operand of the cast. */ 303118334Speter switch (TREE_CODE (arg)) 303218334Speter { 303318334Speter case NOP_EXPR: 303418334Speter case CONVERT_EXPR: 303518334Speter case FLOAT_EXPR: 303618334Speter case FIX_TRUNC_EXPR: 303718334Speter case FIX_FLOOR_EXPR: 303818334Speter case FIX_ROUND_EXPR: 303918334Speter case FIX_CEIL_EXPR: 304018334Speter if (pedantic) 304190075Sobrien pedwarn ("ISO C forbids the address of a cast expression"); 304218334Speter return convert (build_pointer_type (TREE_TYPE (arg)), 304318334Speter build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 304418334Speter 0)); 304518334Speter } 304618334Speter#endif 304718334Speter 304818334Speter /* Anything not already handled and not a true memory reference 304990075Sobrien or a non-lvalue array is an error. */ 305090075Sobrien else if (typecode != FUNCTION_TYPE && !flag 305152284Sobrien && !lvalue_or_else (arg, "invalid lvalue in unary `&'")) 305218334Speter return error_mark_node; 305318334Speter 305418334Speter /* Ordinary case; arg is a COMPONENT_REF or a decl. */ 305518334Speter argtype = TREE_TYPE (arg); 305690075Sobrien 305752284Sobrien /* If the lvalue is const or volatile, merge that into the type 305852284Sobrien to which the address will point. Note that you can't get a 305952284Sobrien restricted pointer by taking the address of something, so we 306052284Sobrien only have to deal with `const' and `volatile' here. */ 306190075Sobrien if ((DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') 306290075Sobrien && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))) 306390075Sobrien argtype = c_build_type_variant (argtype, 306490075Sobrien TREE_READONLY (arg), 306590075Sobrien TREE_THIS_VOLATILE (arg)); 306618334Speter 306718334Speter argtype = build_pointer_type (argtype); 306818334Speter 306918334Speter if (mark_addressable (arg) == 0) 307018334Speter return error_mark_node; 307118334Speter 307218334Speter { 307318334Speter tree addr; 307418334Speter 307518334Speter if (TREE_CODE (arg) == COMPONENT_REF) 307618334Speter { 307718334Speter tree field = TREE_OPERAND (arg, 1); 307818334Speter 307990075Sobrien addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), flag); 308018334Speter 308150397Sobrien if (DECL_C_BIT_FIELD (field)) 308218334Speter { 308318334Speter error ("attempt to take address of bit-field structure member `%s'", 308418334Speter IDENTIFIER_POINTER (DECL_NAME (field))); 308518334Speter return error_mark_node; 308618334Speter } 308718334Speter 308890075Sobrien addr = fold (build (PLUS_EXPR, argtype, 308990075Sobrien convert (argtype, addr), 309090075Sobrien convert (argtype, byte_position (field)))); 309118334Speter } 309218334Speter else 309318334Speter addr = build1 (code, argtype, arg); 309418334Speter 309518334Speter /* Address of a static or external variable or 309618334Speter file-scope function counts as a constant. */ 309718334Speter if (staticp (arg) 309818334Speter && ! (TREE_CODE (arg) == FUNCTION_DECL 309918334Speter && DECL_CONTEXT (arg) != 0)) 310018334Speter TREE_CONSTANT (addr) = 1; 310118334Speter return addr; 310218334Speter } 310350397Sobrien 310450397Sobrien default: 310550397Sobrien break; 310618334Speter } 310718334Speter 310852284Sobrien if (argtype == 0) 310952284Sobrien argtype = TREE_TYPE (arg); 311052284Sobrien return fold (build1 (code, argtype, arg)); 311118334Speter} 311218334Speter 311318334Speter#if 0 311418334Speter/* If CONVERSIONS is a conversion expression or a nested sequence of such, 311518334Speter convert ARG with the same conversions in the same order 311618334Speter and return the result. */ 311718334Speter 311818334Speterstatic tree 311918334Speterconvert_sequence (conversions, arg) 312018334Speter tree conversions; 312118334Speter tree arg; 312218334Speter{ 312318334Speter switch (TREE_CODE (conversions)) 312418334Speter { 312518334Speter case NOP_EXPR: 312618334Speter case CONVERT_EXPR: 312718334Speter case FLOAT_EXPR: 312818334Speter case FIX_TRUNC_EXPR: 312918334Speter case FIX_FLOOR_EXPR: 313018334Speter case FIX_ROUND_EXPR: 313118334Speter case FIX_CEIL_EXPR: 313218334Speter return convert (TREE_TYPE (conversions), 313318334Speter convert_sequence (TREE_OPERAND (conversions, 0), 313418334Speter arg)); 313518334Speter 313618334Speter default: 313718334Speter return arg; 313818334Speter } 313918334Speter} 314018334Speter#endif /* 0 */ 314118334Speter 314218334Speter/* Return nonzero if REF is an lvalue valid for this language. 314318334Speter Lvalues can be assigned, unless their type has TYPE_READONLY. 314418334Speter Lvalues can have their address taken, unless they have DECL_REGISTER. */ 314518334Speter 314618334Speterint 314718334Speterlvalue_p (ref) 314818334Speter tree ref; 314918334Speter{ 315090075Sobrien enum tree_code code = TREE_CODE (ref); 315118334Speter 315218334Speter switch (code) 315318334Speter { 315418334Speter case REALPART_EXPR: 315518334Speter case IMAGPART_EXPR: 315618334Speter case COMPONENT_REF: 315718334Speter return lvalue_p (TREE_OPERAND (ref, 0)); 315818334Speter 315990075Sobrien case COMPOUND_LITERAL_EXPR: 316018334Speter case STRING_CST: 316118334Speter return 1; 316218334Speter 316318334Speter case INDIRECT_REF: 316418334Speter case ARRAY_REF: 316518334Speter case VAR_DECL: 316618334Speter case PARM_DECL: 316718334Speter case RESULT_DECL: 316818334Speter case ERROR_MARK: 316950397Sobrien return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE 317050397Sobrien && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE); 317150397Sobrien 317250397Sobrien case BIND_EXPR: 317350397Sobrien case RTL_EXPR: 317450397Sobrien return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE; 317550397Sobrien 317650397Sobrien default: 317750397Sobrien return 0; 317818334Speter } 317918334Speter} 318018334Speter 318118334Speter/* Return nonzero if REF is an lvalue valid for this language; 318218334Speter otherwise, print an error message and return zero. */ 318318334Speter 318418334Speterint 318552284Sobrienlvalue_or_else (ref, msgid) 318618334Speter tree ref; 318752284Sobrien const char *msgid; 318818334Speter{ 318918334Speter int win = lvalue_p (ref); 319090075Sobrien 319118334Speter if (! win) 319290075Sobrien error ("%s", msgid); 319390075Sobrien 319418334Speter return win; 319518334Speter} 319618334Speter 319718334Speter/* Apply unary lvalue-demanding operator CODE to the expression ARG 319818334Speter for certain kinds of expressions which are not really lvalues 319990075Sobrien but which we can accept as lvalues. If FLAG is nonzero, then 320090075Sobrien non-lvalues are OK since we may be converting a non-lvalue array to 320190075Sobrien a pointer in C99. 320218334Speter 320318334Speter If ARG is not a kind of expression we can handle, return zero. */ 320418334Speter 320518334Speterstatic tree 320690075Sobrienunary_complex_lvalue (code, arg, flag) 320718334Speter enum tree_code code; 320818334Speter tree arg; 320990075Sobrien int flag; 321018334Speter{ 321118334Speter /* Handle (a, b) used as an "lvalue". */ 321218334Speter if (TREE_CODE (arg) == COMPOUND_EXPR) 321318334Speter { 321418334Speter tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); 321550397Sobrien 321650397Sobrien /* If this returns a function type, it isn't really being used as 321750397Sobrien an lvalue, so don't issue a warning about it. */ 321890075Sobrien if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag) 321950397Sobrien pedantic_lvalue_warning (COMPOUND_EXPR); 322050397Sobrien 322118334Speter return build (COMPOUND_EXPR, TREE_TYPE (real_result), 322218334Speter TREE_OPERAND (arg, 0), real_result); 322318334Speter } 322418334Speter 322518334Speter /* Handle (a ? b : c) used as an "lvalue". */ 322618334Speter if (TREE_CODE (arg) == COND_EXPR) 322718334Speter { 322890075Sobrien if (!flag) 322990075Sobrien pedantic_lvalue_warning (COND_EXPR); 323090075Sobrien if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE && !flag) 323150397Sobrien pedantic_lvalue_warning (COMPOUND_EXPR); 323250397Sobrien 323318334Speter return (build_conditional_expr 323418334Speter (TREE_OPERAND (arg, 0), 323590075Sobrien build_unary_op (code, TREE_OPERAND (arg, 1), flag), 323690075Sobrien build_unary_op (code, TREE_OPERAND (arg, 2), flag))); 323718334Speter } 323818334Speter 323918334Speter return 0; 324018334Speter} 324118334Speter 324218334Speter/* If pedantic, warn about improper lvalue. CODE is either COND_EXPR 324318334Speter COMPOUND_EXPR, or CONVERT_EXPR (for casts). */ 324418334Speter 324518334Speterstatic void 324618334Speterpedantic_lvalue_warning (code) 324718334Speter enum tree_code code; 324818334Speter{ 324918334Speter if (pedantic) 325090075Sobrien switch (code) 325190075Sobrien { 325290075Sobrien case COND_EXPR: 325390075Sobrien pedwarn ("ISO C forbids use of conditional expressions as lvalues"); 325490075Sobrien break; 325590075Sobrien case COMPOUND_EXPR: 325690075Sobrien pedwarn ("ISO C forbids use of compound expressions as lvalues"); 325790075Sobrien break; 325890075Sobrien default: 325990075Sobrien pedwarn ("ISO C forbids use of cast expressions as lvalues"); 326090075Sobrien break; 326190075Sobrien } 326218334Speter} 326318334Speter 326418334Speter/* Warn about storing in something that is `const'. */ 326518334Speter 326618334Spetervoid 326752284Sobrienreadonly_warning (arg, msgid) 326818334Speter tree arg; 326952284Sobrien const char *msgid; 327018334Speter{ 327118334Speter if (TREE_CODE (arg) == COMPONENT_REF) 327218334Speter { 327318334Speter if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) 327452284Sobrien readonly_warning (TREE_OPERAND (arg, 0), msgid); 327518334Speter else 327652284Sobrien pedwarn ("%s of read-only member `%s'", _(msgid), 327752284Sobrien IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); 327818334Speter } 327918334Speter else if (TREE_CODE (arg) == VAR_DECL) 328052284Sobrien pedwarn ("%s of read-only variable `%s'", _(msgid), 328152284Sobrien IDENTIFIER_POINTER (DECL_NAME (arg))); 328218334Speter else 328352284Sobrien pedwarn ("%s of read-only location", _(msgid)); 328418334Speter} 328518334Speter 328618334Speter/* Mark EXP saying that we need to be able to take the 328718334Speter address of it; it should not be allocated in a register. 328818334Speter Value is 1 if successful. */ 328918334Speter 329018334Speterint 329118334Spetermark_addressable (exp) 329218334Speter tree exp; 329318334Speter{ 329490075Sobrien tree x = exp; 329518334Speter while (1) 329618334Speter switch (TREE_CODE (x)) 329718334Speter { 329850397Sobrien case COMPONENT_REF: 329950397Sobrien if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) 330050397Sobrien { 330190075Sobrien error ("cannot take address of bit-field `%s'", 330250397Sobrien IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1)))); 330350397Sobrien return 0; 330450397Sobrien } 330550397Sobrien 330650397Sobrien /* ... fall through ... */ 330750397Sobrien 330818334Speter case ADDR_EXPR: 330918334Speter case ARRAY_REF: 331018334Speter case REALPART_EXPR: 331118334Speter case IMAGPART_EXPR: 331218334Speter x = TREE_OPERAND (x, 0); 331318334Speter break; 331418334Speter 331590075Sobrien case COMPOUND_LITERAL_EXPR: 331618334Speter case CONSTRUCTOR: 331718334Speter TREE_ADDRESSABLE (x) = 1; 331818334Speter return 1; 331918334Speter 332018334Speter case VAR_DECL: 332118334Speter case CONST_DECL: 332218334Speter case PARM_DECL: 332318334Speter case RESULT_DECL: 332418334Speter if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) 332518334Speter && DECL_NONLOCAL (x)) 332618334Speter { 332718334Speter if (TREE_PUBLIC (x)) 332818334Speter { 332918334Speter error ("global register variable `%s' used in nested function", 333018334Speter IDENTIFIER_POINTER (DECL_NAME (x))); 333118334Speter return 0; 333218334Speter } 333318334Speter pedwarn ("register variable `%s' used in nested function", 333418334Speter IDENTIFIER_POINTER (DECL_NAME (x))); 333518334Speter } 333618334Speter else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) 333718334Speter { 333818334Speter if (TREE_PUBLIC (x)) 333918334Speter { 334018334Speter error ("address of global register variable `%s' requested", 334118334Speter IDENTIFIER_POINTER (DECL_NAME (x))); 334218334Speter return 0; 334318334Speter } 334418334Speter 334518334Speter /* If we are making this addressable due to its having 334618334Speter volatile components, give a different error message. Also 334718334Speter handle the case of an unnamed parameter by not trying 334818334Speter to give the name. */ 334918334Speter 335018334Speter else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x))) 335118334Speter { 335218334Speter error ("cannot put object with volatile field into register"); 335318334Speter return 0; 335418334Speter } 335518334Speter 335618334Speter pedwarn ("address of register variable `%s' requested", 335718334Speter IDENTIFIER_POINTER (DECL_NAME (x))); 335818334Speter } 335918334Speter put_var_into_stack (x); 336018334Speter 336118334Speter /* drops in */ 336218334Speter case FUNCTION_DECL: 336318334Speter TREE_ADDRESSABLE (x) = 1; 336418334Speter#if 0 /* poplevel deals with this now. */ 336518334Speter if (DECL_CONTEXT (x) == 0) 336618334Speter TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; 336718334Speter#endif 336818334Speter 336918334Speter default: 337018334Speter return 1; 337118334Speter } 337218334Speter} 337318334Speter 337418334Speter/* Build and return a conditional expression IFEXP ? OP1 : OP2. */ 337518334Speter 337618334Spetertree 337718334Speterbuild_conditional_expr (ifexp, op1, op2) 337818334Speter tree ifexp, op1, op2; 337918334Speter{ 338090075Sobrien tree type1; 338190075Sobrien tree type2; 338290075Sobrien enum tree_code code1; 338390075Sobrien enum tree_code code2; 338490075Sobrien tree result_type = NULL; 338518334Speter tree orig_op1 = op1, orig_op2 = op2; 338618334Speter 338718334Speter ifexp = truthvalue_conversion (default_conversion (ifexp)); 338818334Speter 338918334Speter#if 0 /* Produces wrong result if within sizeof. */ 339018334Speter /* Don't promote the operands separately if they promote 339118334Speter the same way. Return the unpromoted type and let the combined 339218334Speter value get promoted if necessary. */ 339318334Speter 339418334Speter if (TREE_TYPE (op1) == TREE_TYPE (op2) 339518334Speter && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE 339618334Speter && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE 339718334Speter && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE) 339818334Speter { 339918334Speter if (TREE_CODE (ifexp) == INTEGER_CST) 340018334Speter return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); 340118334Speter 340218334Speter return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2)); 340318334Speter } 340418334Speter#endif 340518334Speter 340618334Speter /* Promote both alternatives. */ 340718334Speter 340818334Speter if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE) 340918334Speter op1 = default_conversion (op1); 341018334Speter if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE) 341118334Speter op2 = default_conversion (op2); 341218334Speter 341318334Speter if (TREE_CODE (ifexp) == ERROR_MARK 341418334Speter || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK 341518334Speter || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK) 341618334Speter return error_mark_node; 341718334Speter 341818334Speter type1 = TREE_TYPE (op1); 341918334Speter code1 = TREE_CODE (type1); 342018334Speter type2 = TREE_TYPE (op2); 342118334Speter code2 = TREE_CODE (type2); 342218334Speter 342318334Speter /* Quickly detect the usual case where op1 and op2 have the same type 342418334Speter after promotion. */ 342518334Speter if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) 342618334Speter { 342718334Speter if (type1 == type2) 342818334Speter result_type = type1; 342918334Speter else 343018334Speter result_type = TYPE_MAIN_VARIANT (type1); 343118334Speter } 343290075Sobrien else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE 343390075Sobrien || code1 == COMPLEX_TYPE) 343490075Sobrien && (code2 == INTEGER_TYPE || code2 == REAL_TYPE 343590075Sobrien || code2 == COMPLEX_TYPE)) 343618334Speter { 343718334Speter result_type = common_type (type1, type2); 343890075Sobrien 343990075Sobrien /* If -Wsign-compare, warn here if type1 and type2 have 344090075Sobrien different signedness. We'll promote the signed to unsigned 344190075Sobrien and later code won't know it used to be different. 344290075Sobrien Do this check on the original types, so that explicit casts 344390075Sobrien will be considered, but default promotions won't. */ 344490075Sobrien if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare) 344590075Sobrien && !skip_evaluation) 344690075Sobrien { 344790075Sobrien int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1)); 344890075Sobrien int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2)); 344990075Sobrien 345090075Sobrien if (unsigned_op1 ^ unsigned_op2) 345190075Sobrien { 345290075Sobrien /* Do not warn if the result type is signed, since the 345390075Sobrien signed type will only be chosen if it can represent 345490075Sobrien all the values of the unsigned type. */ 345590075Sobrien if (! TREE_UNSIGNED (result_type)) 345690075Sobrien /* OK */; 345790075Sobrien /* Do not warn if the signed quantity is an unsuffixed 345890075Sobrien integer literal (or some static constant expression 345990075Sobrien involving such literals) and it is non-negative. */ 346090075Sobrien else if ((unsigned_op2 && tree_expr_nonnegative_p (op1)) 346190075Sobrien || (unsigned_op1 && tree_expr_nonnegative_p (op2))) 346290075Sobrien /* OK */; 346390075Sobrien else 346490075Sobrien warning ("signed and unsigned type in conditional expression"); 346590075Sobrien } 346690075Sobrien } 346718334Speter } 346818334Speter else if (code1 == VOID_TYPE || code2 == VOID_TYPE) 346918334Speter { 347018334Speter if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) 347190075Sobrien pedwarn ("ISO C forbids conditional expr with only one void side"); 347218334Speter result_type = void_type_node; 347318334Speter } 347418334Speter else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) 347518334Speter { 347618334Speter if (comp_target_types (type1, type2)) 347718334Speter result_type = common_type (type1, type2); 347818334Speter else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node 347918334Speter && TREE_CODE (orig_op1) != NOP_EXPR) 348018334Speter result_type = qualify_type (type2, type1); 348118334Speter else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node 348218334Speter && TREE_CODE (orig_op2) != NOP_EXPR) 348318334Speter result_type = qualify_type (type1, type2); 348490075Sobrien else if (VOID_TYPE_P (TREE_TYPE (type1))) 348518334Speter { 348618334Speter if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE) 348790075Sobrien pedwarn ("ISO C forbids conditional expr between `void *' and function pointer"); 348890075Sobrien result_type = build_pointer_type (qualify_type (TREE_TYPE (type1), 348990075Sobrien TREE_TYPE (type2))); 349018334Speter } 349190075Sobrien else if (VOID_TYPE_P (TREE_TYPE (type2))) 349218334Speter { 349318334Speter if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE) 349490075Sobrien pedwarn ("ISO C forbids conditional expr between `void *' and function pointer"); 349590075Sobrien result_type = build_pointer_type (qualify_type (TREE_TYPE (type2), 349690075Sobrien TREE_TYPE (type1))); 349718334Speter } 349818334Speter else 349918334Speter { 350018334Speter pedwarn ("pointer type mismatch in conditional expression"); 350118334Speter result_type = build_pointer_type (void_type_node); 350218334Speter } 350318334Speter } 350418334Speter else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) 350518334Speter { 350618334Speter if (! integer_zerop (op2)) 350718334Speter pedwarn ("pointer/integer type mismatch in conditional expression"); 350818334Speter else 350918334Speter { 351018334Speter op2 = null_pointer_node; 351118334Speter } 351218334Speter result_type = type1; 351318334Speter } 351418334Speter else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) 351518334Speter { 351618334Speter if (!integer_zerop (op1)) 351718334Speter pedwarn ("pointer/integer type mismatch in conditional expression"); 351818334Speter else 351918334Speter { 352018334Speter op1 = null_pointer_node; 352118334Speter } 352218334Speter result_type = type2; 352318334Speter } 352418334Speter 352518334Speter if (!result_type) 352618334Speter { 352718334Speter if (flag_cond_mismatch) 352818334Speter result_type = void_type_node; 352918334Speter else 353018334Speter { 353118334Speter error ("type mismatch in conditional expression"); 353218334Speter return error_mark_node; 353318334Speter } 353418334Speter } 353518334Speter 353618334Speter /* Merge const and volatile flags of the incoming types. */ 353718334Speter result_type 353818334Speter = build_type_variant (result_type, 353918334Speter TREE_READONLY (op1) || TREE_READONLY (op2), 354018334Speter TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); 354118334Speter 354218334Speter if (result_type != TREE_TYPE (op1)) 354318334Speter op1 = convert_and_check (result_type, op1); 354418334Speter if (result_type != TREE_TYPE (op2)) 354518334Speter op2 = convert_and_check (result_type, op2); 354618334Speter 354718334Speter if (TREE_CODE (ifexp) == INTEGER_CST) 354818334Speter return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1); 354918334Speter 355018334Speter return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); 355118334Speter} 355218334Speter 355318334Speter/* Given a list of expressions, return a compound expression 355418334Speter that performs them all and returns the value of the last of them. */ 355518334Speter 355618334Spetertree 355718334Speterbuild_compound_expr (list) 355818334Speter tree list; 355918334Speter{ 356018334Speter return internal_build_compound_expr (list, TRUE); 356118334Speter} 356218334Speter 356318334Speterstatic tree 356418334Speterinternal_build_compound_expr (list, first_p) 356518334Speter tree list; 356618334Speter int first_p; 356718334Speter{ 356890075Sobrien tree rest; 356918334Speter 357018334Speter if (TREE_CHAIN (list) == 0) 357118334Speter { 357290075Sobrien /* Convert arrays and functions to pointers when there 357390075Sobrien really is a comma operator. */ 357490075Sobrien if (!first_p) 357590075Sobrien TREE_VALUE (list) 357690075Sobrien = default_function_array_conversion (TREE_VALUE (list)); 357790075Sobrien 357818334Speter#if 0 /* If something inside inhibited lvalueness, we should not override. */ 357918334Speter /* Consider (x, y+0), which is not an lvalue since y+0 is not. */ 358018334Speter 358118334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 358218334Speter if (TREE_CODE (list) == NON_LVALUE_EXPR) 358318334Speter list = TREE_OPERAND (list, 0); 358418334Speter#endif 358518334Speter 358618334Speter /* Don't let (0, 0) be null pointer constant. */ 358718334Speter if (!first_p && integer_zerop (TREE_VALUE (list))) 358818334Speter return non_lvalue (TREE_VALUE (list)); 358918334Speter return TREE_VALUE (list); 359018334Speter } 359118334Speter 359218334Speter rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE); 359318334Speter 359418334Speter if (! TREE_SIDE_EFFECTS (TREE_VALUE (list))) 359518334Speter { 359618334Speter /* The left-hand operand of a comma expression is like an expression 359718334Speter statement: with -W or -Wunused, we should warn if it doesn't have 359818334Speter any side-effects, unless it was explicitly cast to (void). */ 359990075Sobrien if ((extra_warnings || warn_unused_value) 360018334Speter && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR 360190075Sobrien && VOID_TYPE_P (TREE_TYPE (TREE_VALUE (list))))) 360218334Speter warning ("left-hand operand of comma expression has no effect"); 360318334Speter 360418334Speter /* When pedantic, a compound expression can be neither an lvalue 360518334Speter nor an integer constant expression. */ 360618334Speter if (! pedantic) 360718334Speter return rest; 360818334Speter } 360918334Speter 361018334Speter /* With -Wunused, we should also warn if the left-hand operand does have 361118334Speter side-effects, but computes a value which is not used. For example, in 361218334Speter `foo() + bar(), baz()' the result of the `+' operator is not used, 361318334Speter so we should issue a warning. */ 361490075Sobrien else if (warn_unused_value) 361518334Speter warn_if_unused_value (TREE_VALUE (list)); 361618334Speter 361718334Speter return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest); 361818334Speter} 361918334Speter 362018334Speter/* Build an expression representing a cast to type TYPE of expression EXPR. */ 362118334Speter 362218334Spetertree 362318334Speterbuild_c_cast (type, expr) 362490075Sobrien tree type; 362518334Speter tree expr; 362618334Speter{ 362790075Sobrien tree value = expr; 362818334Speter 362918334Speter if (type == error_mark_node || expr == error_mark_node) 363018334Speter return error_mark_node; 363118334Speter type = TYPE_MAIN_VARIANT (type); 363218334Speter 363318334Speter#if 0 363418334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 363518334Speter if (TREE_CODE (value) == NON_LVALUE_EXPR) 363618334Speter value = TREE_OPERAND (value, 0); 363718334Speter#endif 363818334Speter 363918334Speter if (TREE_CODE (type) == ARRAY_TYPE) 364018334Speter { 364118334Speter error ("cast specifies array type"); 364218334Speter return error_mark_node; 364318334Speter } 364418334Speter 364518334Speter if (TREE_CODE (type) == FUNCTION_TYPE) 364618334Speter { 364718334Speter error ("cast specifies function type"); 364818334Speter return error_mark_node; 364918334Speter } 365018334Speter 365190075Sobrien if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value))) 365218334Speter { 365318334Speter if (pedantic) 365418334Speter { 365518334Speter if (TREE_CODE (type) == RECORD_TYPE 365618334Speter || TREE_CODE (type) == UNION_TYPE) 365790075Sobrien pedwarn ("ISO C forbids casting nonscalar to the same type"); 365818334Speter } 365918334Speter } 366018334Speter else if (TREE_CODE (type) == UNION_TYPE) 366118334Speter { 366218334Speter tree field; 366390075Sobrien value = default_function_array_conversion (value); 366418334Speter 366518334Speter for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 366618334Speter if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)), 366718334Speter TYPE_MAIN_VARIANT (TREE_TYPE (value)))) 366818334Speter break; 366918334Speter 367018334Speter if (field) 367118334Speter { 367252284Sobrien const char *name; 367318334Speter tree t; 367418334Speter 367518334Speter if (pedantic) 367690075Sobrien pedwarn ("ISO C forbids casts to union type"); 367718334Speter if (TYPE_NAME (type) != 0) 367818334Speter { 367918334Speter if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 368018334Speter name = IDENTIFIER_POINTER (TYPE_NAME (type)); 368118334Speter else 368218334Speter name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 368318334Speter } 368418334Speter else 368518334Speter name = ""; 368618334Speter t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE, 368718334Speter build_tree_list (field, value)), 368818334Speter 0, 0); 368918334Speter TREE_CONSTANT (t) = TREE_CONSTANT (value); 369018334Speter return t; 369118334Speter } 369218334Speter error ("cast to union type from type not present in union"); 369318334Speter return error_mark_node; 369418334Speter } 369518334Speter else 369618334Speter { 369718334Speter tree otype, ovalue; 369818334Speter 369918334Speter /* If casting to void, avoid the error that would come 370018334Speter from default_conversion in the case of a non-lvalue array. */ 370118334Speter if (type == void_type_node) 370218334Speter return build1 (CONVERT_EXPR, type, value); 370318334Speter 370418334Speter /* Convert functions and arrays to pointers, 370518334Speter but don't convert any other types. */ 370690075Sobrien value = default_function_array_conversion (value); 370718334Speter otype = TREE_TYPE (value); 370818334Speter 370918334Speter /* Optionally warn about potentially worrisome casts. */ 371018334Speter 371118334Speter if (warn_cast_qual 371218334Speter && TREE_CODE (type) == POINTER_TYPE 371318334Speter && TREE_CODE (otype) == POINTER_TYPE) 371418334Speter { 371550397Sobrien tree in_type = type; 371650397Sobrien tree in_otype = otype; 371796263Sobrien int added = 0; 371896263Sobrien int discarded = 0; 371950397Sobrien 372090075Sobrien /* Check that the qualifiers on IN_TYPE are a superset of 372190075Sobrien the qualifiers of IN_OTYPE. The outermost level of 372290075Sobrien POINTER_TYPE nodes is uninteresting and we stop as soon 372390075Sobrien as we hit a non-POINTER_TYPE node on either type. */ 372490075Sobrien do 372590075Sobrien { 372690075Sobrien in_otype = TREE_TYPE (in_otype); 372790075Sobrien in_type = TREE_TYPE (in_type); 372896263Sobrien 372996263Sobrien /* GNU C allows cv-qualified function types. 'const' 373096263Sobrien means the function is very pure, 'volatile' means it 373196263Sobrien can't return. We need to warn when such qualifiers 373296263Sobrien are added, not when they're taken away. */ 373396263Sobrien if (TREE_CODE (in_otype) == FUNCTION_TYPE 373496263Sobrien && TREE_CODE (in_type) == FUNCTION_TYPE) 373596263Sobrien added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype)); 373696263Sobrien else 373796263Sobrien discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type)); 373890075Sobrien } 373990075Sobrien while (TREE_CODE (in_type) == POINTER_TYPE 374090075Sobrien && TREE_CODE (in_otype) == POINTER_TYPE); 374190075Sobrien 374296263Sobrien if (added) 374396263Sobrien warning ("cast adds new qualifiers to function type"); 374496263Sobrien 374596263Sobrien if (discarded) 374652284Sobrien /* There are qualifiers present in IN_OTYPE that are not 374752284Sobrien present in IN_TYPE. */ 374890075Sobrien warning ("cast discards qualifiers from pointer target type"); 374918334Speter } 375018334Speter 375118334Speter /* Warn about possible alignment problems. */ 375218334Speter if (STRICT_ALIGNMENT && warn_cast_align 375318334Speter && TREE_CODE (type) == POINTER_TYPE 375418334Speter && TREE_CODE (otype) == POINTER_TYPE 375518334Speter && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE 375618334Speter && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE 375750397Sobrien /* Don't warn about opaque types, where the actual alignment 375850397Sobrien restriction is unknown. */ 375950397Sobrien && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE 376050397Sobrien || TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE) 376150397Sobrien && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode) 376218334Speter && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) 376318334Speter warning ("cast increases required alignment of target type"); 376418334Speter 376518334Speter if (TREE_CODE (type) == INTEGER_TYPE 376618334Speter && TREE_CODE (otype) == POINTER_TYPE 376718334Speter && TYPE_PRECISION (type) != TYPE_PRECISION (otype) 376818334Speter && !TREE_CONSTANT (value)) 376918334Speter warning ("cast from pointer to integer of different size"); 377018334Speter 377118334Speter if (warn_bad_function_cast 377218334Speter && TREE_CODE (value) == CALL_EXPR 377318334Speter && TREE_CODE (type) != TREE_CODE (otype)) 377418334Speter warning ("cast does not match function type"); 377518334Speter 377618334Speter if (TREE_CODE (type) == POINTER_TYPE 377718334Speter && TREE_CODE (otype) == INTEGER_TYPE 377818334Speter && TYPE_PRECISION (type) != TYPE_PRECISION (otype) 377918334Speter /* Don't warn about converting any constant. */ 378018334Speter && !TREE_CONSTANT (value)) 378118334Speter warning ("cast to pointer from integer of different size"); 378218334Speter 378318334Speter ovalue = value; 378418334Speter value = convert (type, value); 378518334Speter 378618334Speter /* Ignore any integer overflow caused by the cast. */ 378718334Speter if (TREE_CODE (value) == INTEGER_CST) 378818334Speter { 378918334Speter TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); 379018334Speter TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); 379118334Speter } 379218334Speter } 379318334Speter 379490075Sobrien /* Pedantically, don't let (void *) (FOO *) 0 be a null pointer constant. */ 379518334Speter if (pedantic && TREE_CODE (value) == INTEGER_CST 379618334Speter && TREE_CODE (expr) == INTEGER_CST 379718334Speter && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE) 379818334Speter value = non_lvalue (value); 379918334Speter 380018334Speter /* If pedantic, don't let a cast be an lvalue. */ 380118334Speter if (value == expr && pedantic) 380218334Speter value = non_lvalue (value); 380318334Speter 380418334Speter return value; 380518334Speter} 380690075Sobrien 380790075Sobrien/* Interpret a cast of expression EXPR to type TYPE. */ 380890075Sobrientree 380990075Sobrienc_cast_expr (type, expr) 381090075Sobrien tree type, expr; 381190075Sobrien{ 381290075Sobrien int saved_wsp = warn_strict_prototypes; 381390075Sobrien 381490075Sobrien /* This avoids warnings about unprototyped casts on 381590075Sobrien integers. E.g. "#define SIG_DFL (void(*)())0". */ 381690075Sobrien if (TREE_CODE (expr) == INTEGER_CST) 381790075Sobrien warn_strict_prototypes = 0; 381890075Sobrien type = groktypename (type); 381990075Sobrien warn_strict_prototypes = saved_wsp; 382090075Sobrien 382190075Sobrien return build_c_cast (type, expr); 382290075Sobrien} 382390075Sobrien 382418334Speter 382518334Speter/* Build an assignment expression of lvalue LHS from value RHS. 382618334Speter MODIFYCODE is the code for a binary operator that we use 382718334Speter to combine the old value of LHS with RHS to get the new value. 382818334Speter Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */ 382918334Speter 383018334Spetertree 383118334Speterbuild_modify_expr (lhs, modifycode, rhs) 383218334Speter tree lhs, rhs; 383318334Speter enum tree_code modifycode; 383418334Speter{ 383590075Sobrien tree result; 383618334Speter tree newrhs; 383718334Speter tree lhstype = TREE_TYPE (lhs); 383818334Speter tree olhstype = lhstype; 383918334Speter 384018334Speter /* Types that aren't fully specified cannot be used in assignments. */ 384118334Speter lhs = require_complete_type (lhs); 384218334Speter 384318334Speter /* Avoid duplicate error messages from operands that had errors. */ 384418334Speter if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) 384518334Speter return error_mark_node; 384618334Speter 384718334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 384818334Speter /* Do not use STRIP_NOPS here. We do not want an enumerator 384918334Speter whose value is 0 to count as a null pointer constant. */ 385018334Speter if (TREE_CODE (rhs) == NON_LVALUE_EXPR) 385118334Speter rhs = TREE_OPERAND (rhs, 0); 385218334Speter 385318334Speter newrhs = rhs; 385418334Speter 385518334Speter /* Handle control structure constructs used as "lvalues". */ 385618334Speter 385718334Speter switch (TREE_CODE (lhs)) 385818334Speter { 385918334Speter /* Handle (a, b) used as an "lvalue". */ 386018334Speter case COMPOUND_EXPR: 386118334Speter pedantic_lvalue_warning (COMPOUND_EXPR); 386290075Sobrien newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), modifycode, rhs); 386318334Speter if (TREE_CODE (newrhs) == ERROR_MARK) 386418334Speter return error_mark_node; 386518334Speter return build (COMPOUND_EXPR, lhstype, 386618334Speter TREE_OPERAND (lhs, 0), newrhs); 386718334Speter 386818334Speter /* Handle (a ? b : c) used as an "lvalue". */ 386918334Speter case COND_EXPR: 387018334Speter pedantic_lvalue_warning (COND_EXPR); 387118334Speter rhs = save_expr (rhs); 387218334Speter { 387318334Speter /* Produce (a ? (b = rhs) : (c = rhs)) 387418334Speter except that the RHS goes through a save-expr 387518334Speter so the code to compute it is only emitted once. */ 387618334Speter tree cond 387718334Speter = build_conditional_expr (TREE_OPERAND (lhs, 0), 387818334Speter build_modify_expr (TREE_OPERAND (lhs, 1), 387918334Speter modifycode, rhs), 388018334Speter build_modify_expr (TREE_OPERAND (lhs, 2), 388118334Speter modifycode, rhs)); 388218334Speter if (TREE_CODE (cond) == ERROR_MARK) 388318334Speter return cond; 388418334Speter /* Make sure the code to compute the rhs comes out 388518334Speter before the split. */ 388618334Speter return build (COMPOUND_EXPR, TREE_TYPE (lhs), 388718334Speter /* But cast it to void to avoid an "unused" error. */ 388818334Speter convert (void_type_node, rhs), cond); 388918334Speter } 389050397Sobrien default: 389150397Sobrien break; 389218334Speter } 389318334Speter 389418334Speter /* If a binary op has been requested, combine the old LHS value with the RHS 389518334Speter producing the value we should actually store into the LHS. */ 389618334Speter 389718334Speter if (modifycode != NOP_EXPR) 389818334Speter { 389918334Speter lhs = stabilize_reference (lhs); 390018334Speter newrhs = build_binary_op (modifycode, lhs, rhs, 1); 390118334Speter } 390218334Speter 390318334Speter /* Handle a cast used as an "lvalue". 390418334Speter We have already performed any binary operator using the value as cast. 390518334Speter Now convert the result to the cast type of the lhs, 390618334Speter and then true type of the lhs and store it there; 390718334Speter then convert result back to the cast type to be the value 390818334Speter of the assignment. */ 390918334Speter 391018334Speter switch (TREE_CODE (lhs)) 391118334Speter { 391218334Speter case NOP_EXPR: 391318334Speter case CONVERT_EXPR: 391418334Speter case FLOAT_EXPR: 391518334Speter case FIX_TRUNC_EXPR: 391618334Speter case FIX_FLOOR_EXPR: 391718334Speter case FIX_ROUND_EXPR: 391818334Speter case FIX_CEIL_EXPR: 391990075Sobrien newrhs = default_function_array_conversion (newrhs); 392018334Speter { 392118334Speter tree inner_lhs = TREE_OPERAND (lhs, 0); 392218334Speter tree result; 392318334Speter result = build_modify_expr (inner_lhs, NOP_EXPR, 392418334Speter convert (TREE_TYPE (inner_lhs), 392518334Speter convert (lhstype, newrhs))); 392618334Speter if (TREE_CODE (result) == ERROR_MARK) 392718334Speter return result; 392818334Speter pedantic_lvalue_warning (CONVERT_EXPR); 392918334Speter return convert (TREE_TYPE (lhs), result); 393018334Speter } 393150397Sobrien 393250397Sobrien default: 393350397Sobrien break; 393418334Speter } 393518334Speter 393618334Speter /* Now we have handled acceptable kinds of LHS that are not truly lvalues. 393718334Speter Reject anything strange now. */ 393818334Speter 393952284Sobrien if (!lvalue_or_else (lhs, "invalid lvalue in assignment")) 394018334Speter return error_mark_node; 394118334Speter 394218334Speter /* Warn about storing in something that is `const'. */ 394318334Speter 394418334Speter if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype) 394518334Speter || ((TREE_CODE (lhstype) == RECORD_TYPE 394618334Speter || TREE_CODE (lhstype) == UNION_TYPE) 394718334Speter && C_TYPE_FIELDS_READONLY (lhstype))) 394818334Speter readonly_warning (lhs, "assignment"); 394918334Speter 395018334Speter /* If storing into a structure or union member, 395118334Speter it has probably been given type `int'. 395218334Speter Compute the type that would go with 395318334Speter the actual amount of storage the member occupies. */ 395418334Speter 395518334Speter if (TREE_CODE (lhs) == COMPONENT_REF 395618334Speter && (TREE_CODE (lhstype) == INTEGER_TYPE 395790075Sobrien || TREE_CODE (lhstype) == BOOLEAN_TYPE 395818334Speter || TREE_CODE (lhstype) == REAL_TYPE 395918334Speter || TREE_CODE (lhstype) == ENUMERAL_TYPE)) 396018334Speter lhstype = TREE_TYPE (get_unwidened (lhs, 0)); 396118334Speter 396218334Speter /* If storing in a field that is in actuality a short or narrower than one, 396318334Speter we must store in the field in its actual type. */ 396418334Speter 396518334Speter if (lhstype != TREE_TYPE (lhs)) 396618334Speter { 396718334Speter lhs = copy_node (lhs); 396818334Speter TREE_TYPE (lhs) = lhstype; 396918334Speter } 397018334Speter 397118334Speter /* Convert new value to destination type. */ 397218334Speter 397352284Sobrien newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"), 397418334Speter NULL_TREE, NULL_TREE, 0); 397518334Speter if (TREE_CODE (newrhs) == ERROR_MARK) 397618334Speter return error_mark_node; 397718334Speter 397890075Sobrien /* Scan operands */ 397990075Sobrien 398018334Speter result = build (MODIFY_EXPR, lhstype, lhs, newrhs); 398118334Speter TREE_SIDE_EFFECTS (result) = 1; 398218334Speter 398318334Speter /* If we got the LHS in a different type for storing in, 398418334Speter convert the result back to the nominal type of LHS 398518334Speter so that the value we return always has the same type 398618334Speter as the LHS argument. */ 398718334Speter 398818334Speter if (olhstype == TREE_TYPE (result)) 398918334Speter return result; 399052284Sobrien return convert_for_assignment (olhstype, result, _("assignment"), 399118334Speter NULL_TREE, NULL_TREE, 0); 399218334Speter} 399318334Speter 399418334Speter/* Convert value RHS to type TYPE as preparation for an assignment 399518334Speter to an lvalue of type TYPE. 399618334Speter The real work of conversion is done by `convert'. 399718334Speter The purpose of this function is to generate error messages 399818334Speter for assignments that are not allowed in C. 399918334Speter ERRTYPE is a string to use in error messages: 400018334Speter "assignment", "return", etc. If it is null, this is parameter passing 400152284Sobrien for a function call (and different error messages are output). 400218334Speter 400318334Speter FUNNAME is the name of the function being called, 400418334Speter as an IDENTIFIER_NODE, or null. 400518334Speter PARMNUM is the number of the argument, for printing in error messages. */ 400618334Speter 400718334Speterstatic tree 400818334Speterconvert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) 400918334Speter tree type, rhs; 401052284Sobrien const char *errtype; 401118334Speter tree fundecl, funname; 401218334Speter int parmnum; 401318334Speter{ 401490075Sobrien enum tree_code codel = TREE_CODE (type); 401590075Sobrien tree rhstype; 401690075Sobrien enum tree_code coder; 401718334Speter 401818334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 401918334Speter /* Do not use STRIP_NOPS here. We do not want an enumerator 402018334Speter whose value is 0 to count as a null pointer constant. */ 402118334Speter if (TREE_CODE (rhs) == NON_LVALUE_EXPR) 402218334Speter rhs = TREE_OPERAND (rhs, 0); 402318334Speter 402418334Speter if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE 402518334Speter || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) 402618334Speter rhs = default_conversion (rhs); 402718334Speter else if (optimize && TREE_CODE (rhs) == VAR_DECL) 402890075Sobrien rhs = decl_constant_value_for_broken_optimization (rhs); 402918334Speter 403018334Speter rhstype = TREE_TYPE (rhs); 403118334Speter coder = TREE_CODE (rhstype); 403218334Speter 403318334Speter if (coder == ERROR_MARK) 403418334Speter return error_mark_node; 403518334Speter 403618334Speter if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) 403718334Speter { 403818334Speter overflow_warning (rhs); 403918334Speter /* Check for Objective-C protocols. This will issue a warning if 404018334Speter there are protocol violations. No need to use the return value. */ 404118334Speter maybe_objc_comptypes (type, rhstype, 0); 404218334Speter return rhs; 404318334Speter } 404418334Speter 404518334Speter if (coder == VOID_TYPE) 404618334Speter { 404718334Speter error ("void value not ignored as it ought to be"); 404818334Speter return error_mark_node; 404918334Speter } 405090075Sobrien /* A type converts to a reference to it. 405190075Sobrien This code doesn't fully support references, it's just for the 405290075Sobrien special case of va_start and va_copy. */ 405390075Sobrien if (codel == REFERENCE_TYPE 405490075Sobrien && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1) 405590075Sobrien { 405690075Sobrien if (mark_addressable (rhs) == 0) 405790075Sobrien return error_mark_node; 405890075Sobrien rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs); 405990075Sobrien 406090075Sobrien /* We already know that these two types are compatible, but they 406190075Sobrien may not be exactly identical. In fact, `TREE_TYPE (type)' is 406290075Sobrien likely to be __builtin_va_list and `TREE_TYPE (rhs)' is 406390075Sobrien likely to be va_list, a typedef to __builtin_va_list, which 406490075Sobrien is different enough that it will cause problems later. */ 406590075Sobrien if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type)) 406690075Sobrien rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs); 406790075Sobrien 406890075Sobrien rhs = build1 (NOP_EXPR, type, rhs); 406990075Sobrien return rhs; 407090075Sobrien } 407118334Speter /* Arithmetic types all interconvert, and enum is treated like int. */ 407290075Sobrien else if ((codel == INTEGER_TYPE || codel == REAL_TYPE 407390075Sobrien || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE 407490075Sobrien || codel == BOOLEAN_TYPE) 407590075Sobrien && (coder == INTEGER_TYPE || coder == REAL_TYPE 407690075Sobrien || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE 407790075Sobrien || coder == BOOLEAN_TYPE)) 407818334Speter return convert_and_check (type, rhs); 407918334Speter 408050397Sobrien /* Conversion to a transparent union from its member types. 408150397Sobrien This applies only to function arguments. */ 408250397Sobrien else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype) 408318334Speter { 408418334Speter tree memb_types; 408550397Sobrien tree marginal_memb_type = 0; 408618334Speter 408718334Speter for (memb_types = TYPE_FIELDS (type); memb_types; 408818334Speter memb_types = TREE_CHAIN (memb_types)) 408918334Speter { 409050397Sobrien tree memb_type = TREE_TYPE (memb_types); 409118334Speter 409250397Sobrien if (comptypes (TYPE_MAIN_VARIANT (memb_type), 409350397Sobrien TYPE_MAIN_VARIANT (rhstype))) 409450397Sobrien break; 409550397Sobrien 409650397Sobrien if (TREE_CODE (memb_type) != POINTER_TYPE) 409750397Sobrien continue; 409850397Sobrien 409950397Sobrien if (coder == POINTER_TYPE) 410018334Speter { 410190075Sobrien tree ttl = TREE_TYPE (memb_type); 410290075Sobrien tree ttr = TREE_TYPE (rhstype); 410318334Speter 410418334Speter /* Any non-function converts to a [const][volatile] void * 410518334Speter and vice versa; otherwise, targets must be the same. 410618334Speter Meanwhile, the lhs target must have all the qualifiers of 410718334Speter the rhs. */ 410890075Sobrien if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) 410918334Speter || comp_target_types (memb_type, rhstype)) 411018334Speter { 411150397Sobrien /* If this type won't generate any warnings, use it. */ 411252284Sobrien if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr) 411352284Sobrien || ((TREE_CODE (ttr) == FUNCTION_TYPE 411452284Sobrien && TREE_CODE (ttl) == FUNCTION_TYPE) 411552284Sobrien ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) 411652284Sobrien == TYPE_QUALS (ttr)) 411752284Sobrien : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) 411852284Sobrien == TYPE_QUALS (ttl)))) 411950397Sobrien break; 412018334Speter 412150397Sobrien /* Keep looking for a better type, but remember this one. */ 412250397Sobrien if (! marginal_memb_type) 412350397Sobrien marginal_memb_type = memb_type; 412418334Speter } 412518334Speter } 412618334Speter 412718334Speter /* Can convert integer zero to any pointer type. */ 412850397Sobrien if (integer_zerop (rhs) 412950397Sobrien || (TREE_CODE (rhs) == NOP_EXPR 413050397Sobrien && integer_zerop (TREE_OPERAND (rhs, 0)))) 413150397Sobrien { 413250397Sobrien rhs = null_pointer_node; 413350397Sobrien break; 413450397Sobrien } 413518334Speter } 413650397Sobrien 413750397Sobrien if (memb_types || marginal_memb_type) 413850397Sobrien { 413950397Sobrien if (! memb_types) 414050397Sobrien { 414150397Sobrien /* We have only a marginally acceptable member type; 414250397Sobrien it needs a warning. */ 414390075Sobrien tree ttl = TREE_TYPE (marginal_memb_type); 414490075Sobrien tree ttr = TREE_TYPE (rhstype); 414550397Sobrien 414650397Sobrien /* Const and volatile mean something different for function 414750397Sobrien types, so the usual warnings are not appropriate. */ 414850397Sobrien if (TREE_CODE (ttr) == FUNCTION_TYPE 414950397Sobrien && TREE_CODE (ttl) == FUNCTION_TYPE) 415050397Sobrien { 415150397Sobrien /* Because const and volatile on functions are 415250397Sobrien restrictions that say the function will not do 415350397Sobrien certain things, it is okay to use a const or volatile 415450397Sobrien function where an ordinary one is wanted, but not 415550397Sobrien vice-versa. */ 415652284Sobrien if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) 415752284Sobrien warn_for_assignment ("%s makes qualified function pointer from unqualified", 415852284Sobrien errtype, funname, parmnum); 415950397Sobrien } 416052284Sobrien else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) 416152284Sobrien warn_for_assignment ("%s discards qualifiers from pointer target type", 416252284Sobrien errtype, funname, 416352284Sobrien parmnum); 416450397Sobrien } 416550397Sobrien 416650397Sobrien if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl)) 416790075Sobrien pedwarn ("ISO C prohibits argument conversion to union type"); 416850397Sobrien 416950397Sobrien return build1 (NOP_EXPR, type, rhs); 417050397Sobrien } 417118334Speter } 417218334Speter 417318334Speter /* Conversions among pointers */ 417490075Sobrien else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE) 417590075Sobrien && (coder == POINTER_TYPE || coder == REFERENCE_TYPE)) 417618334Speter { 417790075Sobrien tree ttl = TREE_TYPE (type); 417890075Sobrien tree ttr = TREE_TYPE (rhstype); 417918334Speter 418018334Speter /* Any non-function converts to a [const][volatile] void * 418118334Speter and vice versa; otherwise, targets must be the same. 418218334Speter Meanwhile, the lhs target must have all the qualifiers of the rhs. */ 418390075Sobrien if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) 418418334Speter || comp_target_types (type, rhstype) 418518334Speter || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) 418618334Speter == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) 418718334Speter { 418818334Speter if (pedantic 418990075Sobrien && ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE) 419018334Speter || 419190075Sobrien (VOID_TYPE_P (ttr) 419218334Speter /* Check TREE_CODE to catch cases like (void *) (char *) 0 419318334Speter which are not ANSI null ptr constants. */ 419418334Speter && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) 419518334Speter && TREE_CODE (ttl) == FUNCTION_TYPE))) 419690075Sobrien warn_for_assignment ("ISO C forbids %s between function pointer and `void *'", 419752284Sobrien errtype, funname, parmnum); 419818334Speter /* Const and volatile mean something different for function types, 419918334Speter so the usual warnings are not appropriate. */ 420018334Speter else if (TREE_CODE (ttr) != FUNCTION_TYPE 420118334Speter && TREE_CODE (ttl) != FUNCTION_TYPE) 420218334Speter { 420352284Sobrien if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) 420452284Sobrien warn_for_assignment ("%s discards qualifiers from pointer target type", 420552284Sobrien errtype, funname, parmnum); 420618334Speter /* If this is not a case of ignoring a mismatch in signedness, 420718334Speter no warning. */ 420890075Sobrien else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr) 420918334Speter || comp_target_types (type, rhstype)) 421018334Speter ; 421118334Speter /* If there is a mismatch, do warn. */ 421218334Speter else if (pedantic) 421318334Speter warn_for_assignment ("pointer targets in %s differ in signedness", 421452284Sobrien errtype, funname, parmnum); 421518334Speter } 421618334Speter else if (TREE_CODE (ttl) == FUNCTION_TYPE 421718334Speter && TREE_CODE (ttr) == FUNCTION_TYPE) 421818334Speter { 421918334Speter /* Because const and volatile on functions are restrictions 422018334Speter that say the function will not do certain things, 422118334Speter it is okay to use a const or volatile function 422218334Speter where an ordinary one is wanted, but not vice-versa. */ 422352284Sobrien if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) 422452284Sobrien warn_for_assignment ("%s makes qualified function pointer from unqualified", 422552284Sobrien errtype, funname, parmnum); 422618334Speter } 422718334Speter } 422818334Speter else 422918334Speter warn_for_assignment ("%s from incompatible pointer type", 423052284Sobrien errtype, funname, parmnum); 423118334Speter return convert (type, rhs); 423218334Speter } 423318334Speter else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) 423418334Speter { 423518334Speter /* An explicit constant 0 can convert to a pointer, 423618334Speter or one that results from arithmetic, even including 423718334Speter a cast to integer type. */ 423818334Speter if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs)) 423918334Speter && 424018334Speter ! (TREE_CODE (rhs) == NOP_EXPR 424118334Speter && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE 424218334Speter && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST 424318334Speter && integer_zerop (TREE_OPERAND (rhs, 0)))) 424418334Speter { 424518334Speter warn_for_assignment ("%s makes pointer from integer without a cast", 424652284Sobrien errtype, funname, parmnum); 424718334Speter return convert (type, rhs); 424818334Speter } 424918334Speter return null_pointer_node; 425018334Speter } 425118334Speter else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) 425218334Speter { 425318334Speter warn_for_assignment ("%s makes integer from pointer without a cast", 425452284Sobrien errtype, funname, parmnum); 425518334Speter return convert (type, rhs); 425618334Speter } 425790075Sobrien else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE) 425890075Sobrien return convert (type, rhs); 425918334Speter 426018334Speter if (!errtype) 426118334Speter { 426218334Speter if (funname) 426318334Speter { 426418334Speter tree selector = maybe_building_objc_message_expr (); 426518334Speter 426618334Speter if (selector && parmnum > 2) 426718334Speter error ("incompatible type for argument %d of `%s'", 426818334Speter parmnum - 2, IDENTIFIER_POINTER (selector)); 426918334Speter else 427018334Speter error ("incompatible type for argument %d of `%s'", 427118334Speter parmnum, IDENTIFIER_POINTER (funname)); 427218334Speter } 427318334Speter else 427418334Speter error ("incompatible type for argument %d of indirect function call", 427518334Speter parmnum); 427618334Speter } 427718334Speter else 427852284Sobrien error ("incompatible types in %s", errtype); 427918334Speter 428018334Speter return error_mark_node; 428118334Speter} 428218334Speter 428396263Sobrien/* Convert VALUE for assignment into inlined parameter PARM. */ 428496263Sobrien 428596263Sobrientree 428696263Sobrienc_convert_parm_for_inlining (parm, value, fn) 428796263Sobrien tree parm, value, fn; 428896263Sobrien{ 428996263Sobrien tree ret, type; 429096263Sobrien 429196263Sobrien /* If FN was prototyped, the value has been converted already 429296263Sobrien in convert_arguments. */ 429396263Sobrien if (! value || TYPE_ARG_TYPES (TREE_TYPE (fn))) 429496263Sobrien return value; 429596263Sobrien 429696263Sobrien type = TREE_TYPE (parm); 429796263Sobrien ret = convert_for_assignment (type, value, 429896263Sobrien (char *) 0 /* arg passing */, fn, 429996263Sobrien DECL_NAME (fn), 0); 430096263Sobrien if (PROMOTE_PROTOTYPES 430196263Sobrien && INTEGRAL_TYPE_P (type) 430296263Sobrien && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) 430396263Sobrien ret = default_conversion (ret); 430496263Sobrien return ret; 430596263Sobrien} 430696263Sobrien 430752284Sobrien/* Print a warning using MSGID. 430818334Speter It gets OPNAME as its one parameter. 430918334Speter If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". 431018334Speter FUNCTION and ARGNUM are handled specially if we are building an 431118334Speter Objective-C selector. */ 431218334Speter 431318334Speterstatic void 431452284Sobrienwarn_for_assignment (msgid, opname, function, argnum) 431552284Sobrien const char *msgid; 431652284Sobrien const char *opname; 431718334Speter tree function; 431818334Speter int argnum; 431918334Speter{ 432018334Speter if (opname == 0) 432118334Speter { 432218334Speter tree selector = maybe_building_objc_message_expr (); 432352284Sobrien char * new_opname; 432418334Speter 432518334Speter if (selector && argnum > 2) 432618334Speter { 432718334Speter function = selector; 432818334Speter argnum -= 2; 432918334Speter } 433018334Speter if (function) 433118334Speter { 433218334Speter /* Function name is known; supply it. */ 433390075Sobrien const char *const argstring = _("passing arg %d of `%s'"); 433452284Sobrien new_opname = (char *) alloca (IDENTIFIER_LENGTH (function) 433552284Sobrien + strlen (argstring) + 1 + 25 433652284Sobrien /*%d*/ + 1); 433752284Sobrien sprintf (new_opname, argstring, argnum, 433852284Sobrien IDENTIFIER_POINTER (function)); 433918334Speter } 434018334Speter else 434118334Speter { 434290075Sobrien /* Function name unknown (call through ptr); just give arg number. */ 434390075Sobrien const char *const argnofun = _("passing arg %d of pointer to function"); 434452284Sobrien new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1); 434552284Sobrien sprintf (new_opname, argnofun, argnum); 434618334Speter } 434752284Sobrien opname = new_opname; 434818334Speter } 434952284Sobrien pedwarn (msgid, opname); 435018334Speter} 435118334Speter 435218334Speter/* If VALUE is a compound expr all of whose expressions are constant, then 435318334Speter return its value. Otherwise, return error_mark_node. 435418334Speter 435518334Speter This is for handling COMPOUND_EXPRs as initializer elements 435618334Speter which is allowed with a warning when -pedantic is specified. */ 435718334Speter 435818334Speterstatic tree 435918334Spetervalid_compound_expr_initializer (value, endtype) 436018334Speter tree value; 436118334Speter tree endtype; 436218334Speter{ 436318334Speter if (TREE_CODE (value) == COMPOUND_EXPR) 436418334Speter { 436518334Speter if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype) 436618334Speter == error_mark_node) 436718334Speter return error_mark_node; 436818334Speter return valid_compound_expr_initializer (TREE_OPERAND (value, 1), 436918334Speter endtype); 437018334Speter } 437118334Speter else if (! TREE_CONSTANT (value) 437218334Speter && ! initializer_constant_valid_p (value, endtype)) 437318334Speter return error_mark_node; 437418334Speter else 437518334Speter return value; 437618334Speter} 437718334Speter 437818334Speter/* Perform appropriate conversions on the initial value of a variable, 437918334Speter store it in the declaration DECL, 438018334Speter and print any error messages that are appropriate. 438118334Speter If the init is invalid, store an ERROR_MARK. */ 438218334Speter 438318334Spetervoid 438418334Speterstore_init_value (decl, init) 438518334Speter tree decl, init; 438618334Speter{ 438790075Sobrien tree value, type; 438818334Speter 438918334Speter /* If variable's type was invalidly declared, just ignore it. */ 439018334Speter 439118334Speter type = TREE_TYPE (decl); 439218334Speter if (TREE_CODE (type) == ERROR_MARK) 439318334Speter return; 439418334Speter 439518334Speter /* Digest the specified initializer into an expression. */ 439618334Speter 439718334Speter value = digest_init (type, init, TREE_STATIC (decl), 439890075Sobrien TREE_STATIC (decl) || (pedantic && !flag_isoc99)); 439918334Speter 440018334Speter /* Store the expression if valid; else report error. */ 440118334Speter 440218334Speter#if 0 440318334Speter /* Note that this is the only place we can detect the error 440418334Speter in a case such as struct foo bar = (struct foo) { x, y }; 440518334Speter where there is one initial value which is a constructor expression. */ 440618334Speter if (value == error_mark_node) 440718334Speter ; 440818334Speter else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value)) 440918334Speter { 441018334Speter error ("initializer for static variable is not constant"); 441118334Speter value = error_mark_node; 441218334Speter } 441318334Speter else if (TREE_STATIC (decl) 441418334Speter && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) 441518334Speter { 441618334Speter error ("initializer for static variable uses complicated arithmetic"); 441718334Speter value = error_mark_node; 441818334Speter } 441918334Speter else 442018334Speter { 442118334Speter if (pedantic && TREE_CODE (value) == CONSTRUCTOR) 442218334Speter { 442318334Speter if (! TREE_CONSTANT (value)) 442418334Speter pedwarn ("aggregate initializer is not constant"); 442518334Speter else if (! TREE_STATIC (value)) 442618334Speter pedwarn ("aggregate initializer uses complicated arithmetic"); 442718334Speter } 442818334Speter } 442918334Speter#endif 443018334Speter 443190075Sobrien if (warn_traditional && !in_system_header 443290075Sobrien && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && ! TREE_STATIC (decl)) 443390075Sobrien warning ("traditional C rejects automatic aggregate initialization"); 443490075Sobrien 443518334Speter DECL_INITIAL (decl) = value; 443618334Speter 443718334Speter /* ANSI wants warnings about out-of-range constant initializers. */ 443818334Speter STRIP_TYPE_NOPS (value); 443918334Speter constant_expression_warning (value); 444090075Sobrien 444190075Sobrien /* Check if we need to set array size from compound literal size. */ 444290075Sobrien if (TREE_CODE (type) == ARRAY_TYPE 444390075Sobrien && TYPE_DOMAIN (type) == 0 444490075Sobrien && value != error_mark_node) 444590075Sobrien { 444690075Sobrien tree inside_init = init; 444790075Sobrien 444890075Sobrien if (TREE_CODE (init) == NON_LVALUE_EXPR) 444990075Sobrien inside_init = TREE_OPERAND (init, 0); 445090075Sobrien inside_init = fold (inside_init); 445190075Sobrien 445290075Sobrien if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) 445390075Sobrien { 445490075Sobrien tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init); 445590075Sobrien 445690075Sobrien if (TYPE_DOMAIN (TREE_TYPE (decl))) 445790075Sobrien { 445890075Sobrien /* For int foo[] = (int [3]){1}; we need to set array size 445990075Sobrien now since later on array initializer will be just the 446090075Sobrien brace enclosed list of the compound literal. */ 446190075Sobrien TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl)); 446290075Sobrien layout_type (type); 446390075Sobrien layout_decl (decl, 0); 446490075Sobrien } 446590075Sobrien } 446690075Sobrien } 446718334Speter} 446818334Speter 446918334Speter/* Methods for storing and printing names for error messages. */ 447018334Speter 447118334Speter/* Implement a spelling stack that allows components of a name to be pushed 447218334Speter and popped. Each element on the stack is this structure. */ 447318334Speter 447418334Speterstruct spelling 447518334Speter{ 447618334Speter int kind; 447718334Speter union 447818334Speter { 447918334Speter int i; 448052284Sobrien const char *s; 448118334Speter } u; 448218334Speter}; 448318334Speter 448418334Speter#define SPELLING_STRING 1 448518334Speter#define SPELLING_MEMBER 2 448618334Speter#define SPELLING_BOUNDS 3 448718334Speter 448818334Speterstatic struct spelling *spelling; /* Next stack element (unused). */ 448918334Speterstatic struct spelling *spelling_base; /* Spelling stack base. */ 449018334Speterstatic int spelling_size; /* Size of the spelling stack. */ 449118334Speter 449218334Speter/* Macros to save and restore the spelling stack around push_... functions. 449318334Speter Alternative to SAVE_SPELLING_STACK. */ 449418334Speter 449518334Speter#define SPELLING_DEPTH() (spelling - spelling_base) 449690075Sobrien#define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH)) 449718334Speter 449818334Speter/* Save and restore the spelling stack around arbitrary C code. */ 449918334Speter 450018334Speter#define SAVE_SPELLING_DEPTH(code) \ 450118334Speter{ \ 450218334Speter int __depth = SPELLING_DEPTH (); \ 450318334Speter code; \ 450418334Speter RESTORE_SPELLING_DEPTH (__depth); \ 450518334Speter} 450618334Speter 450718334Speter/* Push an element on the spelling stack with type KIND and assign VALUE 450818334Speter to MEMBER. */ 450918334Speter 451018334Speter#define PUSH_SPELLING(KIND, VALUE, MEMBER) \ 451118334Speter{ \ 451218334Speter int depth = SPELLING_DEPTH (); \ 451318334Speter \ 451418334Speter if (depth >= spelling_size) \ 451518334Speter { \ 451618334Speter spelling_size += 10; \ 451718334Speter if (spelling_base == 0) \ 451818334Speter spelling_base \ 451918334Speter = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling)); \ 452018334Speter else \ 452118334Speter spelling_base \ 452218334Speter = (struct spelling *) xrealloc (spelling_base, \ 452318334Speter spelling_size * sizeof (struct spelling)); \ 452418334Speter RESTORE_SPELLING_DEPTH (depth); \ 452518334Speter } \ 452618334Speter \ 452718334Speter spelling->kind = (KIND); \ 452818334Speter spelling->MEMBER = (VALUE); \ 452918334Speter spelling++; \ 453018334Speter} 453118334Speter 453218334Speter/* Push STRING on the stack. Printed literally. */ 453318334Speter 453418334Speterstatic void 453518334Speterpush_string (string) 453652284Sobrien const char *string; 453718334Speter{ 453818334Speter PUSH_SPELLING (SPELLING_STRING, string, u.s); 453918334Speter} 454018334Speter 454118334Speter/* Push a member name on the stack. Printed as '.' STRING. */ 454218334Speter 454318334Speterstatic void 454418334Speterpush_member_name (decl) 454518334Speter tree decl; 454618334Speter 454718334Speter{ 454890075Sobrien const char *const string 454918334Speter = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>"; 455018334Speter PUSH_SPELLING (SPELLING_MEMBER, string, u.s); 455118334Speter} 455218334Speter 455318334Speter/* Push an array bounds on the stack. Printed as [BOUNDS]. */ 455418334Speter 455518334Speterstatic void 455618334Speterpush_array_bounds (bounds) 455718334Speter int bounds; 455818334Speter{ 455918334Speter PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i); 456018334Speter} 456118334Speter 456218334Speter/* Compute the maximum size in bytes of the printed spelling. */ 456318334Speter 456418334Speterstatic int 456518334Speterspelling_length () 456618334Speter{ 456790075Sobrien int size = 0; 456890075Sobrien struct spelling *p; 456918334Speter 457018334Speter for (p = spelling_base; p < spelling; p++) 457118334Speter { 457218334Speter if (p->kind == SPELLING_BOUNDS) 457318334Speter size += 25; 457418334Speter else 457518334Speter size += strlen (p->u.s) + 1; 457618334Speter } 457718334Speter 457818334Speter return size; 457918334Speter} 458018334Speter 458118334Speter/* Print the spelling to BUFFER and return it. */ 458218334Speter 458318334Speterstatic char * 458418334Speterprint_spelling (buffer) 458590075Sobrien char *buffer; 458618334Speter{ 458790075Sobrien char *d = buffer; 458890075Sobrien struct spelling *p; 458918334Speter 459018334Speter for (p = spelling_base; p < spelling; p++) 459118334Speter if (p->kind == SPELLING_BOUNDS) 459218334Speter { 459318334Speter sprintf (d, "[%d]", p->u.i); 459418334Speter d += strlen (d); 459518334Speter } 459618334Speter else 459718334Speter { 459890075Sobrien const char *s; 459918334Speter if (p->kind == SPELLING_MEMBER) 460018334Speter *d++ = '.'; 460150397Sobrien for (s = p->u.s; (*d = *s++); d++) 460218334Speter ; 460318334Speter } 460418334Speter *d++ = '\0'; 460518334Speter return buffer; 460618334Speter} 460718334Speter 460818334Speter/* Issue an error message for a bad initializer component. 460952284Sobrien MSGID identifies the message. 461052284Sobrien The component name is taken from the spelling stack. */ 461118334Speter 461218334Spetervoid 461352284Sobrienerror_init (msgid) 461452284Sobrien const char *msgid; 461518334Speter{ 461652284Sobrien char *ofwhat; 461718334Speter 461890075Sobrien error ("%s", _(msgid)); 461952284Sobrien ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); 462018334Speter if (*ofwhat) 462152284Sobrien error ("(near initialization for `%s')", ofwhat); 462218334Speter} 462318334Speter 462418334Speter/* Issue a pedantic warning for a bad initializer component. 462552284Sobrien MSGID identifies the message. 462652284Sobrien The component name is taken from the spelling stack. */ 462718334Speter 462818334Spetervoid 462952284Sobrienpedwarn_init (msgid) 463052284Sobrien const char *msgid; 463118334Speter{ 463252284Sobrien char *ofwhat; 463318334Speter 463490075Sobrien pedwarn ("%s", _(msgid)); 463552284Sobrien ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); 463618334Speter if (*ofwhat) 463752284Sobrien pedwarn ("(near initialization for `%s')", ofwhat); 463818334Speter} 463918334Speter 464018334Speter/* Issue a warning for a bad initializer component. 464152284Sobrien MSGID identifies the message. 464252284Sobrien The component name is taken from the spelling stack. */ 464318334Speter 464418334Speterstatic void 464552284Sobrienwarning_init (msgid) 464652284Sobrien const char *msgid; 464718334Speter{ 464852284Sobrien char *ofwhat; 464918334Speter 465090075Sobrien warning ("%s", _(msgid)); 465152284Sobrien ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); 465218334Speter if (*ofwhat) 465352284Sobrien warning ("(near initialization for `%s')", ofwhat); 465418334Speter} 465518334Speter 465618334Speter/* Digest the parser output INIT as an initializer for type TYPE. 465718334Speter Return a C expression of type TYPE to represent the initial value. 465818334Speter 465918334Speter The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors 466018334Speter if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT 466118334Speter applies only to elements of constructors. */ 466218334Speter 466318334Speterstatic tree 466418334Speterdigest_init (type, init, require_constant, constructor_constant) 466518334Speter tree type, init; 466618334Speter int require_constant, constructor_constant; 466718334Speter{ 466818334Speter enum tree_code code = TREE_CODE (type); 466918334Speter tree inside_init = init; 467018334Speter 467190075Sobrien if (type == error_mark_node 467290075Sobrien || init == error_mark_node 467390075Sobrien || TREE_TYPE (init) == error_mark_node) 467490075Sobrien return error_mark_node; 467518334Speter 467618334Speter /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ 467718334Speter /* Do not use STRIP_NOPS here. We do not want an enumerator 467818334Speter whose value is 0 to count as a null pointer constant. */ 467918334Speter if (TREE_CODE (init) == NON_LVALUE_EXPR) 468018334Speter inside_init = TREE_OPERAND (init, 0); 468118334Speter 468290075Sobrien inside_init = fold (inside_init); 468390075Sobrien 468418334Speter /* Initialization of an array of chars from a string constant 468518334Speter optionally enclosed in braces. */ 468618334Speter 468718334Speter if (code == ARRAY_TYPE) 468818334Speter { 468918334Speter tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 469018334Speter if ((typ1 == char_type_node 469118334Speter || typ1 == signed_char_type_node 469218334Speter || typ1 == unsigned_char_type_node 469318334Speter || typ1 == unsigned_wchar_type_node 469418334Speter || typ1 == signed_wchar_type_node) 469518334Speter && ((inside_init && TREE_CODE (inside_init) == STRING_CST))) 469618334Speter { 469718334Speter if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), 469818334Speter TYPE_MAIN_VARIANT (type))) 469918334Speter return inside_init; 470018334Speter 470118334Speter if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) 470218334Speter != char_type_node) 470318334Speter && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) 470418334Speter { 470552284Sobrien error_init ("char-array initialized from wide string"); 470618334Speter return error_mark_node; 470718334Speter } 470818334Speter if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) 470918334Speter == char_type_node) 471018334Speter && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) 471118334Speter { 471252284Sobrien error_init ("int-array initialized from non-wide string"); 471318334Speter return error_mark_node; 471418334Speter } 471518334Speter 471618334Speter TREE_TYPE (inside_init) = type; 471718334Speter if (TYPE_DOMAIN (type) != 0 471890075Sobrien && TYPE_SIZE (type) != 0 471990075Sobrien && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST 472018334Speter /* Subtract 1 (or sizeof (wchar_t)) 472118334Speter because it's ok to ignore the terminating null char 472218334Speter that is counted in the length of the constant. */ 472390075Sobrien && 0 > compare_tree_int (TYPE_SIZE_UNIT (type), 472490075Sobrien TREE_STRING_LENGTH (inside_init) 472590075Sobrien - ((TYPE_PRECISION (typ1) 472690075Sobrien != TYPE_PRECISION (char_type_node)) 472790075Sobrien ? (TYPE_PRECISION (wchar_type_node) 472890075Sobrien / BITS_PER_UNIT) 472990075Sobrien : 1))) 473090075Sobrien pedwarn_init ("initializer-string for array of chars is too long"); 473190075Sobrien 473218334Speter return inside_init; 473318334Speter } 473418334Speter } 473518334Speter 473618334Speter /* Any type can be initialized 473718334Speter from an expression of the same type, optionally with braces. */ 473818334Speter 473918334Speter if (inside_init && TREE_TYPE (inside_init) != 0 474018334Speter && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)), 474118334Speter TYPE_MAIN_VARIANT (type)) 474218334Speter || (code == ARRAY_TYPE 474318334Speter && comptypes (TREE_TYPE (inside_init), type)) 474496263Sobrien || (code == VECTOR_TYPE 474596263Sobrien && comptypes (TREE_TYPE (inside_init), type)) 474618334Speter || (code == POINTER_TYPE 474718334Speter && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE 474818334Speter || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE) 474918334Speter && comptypes (TREE_TYPE (TREE_TYPE (inside_init)), 475018334Speter TREE_TYPE (type))))) 475118334Speter { 475290075Sobrien if (code == POINTER_TYPE) 475390075Sobrien inside_init = default_function_array_conversion (inside_init); 475490075Sobrien 475590075Sobrien if (require_constant && !flag_isoc99 475690075Sobrien && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR) 475718334Speter { 475890075Sobrien /* As an extension, allow initializing objects with static storage 475990075Sobrien duration with compound literals (which are then treated just as 476090075Sobrien the brace enclosed list they contain). */ 476190075Sobrien tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init); 476290075Sobrien inside_init = DECL_INITIAL (decl); 476390075Sobrien } 476490075Sobrien 476590075Sobrien if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST 476690075Sobrien && TREE_CODE (inside_init) != CONSTRUCTOR) 476790075Sobrien { 476852284Sobrien error_init ("array initialized from non-constant array expression"); 476918334Speter return error_mark_node; 477018334Speter } 477118334Speter 477218334Speter if (optimize && TREE_CODE (inside_init) == VAR_DECL) 477390075Sobrien inside_init = decl_constant_value_for_broken_optimization (inside_init); 477418334Speter 477518334Speter /* Compound expressions can only occur here if -pedantic or 477618334Speter -pedantic-errors is specified. In the later case, we always want 477718334Speter an error. In the former case, we simply want a warning. */ 477818334Speter if (require_constant && pedantic 477918334Speter && TREE_CODE (inside_init) == COMPOUND_EXPR) 478018334Speter { 478118334Speter inside_init 478218334Speter = valid_compound_expr_initializer (inside_init, 478318334Speter TREE_TYPE (inside_init)); 478418334Speter if (inside_init == error_mark_node) 478552284Sobrien error_init ("initializer element is not constant"); 478618334Speter else 478752284Sobrien pedwarn_init ("initializer element is not constant"); 478818334Speter if (flag_pedantic_errors) 478918334Speter inside_init = error_mark_node; 479018334Speter } 479190075Sobrien else if (require_constant 479290075Sobrien && (!TREE_CONSTANT (inside_init) 479390075Sobrien /* This test catches things like `7 / 0' which 479490075Sobrien result in an expression for which TREE_CONSTANT 479590075Sobrien is true, but which is not actually something 479690075Sobrien that is a legal constant. We really should not 479790075Sobrien be using this function, because it is a part of 479890075Sobrien the back-end. Instead, the expression should 479990075Sobrien already have been turned into ERROR_MARK_NODE. */ 480090075Sobrien || !initializer_constant_valid_p (inside_init, 480190075Sobrien TREE_TYPE (inside_init)))) 480218334Speter { 480352284Sobrien error_init ("initializer element is not constant"); 480418334Speter inside_init = error_mark_node; 480518334Speter } 480618334Speter 480718334Speter return inside_init; 480818334Speter } 480918334Speter 481018334Speter /* Handle scalar types, including conversions. */ 481118334Speter 481218334Speter if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE 481390075Sobrien || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE) 481418334Speter { 481518334Speter /* Note that convert_for_assignment calls default_conversion 481618334Speter for arrays and functions. We must not call it in the 481718334Speter case where inside_init is a null pointer constant. */ 481818334Speter inside_init 481952284Sobrien = convert_for_assignment (type, init, _("initialization"), 482018334Speter NULL_TREE, NULL_TREE, 0); 482118334Speter 482218334Speter if (require_constant && ! TREE_CONSTANT (inside_init)) 482318334Speter { 482452284Sobrien error_init ("initializer element is not constant"); 482518334Speter inside_init = error_mark_node; 482618334Speter } 482718334Speter else if (require_constant 482818334Speter && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) 482918334Speter { 483052284Sobrien error_init ("initializer element is not computable at load time"); 483118334Speter inside_init = error_mark_node; 483218334Speter } 483318334Speter 483418334Speter return inside_init; 483518334Speter } 483618334Speter 483718334Speter /* Come here only for records and arrays. */ 483818334Speter 483990075Sobrien if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 484018334Speter { 484152284Sobrien error_init ("variable-sized object may not be initialized"); 484218334Speter return error_mark_node; 484318334Speter } 484418334Speter 484518334Speter /* Traditionally, you can write struct foo x = 0; 484618334Speter and it initializes the first element of x to 0. */ 484718334Speter if (flag_traditional) 484818334Speter { 484918334Speter tree top = 0, prev = 0, otype = type; 485018334Speter while (TREE_CODE (type) == RECORD_TYPE 485118334Speter || TREE_CODE (type) == ARRAY_TYPE 485218334Speter || TREE_CODE (type) == QUAL_UNION_TYPE 485318334Speter || TREE_CODE (type) == UNION_TYPE) 485418334Speter { 485518334Speter tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); 485618334Speter if (prev == 0) 485718334Speter top = temp; 485818334Speter else 485918334Speter TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp); 486018334Speter prev = temp; 486118334Speter if (TREE_CODE (type) == ARRAY_TYPE) 486218334Speter type = TREE_TYPE (type); 486318334Speter else if (TYPE_FIELDS (type)) 486418334Speter type = TREE_TYPE (TYPE_FIELDS (type)); 486518334Speter else 486618334Speter { 486752284Sobrien error_init ("invalid initializer"); 486818334Speter return error_mark_node; 486918334Speter } 487018334Speter } 487118334Speter 487218334Speter if (otype != type) 487318334Speter { 487418334Speter TREE_OPERAND (prev, 1) 487518334Speter = build_tree_list (NULL_TREE, 487618334Speter digest_init (type, init, require_constant, 487718334Speter constructor_constant)); 487818334Speter return top; 487918334Speter } 488018334Speter else 488118334Speter return error_mark_node; 488218334Speter } 488352284Sobrien error_init ("invalid initializer"); 488418334Speter return error_mark_node; 488518334Speter} 488618334Speter 488718334Speter/* Handle initializers that use braces. */ 488818334Speter 488918334Speter/* Type of object we are accumulating a constructor for. 489018334Speter This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE. */ 489118334Speterstatic tree constructor_type; 489218334Speter 489318334Speter/* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields 489418334Speter left to fill. */ 489518334Speterstatic tree constructor_fields; 489618334Speter 489718334Speter/* For an ARRAY_TYPE, this is the specified index 489890075Sobrien at which to store the next element we get. */ 489918334Speterstatic tree constructor_index; 490018334Speter 490118334Speter/* For an ARRAY_TYPE, this is the maximum index. */ 490218334Speterstatic tree constructor_max_index; 490318334Speter 490418334Speter/* For a RECORD_TYPE, this is the first field not yet written out. */ 490518334Speterstatic tree constructor_unfilled_fields; 490618334Speter 490718334Speter/* For an ARRAY_TYPE, this is the index of the first element 490890075Sobrien not yet written out. */ 490918334Speterstatic tree constructor_unfilled_index; 491018334Speter 491118334Speter/* In a RECORD_TYPE, the byte index of the next consecutive field. 491290075Sobrien This is so we can generate gaps between fields, when appropriate. */ 491318334Speterstatic tree constructor_bit_index; 491418334Speter 491518334Speter/* If we are saving up the elements rather than allocating them, 491618334Speter this is the list of elements so far (in reverse order, 491718334Speter most recent first). */ 491818334Speterstatic tree constructor_elements; 491918334Speter 492090075Sobrien/* 1 if constructor should be incrementally stored into a constructor chain, 492190075Sobrien 0 if all the elements should be kept in AVL tree. */ 492290075Sobrienstatic int constructor_incremental; 492390075Sobrien 492418334Speter/* 1 if so far this constructor's elements are all compile-time constants. */ 492518334Speterstatic int constructor_constant; 492618334Speter 492718334Speter/* 1 if so far this constructor's elements are all valid address constants. */ 492818334Speterstatic int constructor_simple; 492918334Speter 493018334Speter/* 1 if this constructor is erroneous so far. */ 493118334Speterstatic int constructor_erroneous; 493218334Speter 493318334Speter/* 1 if have called defer_addressed_constants. */ 493418334Speterstatic int constructor_subconstants_deferred; 493518334Speter 493650397Sobrien/* Structure for managing pending initializer elements, organized as an 493750397Sobrien AVL tree. */ 493850397Sobrien 493950397Sobrienstruct init_node 494050397Sobrien{ 494150397Sobrien struct init_node *left, *right; 494250397Sobrien struct init_node *parent; 494350397Sobrien int balance; 494450397Sobrien tree purpose; 494550397Sobrien tree value; 494650397Sobrien}; 494750397Sobrien 494850397Sobrien/* Tree of pending elements at this constructor level. 494918334Speter These are elements encountered out of order 495018334Speter which belong at places we haven't reached yet in actually 495190075Sobrien writing the output. 495290075Sobrien Will never hold tree nodes across GC runs. */ 495350397Sobrienstatic struct init_node *constructor_pending_elts; 495418334Speter 495518334Speter/* The SPELLING_DEPTH of this constructor. */ 495618334Speterstatic int constructor_depth; 495718334Speter 495818334Speter/* 0 if implicitly pushing constructor levels is allowed. */ 495950397Sobrienint constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */ 496018334Speter 496118334Speterstatic int require_constant_value; 496218334Speterstatic int require_constant_elements; 496318334Speter 496418334Speter/* DECL node for which an initializer is being read. 496518334Speter 0 means we are reading a constructor expression 496618334Speter such as (struct foo) {...}. */ 496718334Speterstatic tree constructor_decl; 496818334Speter 496918334Speter/* start_init saves the ASMSPEC arg here for really_start_incremental_init. */ 497090075Sobrienstatic const char *constructor_asmspec; 497118334Speter 497218334Speter/* Nonzero if this is an initializer for a top-level decl. */ 497318334Speterstatic int constructor_top_level; 497418334Speter 497590075Sobrien/* Nonzero if there were any member designators in this initializer. */ 497690075Sobrienstatic int constructor_designated; 497790075Sobrien 497890075Sobrien/* Nesting depth of designator list. */ 497990075Sobrienstatic int designator_depth; 498090075Sobrien 498190075Sobrien/* Nonzero if there were diagnosed errors in this designator list. */ 498290075Sobrienstatic int designator_errorneous; 498390075Sobrien 498418334Speter 498518334Speter/* This stack has a level for each implicit or explicit level of 498618334Speter structuring in the initializer, including the outermost one. It 498718334Speter saves the values of most of the variables above. */ 498818334Speter 498990075Sobrienstruct constructor_range_stack; 499090075Sobrien 499118334Speterstruct constructor_stack 499218334Speter{ 499318334Speter struct constructor_stack *next; 499418334Speter tree type; 499518334Speter tree fields; 499618334Speter tree index; 499718334Speter tree max_index; 499818334Speter tree unfilled_index; 499918334Speter tree unfilled_fields; 500018334Speter tree bit_index; 500118334Speter tree elements; 500290075Sobrien struct init_node *pending_elts; 500318334Speter int offset; 500418334Speter int depth; 500518334Speter /* If nonzero, this value should replace the entire 500618334Speter constructor at this level. */ 500718334Speter tree replacement_value; 500890075Sobrien struct constructor_range_stack *range_stack; 500918334Speter char constant; 501018334Speter char simple; 501118334Speter char implicit; 501218334Speter char erroneous; 501318334Speter char outer; 501490075Sobrien char incremental; 501590075Sobrien char designated; 501618334Speter}; 501718334Speter 501818334Speterstruct constructor_stack *constructor_stack; 501918334Speter 502090075Sobrien/* This stack represents designators from some range designator up to 502190075Sobrien the last designator in the list. */ 502290075Sobrien 502390075Sobrienstruct constructor_range_stack 502490075Sobrien{ 502590075Sobrien struct constructor_range_stack *next, *prev; 502690075Sobrien struct constructor_stack *stack; 502790075Sobrien tree range_start; 502890075Sobrien tree index; 502990075Sobrien tree range_end; 503090075Sobrien tree fields; 503190075Sobrien}; 503290075Sobrien 503390075Sobrienstruct constructor_range_stack *constructor_range_stack; 503490075Sobrien 503518334Speter/* This stack records separate initializers that are nested. 503618334Speter Nested initializers can't happen in ANSI C, but GNU C allows them 503718334Speter in cases like { ... (struct foo) { ... } ... }. */ 503818334Speter 503918334Speterstruct initializer_stack 504018334Speter{ 504118334Speter struct initializer_stack *next; 504218334Speter tree decl; 504390075Sobrien const char *asmspec; 504418334Speter struct constructor_stack *constructor_stack; 504590075Sobrien struct constructor_range_stack *constructor_range_stack; 504618334Speter tree elements; 504718334Speter struct spelling *spelling; 504818334Speter struct spelling *spelling_base; 504918334Speter int spelling_size; 505018334Speter char top_level; 505118334Speter char require_constant_value; 505218334Speter char require_constant_elements; 505318334Speter char deferred; 505418334Speter}; 505518334Speter 505618334Speterstruct initializer_stack *initializer_stack; 505718334Speter 505818334Speter/* Prepare to parse and output the initializer for variable DECL. */ 505918334Speter 506018334Spetervoid 506118334Speterstart_init (decl, asmspec_tree, top_level) 506218334Speter tree decl; 506318334Speter tree asmspec_tree; 506418334Speter int top_level; 506518334Speter{ 506652284Sobrien const char *locus; 506718334Speter struct initializer_stack *p 506818334Speter = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack)); 506990075Sobrien const char *asmspec = 0; 507018334Speter 507118334Speter if (asmspec_tree) 507218334Speter asmspec = TREE_STRING_POINTER (asmspec_tree); 507318334Speter 507418334Speter p->decl = constructor_decl; 507518334Speter p->asmspec = constructor_asmspec; 507618334Speter p->require_constant_value = require_constant_value; 507718334Speter p->require_constant_elements = require_constant_elements; 507818334Speter p->constructor_stack = constructor_stack; 507990075Sobrien p->constructor_range_stack = constructor_range_stack; 508018334Speter p->elements = constructor_elements; 508118334Speter p->spelling = spelling; 508218334Speter p->spelling_base = spelling_base; 508318334Speter p->spelling_size = spelling_size; 508418334Speter p->deferred = constructor_subconstants_deferred; 508518334Speter p->top_level = constructor_top_level; 508618334Speter p->next = initializer_stack; 508718334Speter initializer_stack = p; 508818334Speter 508918334Speter constructor_decl = decl; 509018334Speter constructor_asmspec = asmspec; 509118334Speter constructor_subconstants_deferred = 0; 509290075Sobrien constructor_designated = 0; 509318334Speter constructor_top_level = top_level; 509418334Speter 509518334Speter if (decl != 0) 509618334Speter { 509718334Speter require_constant_value = TREE_STATIC (decl); 509818334Speter require_constant_elements 509990075Sobrien = ((TREE_STATIC (decl) || (pedantic && !flag_isoc99)) 510018334Speter /* For a scalar, you can always use any value to initialize, 510118334Speter even within braces. */ 510218334Speter && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE 510318334Speter || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE 510418334Speter || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE 510518334Speter || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE)); 510618334Speter locus = IDENTIFIER_POINTER (DECL_NAME (decl)); 510718334Speter } 510818334Speter else 510918334Speter { 511018334Speter require_constant_value = 0; 511118334Speter require_constant_elements = 0; 511218334Speter locus = "(anonymous)"; 511318334Speter } 511418334Speter 511518334Speter constructor_stack = 0; 511690075Sobrien constructor_range_stack = 0; 511718334Speter 511818334Speter missing_braces_mentioned = 0; 511918334Speter 512018334Speter spelling_base = 0; 512118334Speter spelling_size = 0; 512218334Speter RESTORE_SPELLING_DEPTH (0); 512318334Speter 512418334Speter if (locus) 512518334Speter push_string (locus); 512618334Speter} 512718334Speter 512818334Spetervoid 512918334Speterfinish_init () 513018334Speter{ 513118334Speter struct initializer_stack *p = initializer_stack; 513218334Speter 513318334Speter /* Output subconstants (string constants, usually) 513418334Speter that were referenced within this initializer and saved up. 513518334Speter Must do this if and only if we called defer_addressed_constants. */ 513618334Speter if (constructor_subconstants_deferred) 513718334Speter output_deferred_addressed_constants (); 513818334Speter 513918334Speter /* Free the whole constructor stack of this initializer. */ 514018334Speter while (constructor_stack) 514118334Speter { 514218334Speter struct constructor_stack *q = constructor_stack; 514318334Speter constructor_stack = q->next; 514418334Speter free (q); 514518334Speter } 514618334Speter 514790075Sobrien if (constructor_range_stack) 514890075Sobrien abort (); 514990075Sobrien 515018334Speter /* Pop back to the data of the outer initializer (if any). */ 515118334Speter constructor_decl = p->decl; 515218334Speter constructor_asmspec = p->asmspec; 515318334Speter require_constant_value = p->require_constant_value; 515418334Speter require_constant_elements = p->require_constant_elements; 515518334Speter constructor_stack = p->constructor_stack; 515690075Sobrien constructor_range_stack = p->constructor_range_stack; 515718334Speter constructor_elements = p->elements; 515818334Speter spelling = p->spelling; 515918334Speter spelling_base = p->spelling_base; 516018334Speter spelling_size = p->spelling_size; 516118334Speter constructor_subconstants_deferred = p->deferred; 516218334Speter constructor_top_level = p->top_level; 516318334Speter initializer_stack = p->next; 516418334Speter free (p); 516518334Speter} 516618334Speter 516718334Speter/* Call here when we see the initializer is surrounded by braces. 516818334Speter This is instead of a call to push_init_level; 516918334Speter it is matched by a call to pop_init_level. 517018334Speter 517118334Speter TYPE is the type to initialize, for a constructor expression. 517218334Speter For an initializer for a decl, TYPE is zero. */ 517318334Speter 517418334Spetervoid 517518334Speterreally_start_incremental_init (type) 517618334Speter tree type; 517718334Speter{ 517818334Speter struct constructor_stack *p 517918334Speter = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); 518018334Speter 518118334Speter if (type == 0) 518218334Speter type = TREE_TYPE (constructor_decl); 518318334Speter 518418334Speter p->type = constructor_type; 518518334Speter p->fields = constructor_fields; 518618334Speter p->index = constructor_index; 518718334Speter p->max_index = constructor_max_index; 518818334Speter p->unfilled_index = constructor_unfilled_index; 518918334Speter p->unfilled_fields = constructor_unfilled_fields; 519018334Speter p->bit_index = constructor_bit_index; 519118334Speter p->elements = constructor_elements; 519218334Speter p->constant = constructor_constant; 519318334Speter p->simple = constructor_simple; 519418334Speter p->erroneous = constructor_erroneous; 519518334Speter p->pending_elts = constructor_pending_elts; 519618334Speter p->depth = constructor_depth; 519718334Speter p->replacement_value = 0; 519818334Speter p->implicit = 0; 519990075Sobrien p->range_stack = 0; 520090075Sobrien p->outer = 0; 520118334Speter p->incremental = constructor_incremental; 520290075Sobrien p->designated = constructor_designated; 520318334Speter p->next = 0; 520418334Speter constructor_stack = p; 520518334Speter 520618334Speter constructor_constant = 1; 520718334Speter constructor_simple = 1; 520818334Speter constructor_depth = SPELLING_DEPTH (); 520918334Speter constructor_elements = 0; 521018334Speter constructor_pending_elts = 0; 521118334Speter constructor_type = type; 521290075Sobrien constructor_incremental = 1; 521390075Sobrien constructor_designated = 0; 521490075Sobrien designator_depth = 0; 521590075Sobrien designator_errorneous = 0; 521618334Speter 521718334Speter if (TREE_CODE (constructor_type) == RECORD_TYPE 521818334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 521918334Speter { 522018334Speter constructor_fields = TYPE_FIELDS (constructor_type); 522118334Speter /* Skip any nameless bit fields at the beginning. */ 522250397Sobrien while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields) 522318334Speter && DECL_NAME (constructor_fields) == 0) 522418334Speter constructor_fields = TREE_CHAIN (constructor_fields); 522590075Sobrien 522618334Speter constructor_unfilled_fields = constructor_fields; 522790075Sobrien constructor_bit_index = bitsize_zero_node; 522818334Speter } 522918334Speter else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 523018334Speter { 523118334Speter if (TYPE_DOMAIN (constructor_type)) 523218334Speter { 523318334Speter constructor_max_index 523418334Speter = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); 523590075Sobrien 523690075Sobrien /* Detect non-empty initializations of zero-length arrays. */ 523790075Sobrien if (constructor_max_index == NULL_TREE 523890075Sobrien && TYPE_SIZE (constructor_type)) 523990075Sobrien constructor_max_index = build_int_2 (-1, -1); 524090075Sobrien 524190075Sobrien /* constructor_max_index needs to be an INTEGER_CST. Attempts 524290075Sobrien to initialize VLAs will cause an proper error; avoid tree 524390075Sobrien checking errors as well by setting a safe value. */ 524490075Sobrien if (constructor_max_index 524590075Sobrien && TREE_CODE (constructor_max_index) != INTEGER_CST) 524690075Sobrien constructor_max_index = build_int_2 (-1, -1); 524790075Sobrien 524818334Speter constructor_index 524990075Sobrien = convert (bitsizetype, 525090075Sobrien TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); 525118334Speter } 525218334Speter else 525390075Sobrien constructor_index = bitsize_zero_node; 525490075Sobrien 525590075Sobrien constructor_unfilled_index = constructor_index; 525618334Speter } 525796263Sobrien else if (TREE_CODE (constructor_type) == VECTOR_TYPE) 525896263Sobrien { 525996263Sobrien /* Vectors are like simple fixed-size arrays. */ 526096263Sobrien constructor_max_index = 526196263Sobrien build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0); 526296263Sobrien constructor_index = convert (bitsizetype, integer_zero_node); 526396263Sobrien constructor_unfilled_index = constructor_index; 526496263Sobrien } 526518334Speter else 526618334Speter { 526718334Speter /* Handle the case of int x = {5}; */ 526818334Speter constructor_fields = constructor_type; 526918334Speter constructor_unfilled_fields = constructor_type; 527018334Speter } 527118334Speter} 527218334Speter 527318334Speter/* Push down into a subobject, for initialization. 527418334Speter If this is for an explicit set of braces, IMPLICIT is 0. 527518334Speter If it is because the next element belongs at a lower level, 527690075Sobrien IMPLICIT is 1 (or 2 if the push is because of designator list). */ 527718334Speter 527818334Spetervoid 527918334Speterpush_init_level (implicit) 528018334Speter int implicit; 528118334Speter{ 528218334Speter struct constructor_stack *p; 528390075Sobrien tree value = NULL_TREE; 528418334Speter 528518334Speter /* If we've exhausted any levels that didn't have braces, 528618334Speter pop them now. */ 528718334Speter while (constructor_stack->implicit) 528818334Speter { 528918334Speter if ((TREE_CODE (constructor_type) == RECORD_TYPE 529018334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 529118334Speter && constructor_fields == 0) 529218334Speter process_init_element (pop_init_level (1)); 529318334Speter else if (TREE_CODE (constructor_type) == ARRAY_TYPE 529418334Speter && tree_int_cst_lt (constructor_max_index, constructor_index)) 529518334Speter process_init_element (pop_init_level (1)); 529618334Speter else 529718334Speter break; 529818334Speter } 529918334Speter 530090075Sobrien /* Unless this is an explicit brace, we need to preserve previous 530190075Sobrien content if any. */ 530290075Sobrien if (implicit) 530318334Speter { 530490075Sobrien if ((TREE_CODE (constructor_type) == RECORD_TYPE 530590075Sobrien || TREE_CODE (constructor_type) == UNION_TYPE) 530690075Sobrien && constructor_fields) 530790075Sobrien value = find_init_member (constructor_fields); 530890075Sobrien else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 530990075Sobrien value = find_init_member (constructor_index); 531018334Speter } 531118334Speter 531218334Speter p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack)); 531318334Speter p->type = constructor_type; 531418334Speter p->fields = constructor_fields; 531518334Speter p->index = constructor_index; 531618334Speter p->max_index = constructor_max_index; 531718334Speter p->unfilled_index = constructor_unfilled_index; 531818334Speter p->unfilled_fields = constructor_unfilled_fields; 531918334Speter p->bit_index = constructor_bit_index; 532018334Speter p->elements = constructor_elements; 532118334Speter p->constant = constructor_constant; 532218334Speter p->simple = constructor_simple; 532318334Speter p->erroneous = constructor_erroneous; 532418334Speter p->pending_elts = constructor_pending_elts; 532518334Speter p->depth = constructor_depth; 532618334Speter p->replacement_value = 0; 532718334Speter p->implicit = implicit; 532890075Sobrien p->outer = 0; 532918334Speter p->incremental = constructor_incremental; 533090075Sobrien p->designated = constructor_designated; 533118334Speter p->next = constructor_stack; 533290075Sobrien p->range_stack = 0; 533318334Speter constructor_stack = p; 533418334Speter 533518334Speter constructor_constant = 1; 533618334Speter constructor_simple = 1; 533718334Speter constructor_depth = SPELLING_DEPTH (); 533818334Speter constructor_elements = 0; 533990075Sobrien constructor_incremental = 1; 534090075Sobrien constructor_designated = 0; 534118334Speter constructor_pending_elts = 0; 534290075Sobrien if (!implicit) 534390075Sobrien { 534490075Sobrien p->range_stack = constructor_range_stack; 534590075Sobrien constructor_range_stack = 0; 534690075Sobrien designator_depth = 0; 534790075Sobrien designator_errorneous = 0; 534890075Sobrien } 534918334Speter 535018334Speter /* Don't die if an entire brace-pair level is superfluous 535118334Speter in the containing level. */ 535218334Speter if (constructor_type == 0) 535318334Speter ; 535418334Speter else if (TREE_CODE (constructor_type) == RECORD_TYPE 535518334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 535618334Speter { 535718334Speter /* Don't die if there are extra init elts at the end. */ 535818334Speter if (constructor_fields == 0) 535918334Speter constructor_type = 0; 536018334Speter else 536118334Speter { 536218334Speter constructor_type = TREE_TYPE (constructor_fields); 536318334Speter push_member_name (constructor_fields); 536418334Speter constructor_depth++; 536518334Speter } 536618334Speter } 536718334Speter else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 536818334Speter { 536918334Speter constructor_type = TREE_TYPE (constructor_type); 537090075Sobrien push_array_bounds (tree_low_cst (constructor_index, 0)); 537118334Speter constructor_depth++; 537218334Speter } 537318334Speter 537418334Speter if (constructor_type == 0) 537518334Speter { 537652284Sobrien error_init ("extra brace group at end of initializer"); 537718334Speter constructor_fields = 0; 537818334Speter constructor_unfilled_fields = 0; 537918334Speter return; 538018334Speter } 538118334Speter 538290075Sobrien if (value && TREE_CODE (value) == CONSTRUCTOR) 538390075Sobrien { 538490075Sobrien constructor_constant = TREE_CONSTANT (value); 538590075Sobrien constructor_simple = TREE_STATIC (value); 538690075Sobrien constructor_elements = TREE_OPERAND (value, 1); 538790075Sobrien if (constructor_elements 538890075Sobrien && (TREE_CODE (constructor_type) == RECORD_TYPE 538990075Sobrien || TREE_CODE (constructor_type) == ARRAY_TYPE)) 539090075Sobrien set_nonincremental_init (); 539190075Sobrien } 539218334Speter 539390075Sobrien if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned) 539418334Speter { 539518334Speter missing_braces_mentioned = 1; 539652284Sobrien warning_init ("missing braces around initializer"); 539718334Speter } 539818334Speter 539918334Speter if (TREE_CODE (constructor_type) == RECORD_TYPE 540018334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 540118334Speter { 540218334Speter constructor_fields = TYPE_FIELDS (constructor_type); 540318334Speter /* Skip any nameless bit fields at the beginning. */ 540450397Sobrien while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields) 540518334Speter && DECL_NAME (constructor_fields) == 0) 540618334Speter constructor_fields = TREE_CHAIN (constructor_fields); 540790075Sobrien 540818334Speter constructor_unfilled_fields = constructor_fields; 540990075Sobrien constructor_bit_index = bitsize_zero_node; 541018334Speter } 541196263Sobrien else if (TREE_CODE (constructor_type) == VECTOR_TYPE) 541296263Sobrien { 541396263Sobrien /* Vectors are like simple fixed-size arrays. */ 541496263Sobrien constructor_max_index = 541596263Sobrien build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0); 541696263Sobrien constructor_index = convert (bitsizetype, integer_zero_node); 541796263Sobrien constructor_unfilled_index = constructor_index; 541896263Sobrien } 541918334Speter else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 542018334Speter { 542118334Speter if (TYPE_DOMAIN (constructor_type)) 542218334Speter { 542318334Speter constructor_max_index 542418334Speter = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); 542590075Sobrien 542690075Sobrien /* Detect non-empty initializations of zero-length arrays. */ 542790075Sobrien if (constructor_max_index == NULL_TREE 542890075Sobrien && TYPE_SIZE (constructor_type)) 542990075Sobrien constructor_max_index = build_int_2 (-1, -1); 543090075Sobrien 543190075Sobrien /* constructor_max_index needs to be an INTEGER_CST. Attempts 543290075Sobrien to initialize VLAs will cause an proper error; avoid tree 543390075Sobrien checking errors as well by setting a safe value. */ 543490075Sobrien if (constructor_max_index 543590075Sobrien && TREE_CODE (constructor_max_index) != INTEGER_CST) 543690075Sobrien constructor_max_index = build_int_2 (-1, -1); 543790075Sobrien 543818334Speter constructor_index 543990075Sobrien = convert (bitsizetype, 544090075Sobrien TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); 544118334Speter } 544218334Speter else 544390075Sobrien constructor_index = bitsize_zero_node; 544490075Sobrien 544590075Sobrien constructor_unfilled_index = constructor_index; 544690075Sobrien if (value && TREE_CODE (value) == STRING_CST) 544790075Sobrien { 544890075Sobrien /* We need to split the char/wchar array into individual 544990075Sobrien characters, so that we don't have to special case it 545090075Sobrien everywhere. */ 545190075Sobrien set_nonincremental_init_from_string (value); 545290075Sobrien } 545318334Speter } 545418334Speter else 545518334Speter { 545652284Sobrien warning_init ("braces around scalar initializer"); 545718334Speter constructor_fields = constructor_type; 545818334Speter constructor_unfilled_fields = constructor_type; 545918334Speter } 546018334Speter} 546118334Speter 546218334Speter/* At the end of an implicit or explicit brace level, 546318334Speter finish up that level of constructor. 546418334Speter If we were outputting the elements as they are read, return 0 546518334Speter from inner levels (process_init_element ignores that), 546618334Speter but return error_mark_node from the outermost level 546718334Speter (that's what we want to put in DECL_INITIAL). 546818334Speter Otherwise, return a CONSTRUCTOR expression. */ 546918334Speter 547018334Spetertree 547118334Speterpop_init_level (implicit) 547218334Speter int implicit; 547318334Speter{ 547418334Speter struct constructor_stack *p; 547518334Speter tree constructor = 0; 547618334Speter 547718334Speter if (implicit == 0) 547818334Speter { 547918334Speter /* When we come to an explicit close brace, 548018334Speter pop any inner levels that didn't have explicit braces. */ 548118334Speter while (constructor_stack->implicit) 548218334Speter process_init_element (pop_init_level (1)); 548390075Sobrien 548490075Sobrien if (constructor_range_stack) 548590075Sobrien abort (); 548618334Speter } 548718334Speter 548818334Speter p = constructor_stack; 548918334Speter 549090075Sobrien /* Error for initializing a flexible array member, or a zero-length 549190075Sobrien array member in an inappropriate context. */ 549290075Sobrien if (constructor_type && constructor_fields 549390075Sobrien && TREE_CODE (constructor_type) == ARRAY_TYPE 549490075Sobrien && TYPE_DOMAIN (constructor_type) 549590075Sobrien && ! TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type))) 549690075Sobrien { 549790075Sobrien /* Silently discard empty initializations. The parser will 549890075Sobrien already have pedwarned for empty brackets. */ 549990075Sobrien if (integer_zerop (constructor_unfilled_index)) 550090075Sobrien constructor_type = NULL_TREE; 550190075Sobrien else if (! TYPE_SIZE (constructor_type)) 550290075Sobrien { 550390075Sobrien if (constructor_depth > 2) 550490075Sobrien error_init ("initialization of flexible array member in a nested context"); 550590075Sobrien else if (pedantic) 550690075Sobrien pedwarn_init ("initialization of a flexible array member"); 550718334Speter 550890075Sobrien /* We have already issued an error message for the existence 550990075Sobrien of a flexible array member not at the end of the structure. 551090075Sobrien Discard the initializer so that we do not abort later. */ 551190075Sobrien if (TREE_CHAIN (constructor_fields) != NULL_TREE) 551290075Sobrien constructor_type = NULL_TREE; 551390075Sobrien } 551490075Sobrien else 551590075Sobrien /* Zero-length arrays are no longer special, so we should no longer 551690075Sobrien get here. */ 551790075Sobrien abort (); 551890075Sobrien } 551990075Sobrien 552050397Sobrien /* Warn when some struct elements are implicitly initialized to zero. */ 552150397Sobrien if (extra_warnings 552250397Sobrien && constructor_type 552350397Sobrien && TREE_CODE (constructor_type) == RECORD_TYPE 552450397Sobrien && constructor_unfilled_fields) 552550397Sobrien { 552690075Sobrien /* Do not warn for flexible array members or zero-length arrays. */ 552790075Sobrien while (constructor_unfilled_fields 552890075Sobrien && (! DECL_SIZE (constructor_unfilled_fields) 552990075Sobrien || integer_zerop (DECL_SIZE (constructor_unfilled_fields)))) 553090075Sobrien constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); 553190075Sobrien 553290075Sobrien /* Do not warn if this level of the initializer uses member 553390075Sobrien designators; it is likely to be deliberate. */ 553490075Sobrien if (constructor_unfilled_fields && !constructor_designated) 553590075Sobrien { 553690075Sobrien push_member_name (constructor_unfilled_fields); 553790075Sobrien warning_init ("missing initializer"); 553890075Sobrien RESTORE_SPELLING_DEPTH (constructor_depth); 553990075Sobrien } 554050397Sobrien } 554150397Sobrien 554218334Speter /* Now output all pending elements. */ 554390075Sobrien constructor_incremental = 1; 554418334Speter output_pending_init_elements (1); 554518334Speter 554618334Speter /* Pad out the end of the structure. */ 554718334Speter if (p->replacement_value) 554890075Sobrien /* If this closes a superfluous brace pair, 554990075Sobrien just pass out the element between them. */ 555090075Sobrien constructor = p->replacement_value; 555118334Speter else if (constructor_type == 0) 555218334Speter ; 555318334Speter else if (TREE_CODE (constructor_type) != RECORD_TYPE 555418334Speter && TREE_CODE (constructor_type) != UNION_TYPE 555596263Sobrien && TREE_CODE (constructor_type) != ARRAY_TYPE 555696263Sobrien && TREE_CODE (constructor_type) != VECTOR_TYPE) 555718334Speter { 555818334Speter /* A nonincremental scalar initializer--just return 555918334Speter the element, after verifying there is just one. */ 556018334Speter if (constructor_elements == 0) 556118334Speter { 556290075Sobrien if (!constructor_erroneous) 556390075Sobrien error_init ("empty scalar initializer"); 556418334Speter constructor = error_mark_node; 556518334Speter } 556618334Speter else if (TREE_CHAIN (constructor_elements) != 0) 556718334Speter { 556852284Sobrien error_init ("extra elements in scalar initializer"); 556918334Speter constructor = TREE_VALUE (constructor_elements); 557018334Speter } 557118334Speter else 557218334Speter constructor = TREE_VALUE (constructor_elements); 557318334Speter } 557490075Sobrien else 557518334Speter { 557618334Speter if (constructor_erroneous) 557718334Speter constructor = error_mark_node; 557818334Speter else 557918334Speter { 558018334Speter constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE, 558118334Speter nreverse (constructor_elements)); 558218334Speter if (constructor_constant) 558318334Speter TREE_CONSTANT (constructor) = 1; 558418334Speter if (constructor_constant && constructor_simple) 558518334Speter TREE_STATIC (constructor) = 1; 558618334Speter } 558718334Speter } 558818334Speter 558918334Speter constructor_type = p->type; 559018334Speter constructor_fields = p->fields; 559118334Speter constructor_index = p->index; 559218334Speter constructor_max_index = p->max_index; 559318334Speter constructor_unfilled_index = p->unfilled_index; 559418334Speter constructor_unfilled_fields = p->unfilled_fields; 559518334Speter constructor_bit_index = p->bit_index; 559618334Speter constructor_elements = p->elements; 559718334Speter constructor_constant = p->constant; 559818334Speter constructor_simple = p->simple; 559918334Speter constructor_erroneous = p->erroneous; 560090075Sobrien constructor_incremental = p->incremental; 560190075Sobrien constructor_designated = p->designated; 560218334Speter constructor_pending_elts = p->pending_elts; 560318334Speter constructor_depth = p->depth; 560490075Sobrien if (!p->implicit) 560590075Sobrien constructor_range_stack = p->range_stack; 560618334Speter RESTORE_SPELLING_DEPTH (constructor_depth); 560718334Speter 560818334Speter constructor_stack = p->next; 560918334Speter free (p); 561018334Speter 561118334Speter if (constructor == 0) 561218334Speter { 561318334Speter if (constructor_stack == 0) 561418334Speter return error_mark_node; 561518334Speter return NULL_TREE; 561618334Speter } 561718334Speter return constructor; 561818334Speter} 561918334Speter 562090075Sobrien/* Common handling for both array range and field name designators. 562190075Sobrien ARRAY argument is non-zero for array ranges. Returns zero for success. */ 562290075Sobrien 562390075Sobrienstatic int 562490075Sobrienset_designator (array) 562590075Sobrien int array; 562690075Sobrien{ 562790075Sobrien tree subtype; 562890075Sobrien enum tree_code subcode; 562990075Sobrien 563090075Sobrien /* Don't die if an entire brace-pair level is superfluous 563190075Sobrien in the containing level. */ 563290075Sobrien if (constructor_type == 0) 563390075Sobrien return 1; 563490075Sobrien 563590075Sobrien /* If there were errors in this designator list already, bail out silently. */ 563690075Sobrien if (designator_errorneous) 563790075Sobrien return 1; 563890075Sobrien 563990075Sobrien if (!designator_depth) 564090075Sobrien { 564190075Sobrien if (constructor_range_stack) 564290075Sobrien abort (); 564390075Sobrien 564490075Sobrien /* Designator list starts at the level of closest explicit 564590075Sobrien braces. */ 564690075Sobrien while (constructor_stack->implicit) 564790075Sobrien process_init_element (pop_init_level (1)); 564890075Sobrien constructor_designated = 1; 564990075Sobrien return 0; 565090075Sobrien } 565190075Sobrien 565290075Sobrien if (constructor_no_implicit) 565390075Sobrien { 565490075Sobrien error_init ("initialization designators may not nest"); 565590075Sobrien return 1; 565690075Sobrien } 565790075Sobrien 565890075Sobrien if (TREE_CODE (constructor_type) == RECORD_TYPE 565990075Sobrien || TREE_CODE (constructor_type) == UNION_TYPE) 566090075Sobrien { 566190075Sobrien subtype = TREE_TYPE (constructor_fields); 566290075Sobrien if (subtype != error_mark_node) 566390075Sobrien subtype = TYPE_MAIN_VARIANT (subtype); 566490075Sobrien } 566590075Sobrien else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 566690075Sobrien { 566790075Sobrien subtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); 566890075Sobrien } 566990075Sobrien else 567090075Sobrien abort (); 567190075Sobrien 567290075Sobrien subcode = TREE_CODE (subtype); 567390075Sobrien if (array && subcode != ARRAY_TYPE) 567490075Sobrien { 567590075Sobrien error_init ("array index in non-array initializer"); 567690075Sobrien return 1; 567790075Sobrien } 567890075Sobrien else if (!array && subcode != RECORD_TYPE && subcode != UNION_TYPE) 567990075Sobrien { 568090075Sobrien error_init ("field name not in record or union initializer"); 568190075Sobrien return 1; 568290075Sobrien } 568390075Sobrien 568490075Sobrien constructor_designated = 1; 568590075Sobrien push_init_level (2); 568690075Sobrien return 0; 568790075Sobrien} 568890075Sobrien 568990075Sobrien/* If there are range designators in designator list, push a new designator 569090075Sobrien to constructor_range_stack. RANGE_END is end of such stack range or 569190075Sobrien NULL_TREE if there is no range designator at this level. */ 569290075Sobrien 569390075Sobrienstatic void 569490075Sobrienpush_range_stack (range_end) 569590075Sobrien tree range_end; 569690075Sobrien{ 569790075Sobrien struct constructor_range_stack *p; 569890075Sobrien 569990075Sobrien p = (struct constructor_range_stack *) 570090075Sobrien ggc_alloc (sizeof (struct constructor_range_stack)); 570190075Sobrien p->prev = constructor_range_stack; 570290075Sobrien p->next = 0; 570390075Sobrien p->fields = constructor_fields; 570490075Sobrien p->range_start = constructor_index; 570590075Sobrien p->index = constructor_index; 570690075Sobrien p->stack = constructor_stack; 570790075Sobrien p->range_end = range_end; 570890075Sobrien if (constructor_range_stack) 570990075Sobrien constructor_range_stack->next = p; 571090075Sobrien constructor_range_stack = p; 571190075Sobrien} 571290075Sobrien 571318334Speter/* Within an array initializer, specify the next index to be initialized. 571418334Speter FIRST is that index. If LAST is nonzero, then initialize a range 571518334Speter of indices, running from FIRST through LAST. */ 571618334Speter 571718334Spetervoid 571818334Speterset_init_index (first, last) 571918334Speter tree first, last; 572018334Speter{ 572190075Sobrien if (set_designator (1)) 572290075Sobrien return; 572390075Sobrien 572490075Sobrien designator_errorneous = 1; 572590075Sobrien 572618334Speter while ((TREE_CODE (first) == NOP_EXPR 572718334Speter || TREE_CODE (first) == CONVERT_EXPR 572818334Speter || TREE_CODE (first) == NON_LVALUE_EXPR) 572918334Speter && (TYPE_MODE (TREE_TYPE (first)) 573018334Speter == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0))))) 573190075Sobrien first = TREE_OPERAND (first, 0); 573290075Sobrien 573318334Speter if (last) 573418334Speter while ((TREE_CODE (last) == NOP_EXPR 573518334Speter || TREE_CODE (last) == CONVERT_EXPR 573618334Speter || TREE_CODE (last) == NON_LVALUE_EXPR) 573718334Speter && (TYPE_MODE (TREE_TYPE (last)) 573818334Speter == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0))))) 573990075Sobrien last = TREE_OPERAND (last, 0); 574018334Speter 574118334Speter if (TREE_CODE (first) != INTEGER_CST) 574252284Sobrien error_init ("nonconstant array index in initializer"); 574318334Speter else if (last != 0 && TREE_CODE (last) != INTEGER_CST) 574452284Sobrien error_init ("nonconstant array index in initializer"); 574590075Sobrien else if (TREE_CODE (constructor_type) != ARRAY_TYPE) 574652284Sobrien error_init ("array index in non-array initializer"); 574790075Sobrien else if (constructor_max_index 574890075Sobrien && tree_int_cst_lt (constructor_max_index, first)) 574990075Sobrien error_init ("array index in initializer exceeds array bounds"); 575018334Speter else 575118334Speter { 575290075Sobrien constructor_index = convert (bitsizetype, first); 575318334Speter 575490075Sobrien if (last) 575518334Speter { 575690075Sobrien if (tree_int_cst_equal (first, last)) 575790075Sobrien last = 0; 575890075Sobrien else if (tree_int_cst_lt (last, first)) 575990075Sobrien { 576090075Sobrien error_init ("empty index range in initializer"); 576190075Sobrien last = 0; 576290075Sobrien } 576390075Sobrien else 576490075Sobrien { 576590075Sobrien last = convert (bitsizetype, last); 576690075Sobrien if (constructor_max_index != 0 576790075Sobrien && tree_int_cst_lt (constructor_max_index, last)) 576890075Sobrien { 576990075Sobrien error_init ("array index range in initializer exceeds array bounds"); 577090075Sobrien last = 0; 577190075Sobrien } 577290075Sobrien } 577318334Speter } 577490075Sobrien 577590075Sobrien designator_depth++; 577690075Sobrien designator_errorneous = 0; 577790075Sobrien if (constructor_range_stack || last) 577890075Sobrien push_range_stack (last); 577918334Speter } 578018334Speter} 578118334Speter 578218334Speter/* Within a struct initializer, specify the next field to be initialized. */ 578318334Speter 578418334Spetervoid 578518334Speterset_init_label (fieldname) 578618334Speter tree fieldname; 578718334Speter{ 578818334Speter tree tail; 578918334Speter 579090075Sobrien if (set_designator (0)) 579118334Speter return; 579218334Speter 579390075Sobrien designator_errorneous = 1; 579490075Sobrien 579590075Sobrien if (TREE_CODE (constructor_type) != RECORD_TYPE 579690075Sobrien && TREE_CODE (constructor_type) != UNION_TYPE) 579790075Sobrien { 579890075Sobrien error_init ("field name not in record or union initializer"); 579990075Sobrien return; 580090075Sobrien } 580190075Sobrien 580218334Speter for (tail = TYPE_FIELDS (constructor_type); tail; 580318334Speter tail = TREE_CHAIN (tail)) 580418334Speter { 580518334Speter if (DECL_NAME (tail) == fieldname) 580618334Speter break; 580718334Speter } 580818334Speter 580918334Speter if (tail == 0) 581018334Speter error ("unknown field `%s' specified in initializer", 581118334Speter IDENTIFIER_POINTER (fieldname)); 581218334Speter else 581318334Speter { 581418334Speter constructor_fields = tail; 581590075Sobrien designator_depth++; 581690075Sobrien designator_errorneous = 0; 581790075Sobrien if (constructor_range_stack) 581890075Sobrien push_range_stack (NULL_TREE); 581918334Speter } 582018334Speter} 582118334Speter 582250397Sobrien/* Add a new initializer to the tree of pending initializers. PURPOSE 582390075Sobrien identifies the initializer, either array index or field in a structure. 582450397Sobrien VALUE is the value of that index or field. */ 582550397Sobrien 582650397Sobrienstatic void 582750397Sobrienadd_pending_init (purpose, value) 582850397Sobrien tree purpose, value; 582950397Sobrien{ 583050397Sobrien struct init_node *p, **q, *r; 583150397Sobrien 583250397Sobrien q = &constructor_pending_elts; 583350397Sobrien p = 0; 583450397Sobrien 583550397Sobrien if (TREE_CODE (constructor_type) == ARRAY_TYPE) 583650397Sobrien { 583750397Sobrien while (*q != 0) 583850397Sobrien { 583950397Sobrien p = *q; 584050397Sobrien if (tree_int_cst_lt (purpose, p->purpose)) 584150397Sobrien q = &p->left; 584290075Sobrien else if (tree_int_cst_lt (p->purpose, purpose)) 584350397Sobrien q = &p->right; 584450397Sobrien else 584590075Sobrien { 584690075Sobrien if (TREE_SIDE_EFFECTS (p->value)) 584790075Sobrien warning_init ("initialized field with side-effects overwritten"); 584890075Sobrien p->value = value; 584990075Sobrien return; 585090075Sobrien } 585150397Sobrien } 585250397Sobrien } 585350397Sobrien else 585450397Sobrien { 585590075Sobrien tree bitpos; 585690075Sobrien 585790075Sobrien bitpos = bit_position (purpose); 585850397Sobrien while (*q != NULL) 585950397Sobrien { 586050397Sobrien p = *q; 586190075Sobrien if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) 586250397Sobrien q = &p->left; 586360967Sobrien else if (p->purpose != purpose) 586450397Sobrien q = &p->right; 586550397Sobrien else 586690075Sobrien { 586790075Sobrien if (TREE_SIDE_EFFECTS (p->value)) 586890075Sobrien warning_init ("initialized field with side-effects overwritten"); 586990075Sobrien p->value = value; 587090075Sobrien return; 587190075Sobrien } 587250397Sobrien } 587350397Sobrien } 587450397Sobrien 587590075Sobrien r = (struct init_node *) ggc_alloc (sizeof (struct init_node)); 587650397Sobrien r->purpose = purpose; 587750397Sobrien r->value = value; 587850397Sobrien 587950397Sobrien *q = r; 588050397Sobrien r->parent = p; 588150397Sobrien r->left = 0; 588250397Sobrien r->right = 0; 588350397Sobrien r->balance = 0; 588450397Sobrien 588550397Sobrien while (p) 588650397Sobrien { 588750397Sobrien struct init_node *s; 588850397Sobrien 588950397Sobrien if (r == p->left) 589050397Sobrien { 589150397Sobrien if (p->balance == 0) 589250397Sobrien p->balance = -1; 589350397Sobrien else if (p->balance < 0) 589450397Sobrien { 589550397Sobrien if (r->balance < 0) 589650397Sobrien { 589790075Sobrien /* L rotation. */ 589850397Sobrien p->left = r->right; 589950397Sobrien if (p->left) 590050397Sobrien p->left->parent = p; 590150397Sobrien r->right = p; 590250397Sobrien 590350397Sobrien p->balance = 0; 590450397Sobrien r->balance = 0; 590550397Sobrien 590650397Sobrien s = p->parent; 590750397Sobrien p->parent = r; 590850397Sobrien r->parent = s; 590950397Sobrien if (s) 591050397Sobrien { 591150397Sobrien if (s->left == p) 591250397Sobrien s->left = r; 591350397Sobrien else 591450397Sobrien s->right = r; 591550397Sobrien } 591650397Sobrien else 591750397Sobrien constructor_pending_elts = r; 591850397Sobrien } 591950397Sobrien else 592050397Sobrien { 592190075Sobrien /* LR rotation. */ 592250397Sobrien struct init_node *t = r->right; 592350397Sobrien 592450397Sobrien r->right = t->left; 592550397Sobrien if (r->right) 592650397Sobrien r->right->parent = r; 592750397Sobrien t->left = r; 592850397Sobrien 592950397Sobrien p->left = t->right; 593050397Sobrien if (p->left) 593150397Sobrien p->left->parent = p; 593250397Sobrien t->right = p; 593350397Sobrien 593450397Sobrien p->balance = t->balance < 0; 593550397Sobrien r->balance = -(t->balance > 0); 593650397Sobrien t->balance = 0; 593750397Sobrien 593850397Sobrien s = p->parent; 593950397Sobrien p->parent = t; 594050397Sobrien r->parent = t; 594150397Sobrien t->parent = s; 594250397Sobrien if (s) 594350397Sobrien { 594450397Sobrien if (s->left == p) 594550397Sobrien s->left = t; 594650397Sobrien else 594750397Sobrien s->right = t; 594850397Sobrien } 594950397Sobrien else 595050397Sobrien constructor_pending_elts = t; 595150397Sobrien } 595250397Sobrien break; 595350397Sobrien } 595450397Sobrien else 595550397Sobrien { 595650397Sobrien /* p->balance == +1; growth of left side balances the node. */ 595750397Sobrien p->balance = 0; 595850397Sobrien break; 595950397Sobrien } 596050397Sobrien } 596150397Sobrien else /* r == p->right */ 596250397Sobrien { 596350397Sobrien if (p->balance == 0) 596450397Sobrien /* Growth propagation from right side. */ 596550397Sobrien p->balance++; 596650397Sobrien else if (p->balance > 0) 596750397Sobrien { 596850397Sobrien if (r->balance > 0) 596950397Sobrien { 597090075Sobrien /* R rotation. */ 597150397Sobrien p->right = r->left; 597250397Sobrien if (p->right) 597350397Sobrien p->right->parent = p; 597450397Sobrien r->left = p; 597550397Sobrien 597650397Sobrien p->balance = 0; 597750397Sobrien r->balance = 0; 597850397Sobrien 597950397Sobrien s = p->parent; 598050397Sobrien p->parent = r; 598150397Sobrien r->parent = s; 598250397Sobrien if (s) 598350397Sobrien { 598450397Sobrien if (s->left == p) 598550397Sobrien s->left = r; 598650397Sobrien else 598750397Sobrien s->right = r; 598850397Sobrien } 598950397Sobrien else 599050397Sobrien constructor_pending_elts = r; 599150397Sobrien } 599250397Sobrien else /* r->balance == -1 */ 599350397Sobrien { 599450397Sobrien /* RL rotation */ 599550397Sobrien struct init_node *t = r->left; 599650397Sobrien 599750397Sobrien r->left = t->right; 599850397Sobrien if (r->left) 599950397Sobrien r->left->parent = r; 600050397Sobrien t->right = r; 600150397Sobrien 600250397Sobrien p->right = t->left; 600350397Sobrien if (p->right) 600450397Sobrien p->right->parent = p; 600550397Sobrien t->left = p; 600650397Sobrien 600750397Sobrien r->balance = (t->balance < 0); 600850397Sobrien p->balance = -(t->balance > 0); 600950397Sobrien t->balance = 0; 601050397Sobrien 601150397Sobrien s = p->parent; 601250397Sobrien p->parent = t; 601350397Sobrien r->parent = t; 601450397Sobrien t->parent = s; 601550397Sobrien if (s) 601650397Sobrien { 601750397Sobrien if (s->left == p) 601850397Sobrien s->left = t; 601950397Sobrien else 602050397Sobrien s->right = t; 602150397Sobrien } 602250397Sobrien else 602350397Sobrien constructor_pending_elts = t; 602450397Sobrien } 602550397Sobrien break; 602650397Sobrien } 602750397Sobrien else 602850397Sobrien { 602990075Sobrien /* p->balance == -1; growth of right side balances the node. */ 603050397Sobrien p->balance = 0; 603150397Sobrien break; 603250397Sobrien } 603350397Sobrien } 603450397Sobrien 603550397Sobrien r = p; 603650397Sobrien p = p->parent; 603750397Sobrien } 603850397Sobrien} 603950397Sobrien 604090075Sobrien/* Build AVL tree from a sorted chain. */ 604150397Sobrien 604290075Sobrienstatic void 604390075Sobrienset_nonincremental_init () 604490075Sobrien{ 604590075Sobrien tree chain; 604690075Sobrien 604790075Sobrien if (TREE_CODE (constructor_type) != RECORD_TYPE 604890075Sobrien && TREE_CODE (constructor_type) != ARRAY_TYPE) 604990075Sobrien return; 605090075Sobrien 605190075Sobrien for (chain = constructor_elements; chain; chain = TREE_CHAIN (chain)) 605290075Sobrien add_pending_init (TREE_PURPOSE (chain), TREE_VALUE (chain)); 605390075Sobrien constructor_elements = 0; 605490075Sobrien if (TREE_CODE (constructor_type) == RECORD_TYPE) 605590075Sobrien { 605690075Sobrien constructor_unfilled_fields = TYPE_FIELDS (constructor_type); 605790075Sobrien /* Skip any nameless bit fields at the beginning. */ 605890075Sobrien while (constructor_unfilled_fields != 0 605990075Sobrien && DECL_C_BIT_FIELD (constructor_unfilled_fields) 606090075Sobrien && DECL_NAME (constructor_unfilled_fields) == 0) 606190075Sobrien constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); 606290075Sobrien 606390075Sobrien } 606490075Sobrien else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 606590075Sobrien { 606690075Sobrien if (TYPE_DOMAIN (constructor_type)) 606790075Sobrien constructor_unfilled_index 606890075Sobrien = convert (bitsizetype, 606990075Sobrien TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); 607090075Sobrien else 607190075Sobrien constructor_unfilled_index = bitsize_zero_node; 607290075Sobrien } 607390075Sobrien constructor_incremental = 0; 607490075Sobrien} 607590075Sobrien 607690075Sobrien/* Build AVL tree from a string constant. */ 607790075Sobrien 607890075Sobrienstatic void 607990075Sobrienset_nonincremental_init_from_string (str) 608090075Sobrien tree str; 608190075Sobrien{ 608290075Sobrien tree value, purpose, type; 608390075Sobrien HOST_WIDE_INT val[2]; 608490075Sobrien const char *p, *end; 608590075Sobrien int byte, wchar_bytes, charwidth, bitpos; 608690075Sobrien 608790075Sobrien if (TREE_CODE (constructor_type) != ARRAY_TYPE) 608890075Sobrien abort (); 608990075Sobrien 609090075Sobrien if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) 609190075Sobrien == TYPE_PRECISION (char_type_node)) 609290075Sobrien wchar_bytes = 1; 609390075Sobrien else if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) 609490075Sobrien == TYPE_PRECISION (wchar_type_node)) 609590075Sobrien wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; 609690075Sobrien else 609790075Sobrien abort (); 609890075Sobrien 609990075Sobrien charwidth = TYPE_PRECISION (char_type_node); 610090075Sobrien type = TREE_TYPE (constructor_type); 610190075Sobrien p = TREE_STRING_POINTER (str); 610290075Sobrien end = p + TREE_STRING_LENGTH (str); 610390075Sobrien 610490075Sobrien for (purpose = bitsize_zero_node; 610590075Sobrien p < end && !tree_int_cst_lt (constructor_max_index, purpose); 610690075Sobrien purpose = size_binop (PLUS_EXPR, purpose, bitsize_one_node)) 610790075Sobrien { 610890075Sobrien if (wchar_bytes == 1) 610990075Sobrien { 611090075Sobrien val[1] = (unsigned char) *p++; 611190075Sobrien val[0] = 0; 611290075Sobrien } 611390075Sobrien else 611490075Sobrien { 611590075Sobrien val[0] = 0; 611690075Sobrien val[1] = 0; 611790075Sobrien for (byte = 0; byte < wchar_bytes; byte++) 611890075Sobrien { 611990075Sobrien if (BYTES_BIG_ENDIAN) 612090075Sobrien bitpos = (wchar_bytes - byte - 1) * charwidth; 612190075Sobrien else 612290075Sobrien bitpos = byte * charwidth; 612390075Sobrien val[bitpos < HOST_BITS_PER_WIDE_INT] 612490075Sobrien |= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++)) 612590075Sobrien << (bitpos % HOST_BITS_PER_WIDE_INT); 612690075Sobrien } 612790075Sobrien } 612890075Sobrien 612990075Sobrien if (!TREE_UNSIGNED (type)) 613090075Sobrien { 613190075Sobrien bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR; 613290075Sobrien if (bitpos < HOST_BITS_PER_WIDE_INT) 613390075Sobrien { 613490075Sobrien if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1))) 613590075Sobrien { 613690075Sobrien val[1] |= ((HOST_WIDE_INT) -1) << bitpos; 613790075Sobrien val[0] = -1; 613890075Sobrien } 613990075Sobrien } 614090075Sobrien else if (bitpos == HOST_BITS_PER_WIDE_INT) 614190075Sobrien { 614290075Sobrien if (val[1] < 0) 614390075Sobrien val[0] = -1; 614490075Sobrien } 614590075Sobrien else if (val[0] & (((HOST_WIDE_INT) 1) 614690075Sobrien << (bitpos - 1 - HOST_BITS_PER_WIDE_INT))) 614790075Sobrien val[0] |= ((HOST_WIDE_INT) -1) 614890075Sobrien << (bitpos - HOST_BITS_PER_WIDE_INT); 614990075Sobrien } 615090075Sobrien 615190075Sobrien value = build_int_2 (val[1], val[0]); 615290075Sobrien TREE_TYPE (value) = type; 615390075Sobrien add_pending_init (purpose, value); 615490075Sobrien } 615590075Sobrien 615690075Sobrien constructor_incremental = 0; 615790075Sobrien} 615890075Sobrien 615990075Sobrien/* Return value of FIELD in pending initializer or zero if the field was 616090075Sobrien not initialized yet. */ 616190075Sobrien 616290075Sobrienstatic tree 616390075Sobrienfind_init_member (field) 616450397Sobrien tree field; 616550397Sobrien{ 616650397Sobrien struct init_node *p; 616750397Sobrien 616850397Sobrien if (TREE_CODE (constructor_type) == ARRAY_TYPE) 616950397Sobrien { 617090075Sobrien if (constructor_incremental 617190075Sobrien && tree_int_cst_lt (field, constructor_unfilled_index)) 617290075Sobrien set_nonincremental_init (); 617390075Sobrien 617490075Sobrien p = constructor_pending_elts; 617550397Sobrien while (p) 617650397Sobrien { 617790075Sobrien if (tree_int_cst_lt (field, p->purpose)) 617850397Sobrien p = p->left; 617990075Sobrien else if (tree_int_cst_lt (p->purpose, field)) 618090075Sobrien p = p->right; 618150397Sobrien else 618290075Sobrien return p->value; 618350397Sobrien } 618450397Sobrien } 618590075Sobrien else if (TREE_CODE (constructor_type) == RECORD_TYPE) 618650397Sobrien { 618790075Sobrien tree bitpos = bit_position (field); 618890075Sobrien 618990075Sobrien if (constructor_incremental 619090075Sobrien && (!constructor_unfilled_fields 619190075Sobrien || tree_int_cst_lt (bitpos, 619290075Sobrien bit_position (constructor_unfilled_fields)))) 619390075Sobrien set_nonincremental_init (); 619490075Sobrien 619590075Sobrien p = constructor_pending_elts; 619650397Sobrien while (p) 619750397Sobrien { 619850397Sobrien if (field == p->purpose) 619990075Sobrien return p->value; 620090075Sobrien else if (tree_int_cst_lt (bitpos, bit_position (p->purpose))) 620150397Sobrien p = p->left; 620250397Sobrien else 620350397Sobrien p = p->right; 620450397Sobrien } 620550397Sobrien } 620690075Sobrien else if (TREE_CODE (constructor_type) == UNION_TYPE) 620790075Sobrien { 620890075Sobrien if (constructor_elements 620990075Sobrien && TREE_PURPOSE (constructor_elements) == field) 621090075Sobrien return TREE_VALUE (constructor_elements); 621190075Sobrien } 621250397Sobrien return 0; 621350397Sobrien} 621450397Sobrien 621518334Speter/* "Output" the next constructor element. 621618334Speter At top level, really output it to assembler code now. 621718334Speter Otherwise, collect it in a list from which we will make a CONSTRUCTOR. 621818334Speter TYPE is the data type that the containing data type wants here. 621918334Speter FIELD is the field (a FIELD_DECL) or the index that this element fills. 622018334Speter 622118334Speter PENDING if non-nil means output pending elements that belong 622218334Speter right after this element. (PENDING is normally 1; 622318334Speter it is 0 while outputting pending elements, to avoid recursion.) */ 622418334Speter 622518334Speterstatic void 622618334Speteroutput_init_element (value, type, field, pending) 622718334Speter tree value, type, field; 622818334Speter int pending; 622918334Speter{ 623018334Speter if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE 623118334Speter || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE 623218334Speter && !(TREE_CODE (value) == STRING_CST 623318334Speter && TREE_CODE (type) == ARRAY_TYPE 623418334Speter && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE) 623518334Speter && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)), 623618334Speter TYPE_MAIN_VARIANT (type)))) 623718334Speter value = default_conversion (value); 623818334Speter 623990075Sobrien if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR 624090075Sobrien && require_constant_value && !flag_isoc99 && pending) 624190075Sobrien { 624290075Sobrien /* As an extension, allow initializing objects with static storage 624390075Sobrien duration with compound literals (which are then treated just as 624490075Sobrien the brace enclosed list they contain). */ 624590075Sobrien tree decl = COMPOUND_LITERAL_EXPR_DECL (value); 624690075Sobrien value = DECL_INITIAL (decl); 624790075Sobrien } 624890075Sobrien 624918334Speter if (value == error_mark_node) 625018334Speter constructor_erroneous = 1; 625118334Speter else if (!TREE_CONSTANT (value)) 625218334Speter constructor_constant = 0; 625318334Speter else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0 625418334Speter || ((TREE_CODE (constructor_type) == RECORD_TYPE 625518334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 625650397Sobrien && DECL_C_BIT_FIELD (field) 625750397Sobrien && TREE_CODE (value) != INTEGER_CST)) 625818334Speter constructor_simple = 0; 625918334Speter 626018334Speter if (require_constant_value && ! TREE_CONSTANT (value)) 626118334Speter { 626252284Sobrien error_init ("initializer element is not constant"); 626318334Speter value = error_mark_node; 626418334Speter } 626518334Speter else if (require_constant_elements 626618334Speter && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) 626790075Sobrien pedwarn ("initializer element is not computable at load time"); 626818334Speter 626990075Sobrien /* If this field is empty (and not at the end of structure), 627090075Sobrien don't do anything other than checking the initializer. */ 627190075Sobrien if (field 627290075Sobrien && (TREE_TYPE (field) == error_mark_node 627390075Sobrien || (COMPLETE_TYPE_P (TREE_TYPE (field)) 627490075Sobrien && integer_zerop (TYPE_SIZE (TREE_TYPE (field))) 627590075Sobrien && (TREE_CODE (constructor_type) == ARRAY_TYPE 627690075Sobrien || TREE_CHAIN (field))))) 627790075Sobrien return; 627890075Sobrien 627990075Sobrien value = digest_init (type, value, require_constant_value, 628090075Sobrien require_constant_elements); 628190075Sobrien if (value == error_mark_node) 628218334Speter { 628390075Sobrien constructor_erroneous = 1; 628490075Sobrien return; 628518334Speter } 628618334Speter 628718334Speter /* If this element doesn't come next in sequence, 628818334Speter put it on constructor_pending_elts. */ 628918334Speter if (TREE_CODE (constructor_type) == ARRAY_TYPE 629090075Sobrien && (!constructor_incremental 629190075Sobrien || !tree_int_cst_equal (field, constructor_unfilled_index))) 629218334Speter { 629390075Sobrien if (constructor_incremental 629490075Sobrien && tree_int_cst_lt (field, constructor_unfilled_index)) 629590075Sobrien set_nonincremental_init (); 629690075Sobrien 629790075Sobrien add_pending_init (field, value); 629890075Sobrien return; 629918334Speter } 630018334Speter else if (TREE_CODE (constructor_type) == RECORD_TYPE 630190075Sobrien && (!constructor_incremental 630290075Sobrien || field != constructor_unfilled_fields)) 630318334Speter { 630418334Speter /* We do this for records but not for unions. In a union, 630518334Speter no matter which field is specified, it can be initialized 630618334Speter right away since it starts at the beginning of the union. */ 630790075Sobrien if (constructor_incremental) 630818334Speter { 630990075Sobrien if (!constructor_unfilled_fields) 631090075Sobrien set_nonincremental_init (); 631118334Speter else 631218334Speter { 631390075Sobrien tree bitpos, unfillpos; 631418334Speter 631590075Sobrien bitpos = bit_position (field); 631690075Sobrien unfillpos = bit_position (constructor_unfilled_fields); 631718334Speter 631890075Sobrien if (tree_int_cst_lt (bitpos, unfillpos)) 631990075Sobrien set_nonincremental_init (); 632018334Speter } 632118334Speter } 632218334Speter 632390075Sobrien add_pending_init (field, value); 632490075Sobrien return; 632590075Sobrien } 632690075Sobrien else if (TREE_CODE (constructor_type) == UNION_TYPE 632790075Sobrien && constructor_elements) 632890075Sobrien { 632990075Sobrien if (TREE_SIDE_EFFECTS (TREE_VALUE (constructor_elements))) 633090075Sobrien warning_init ("initialized field with side-effects overwritten"); 633118334Speter 633290075Sobrien /* We can have just one union field set. */ 633390075Sobrien constructor_elements = 0; 633418334Speter } 633590075Sobrien 633690075Sobrien /* Otherwise, output this element either to 633790075Sobrien constructor_elements or to the assembler file. */ 633890075Sobrien 633990075Sobrien if (field && TREE_CODE (field) == INTEGER_CST) 634090075Sobrien field = copy_node (field); 634190075Sobrien constructor_elements 634290075Sobrien = tree_cons (field, value, constructor_elements); 634390075Sobrien 634490075Sobrien /* Advance the variable that indicates sequential elements output. */ 634590075Sobrien if (TREE_CODE (constructor_type) == ARRAY_TYPE) 634690075Sobrien constructor_unfilled_index 634790075Sobrien = size_binop (PLUS_EXPR, constructor_unfilled_index, 634890075Sobrien bitsize_one_node); 634990075Sobrien else if (TREE_CODE (constructor_type) == RECORD_TYPE) 635090075Sobrien { 635190075Sobrien constructor_unfilled_fields 635290075Sobrien = TREE_CHAIN (constructor_unfilled_fields); 635390075Sobrien 635490075Sobrien /* Skip any nameless bit fields. */ 635590075Sobrien while (constructor_unfilled_fields != 0 635690075Sobrien && DECL_C_BIT_FIELD (constructor_unfilled_fields) 635790075Sobrien && DECL_NAME (constructor_unfilled_fields) == 0) 635890075Sobrien constructor_unfilled_fields = 635990075Sobrien TREE_CHAIN (constructor_unfilled_fields); 636090075Sobrien } 636190075Sobrien else if (TREE_CODE (constructor_type) == UNION_TYPE) 636290075Sobrien constructor_unfilled_fields = 0; 636390075Sobrien 636490075Sobrien /* Now output any pending elements which have become next. */ 636590075Sobrien if (pending) 636690075Sobrien output_pending_init_elements (0); 636718334Speter} 636818334Speter 636918334Speter/* Output any pending elements which have become next. 637018334Speter As we output elements, constructor_unfilled_{fields,index} 637118334Speter advances, which may cause other elements to become next; 637218334Speter if so, they too are output. 637318334Speter 637418334Speter If ALL is 0, we return when there are 637518334Speter no more pending elements to output now. 637618334Speter 637718334Speter If ALL is 1, we output space as necessary so that 637818334Speter we can output all the pending elements. */ 637918334Speter 638018334Speterstatic void 638118334Speteroutput_pending_init_elements (all) 638218334Speter int all; 638318334Speter{ 638450397Sobrien struct init_node *elt = constructor_pending_elts; 638518334Speter tree next; 638618334Speter 638718334Speter retry: 638818334Speter 638950397Sobrien /* Look thru the whole pending tree. 639018334Speter If we find an element that should be output now, 639118334Speter output it. Otherwise, set NEXT to the element 639218334Speter that comes first among those still pending. */ 639318334Speter 639418334Speter next = 0; 639550397Sobrien while (elt) 639618334Speter { 639718334Speter if (TREE_CODE (constructor_type) == ARRAY_TYPE) 639818334Speter { 639950397Sobrien if (tree_int_cst_equal (elt->purpose, 640018334Speter constructor_unfilled_index)) 640150397Sobrien output_init_element (elt->value, 640250397Sobrien TREE_TYPE (constructor_type), 640350397Sobrien constructor_unfilled_index, 0); 640450397Sobrien else if (tree_int_cst_lt (constructor_unfilled_index, 640550397Sobrien elt->purpose)) 640618334Speter { 640750397Sobrien /* Advance to the next smaller node. */ 640850397Sobrien if (elt->left) 640950397Sobrien elt = elt->left; 641050397Sobrien else 641150397Sobrien { 641250397Sobrien /* We have reached the smallest node bigger than the 641350397Sobrien current unfilled index. Fill the space first. */ 641450397Sobrien next = elt->purpose; 641550397Sobrien break; 641650397Sobrien } 641718334Speter } 641850397Sobrien else 641950397Sobrien { 642050397Sobrien /* Advance to the next bigger node. */ 642150397Sobrien if (elt->right) 642250397Sobrien elt = elt->right; 642350397Sobrien else 642450397Sobrien { 642550397Sobrien /* We have reached the biggest node in a subtree. Find 642650397Sobrien the parent of it, which is the next bigger node. */ 642750397Sobrien while (elt->parent && elt->parent->right == elt) 642850397Sobrien elt = elt->parent; 642950397Sobrien elt = elt->parent; 643050397Sobrien if (elt && tree_int_cst_lt (constructor_unfilled_index, 643150397Sobrien elt->purpose)) 643250397Sobrien { 643350397Sobrien next = elt->purpose; 643450397Sobrien break; 643550397Sobrien } 643650397Sobrien } 643750397Sobrien } 643818334Speter } 643918334Speter else if (TREE_CODE (constructor_type) == RECORD_TYPE 644018334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 644118334Speter { 644290075Sobrien tree ctor_unfilled_bitpos, elt_bitpos; 644390075Sobrien 644450397Sobrien /* If the current record is complete we are done. */ 644550397Sobrien if (constructor_unfilled_fields == 0) 644650397Sobrien break; 644790075Sobrien 644890075Sobrien ctor_unfilled_bitpos = bit_position (constructor_unfilled_fields); 644990075Sobrien elt_bitpos = bit_position (elt->purpose); 645090075Sobrien /* We can't compare fields here because there might be empty 645190075Sobrien fields in between. */ 645290075Sobrien if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos)) 645318334Speter { 645490075Sobrien constructor_unfilled_fields = elt->purpose; 645590075Sobrien output_init_element (elt->value, TREE_TYPE (elt->purpose), 645690075Sobrien elt->purpose, 0); 645718334Speter } 645890075Sobrien else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) 645950397Sobrien { 646050397Sobrien /* Advance to the next smaller node. */ 646150397Sobrien if (elt->left) 646250397Sobrien elt = elt->left; 646350397Sobrien else 646450397Sobrien { 646550397Sobrien /* We have reached the smallest node bigger than the 646650397Sobrien current unfilled field. Fill the space first. */ 646750397Sobrien next = elt->purpose; 646850397Sobrien break; 646950397Sobrien } 647050397Sobrien } 647150397Sobrien else 647250397Sobrien { 647350397Sobrien /* Advance to the next bigger node. */ 647450397Sobrien if (elt->right) 647550397Sobrien elt = elt->right; 647650397Sobrien else 647750397Sobrien { 647850397Sobrien /* We have reached the biggest node in a subtree. Find 647950397Sobrien the parent of it, which is the next bigger node. */ 648050397Sobrien while (elt->parent && elt->parent->right == elt) 648150397Sobrien elt = elt->parent; 648250397Sobrien elt = elt->parent; 648350397Sobrien if (elt 648490075Sobrien && (tree_int_cst_lt (ctor_unfilled_bitpos, 648590075Sobrien bit_position (elt->purpose)))) 648650397Sobrien { 648750397Sobrien next = elt->purpose; 648850397Sobrien break; 648950397Sobrien } 649050397Sobrien } 649150397Sobrien } 649218334Speter } 649318334Speter } 649418334Speter 649518334Speter /* Ordinarily return, but not if we want to output all 649618334Speter and there are elements left. */ 649718334Speter if (! (all && next != 0)) 649818334Speter return; 649918334Speter 650090075Sobrien /* If it's not incremental, just skip over the gap, so that after 650190075Sobrien jumping to retry we will output the next successive element. */ 650290075Sobrien if (TREE_CODE (constructor_type) == RECORD_TYPE 650390075Sobrien || TREE_CODE (constructor_type) == UNION_TYPE) 650490075Sobrien constructor_unfilled_fields = next; 650590075Sobrien else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 650690075Sobrien constructor_unfilled_index = next; 650718334Speter 650850397Sobrien /* ELT now points to the node in the pending tree with the next 650950397Sobrien initializer to output. */ 651018334Speter goto retry; 651118334Speter} 651218334Speter 651318334Speter/* Add one non-braced element to the current constructor level. 651418334Speter This adjusts the current position within the constructor's type. 651518334Speter This may also start or terminate implicit levels 651618334Speter to handle a partly-braced initializer. 651718334Speter 651818334Speter Once this has found the correct level for the new element, 651990075Sobrien it calls output_init_element. */ 652018334Speter 652118334Spetervoid 652218334Speterprocess_init_element (value) 652318334Speter tree value; 652418334Speter{ 652518334Speter tree orig_value = value; 652618334Speter int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; 652718334Speter 652890075Sobrien designator_depth = 0; 652990075Sobrien designator_errorneous = 0; 653090075Sobrien 653118334Speter /* Handle superfluous braces around string cst as in 653218334Speter char x[] = {"foo"}; */ 653318334Speter if (string_flag 653418334Speter && constructor_type 653518334Speter && TREE_CODE (constructor_type) == ARRAY_TYPE 653618334Speter && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE 653718334Speter && integer_zerop (constructor_unfilled_index)) 653818334Speter { 653990075Sobrien if (constructor_stack->replacement_value) 654090075Sobrien error_init ("excess elements in char array initializer"); 654118334Speter constructor_stack->replacement_value = value; 654218334Speter return; 654318334Speter } 654418334Speter 654518334Speter if (constructor_stack->replacement_value != 0) 654618334Speter { 654752284Sobrien error_init ("excess elements in struct initializer"); 654818334Speter return; 654918334Speter } 655018334Speter 655118334Speter /* Ignore elements of a brace group if it is entirely superfluous 655218334Speter and has already been diagnosed. */ 655318334Speter if (constructor_type == 0) 655418334Speter return; 655518334Speter 655618334Speter /* If we've exhausted any levels that didn't have braces, 655718334Speter pop them now. */ 655818334Speter while (constructor_stack->implicit) 655918334Speter { 656018334Speter if ((TREE_CODE (constructor_type) == RECORD_TYPE 656118334Speter || TREE_CODE (constructor_type) == UNION_TYPE) 656218334Speter && constructor_fields == 0) 656318334Speter process_init_element (pop_init_level (1)); 656418334Speter else if (TREE_CODE (constructor_type) == ARRAY_TYPE 656550397Sobrien && (constructor_max_index == 0 656650397Sobrien || tree_int_cst_lt (constructor_max_index, 656750397Sobrien constructor_index))) 656818334Speter process_init_element (pop_init_level (1)); 656918334Speter else 657018334Speter break; 657118334Speter } 657218334Speter 657390075Sobrien /* In the case of [LO ... HI] = VALUE, only evaluate VALUE once. */ 657490075Sobrien if (constructor_range_stack) 657590075Sobrien { 657690075Sobrien /* If value is a compound literal and we'll be just using its 657790075Sobrien content, don't put it into a SAVE_EXPR. */ 657890075Sobrien if (TREE_CODE (value) != COMPOUND_LITERAL_EXPR 657990075Sobrien || !require_constant_value 658090075Sobrien || flag_isoc99) 658190075Sobrien value = save_expr (value); 658290075Sobrien } 658390075Sobrien 658418334Speter while (1) 658518334Speter { 658618334Speter if (TREE_CODE (constructor_type) == RECORD_TYPE) 658718334Speter { 658818334Speter tree fieldtype; 658918334Speter enum tree_code fieldcode; 659018334Speter 659118334Speter if (constructor_fields == 0) 659218334Speter { 659352284Sobrien pedwarn_init ("excess elements in struct initializer"); 659418334Speter break; 659518334Speter } 659618334Speter 659718334Speter fieldtype = TREE_TYPE (constructor_fields); 659818334Speter if (fieldtype != error_mark_node) 659918334Speter fieldtype = TYPE_MAIN_VARIANT (fieldtype); 660018334Speter fieldcode = TREE_CODE (fieldtype); 660118334Speter 660296263Sobrien /* Error for non-static initialization of a flexible array member. */ 660396263Sobrien if (fieldcode == ARRAY_TYPE 660496263Sobrien && !require_constant_value 660596263Sobrien && TYPE_SIZE (fieldtype) == NULL_TREE 660696263Sobrien && TREE_CHAIN (constructor_fields) == NULL_TREE) 660796263Sobrien { 660896263Sobrien error_init ("non-static initialization of a flexible array member"); 660996263Sobrien break; 661096263Sobrien } 661196263Sobrien 661218334Speter /* Accept a string constant to initialize a subarray. */ 661318334Speter if (value != 0 661418334Speter && fieldcode == ARRAY_TYPE 661518334Speter && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE 661618334Speter && string_flag) 661718334Speter value = orig_value; 661818334Speter /* Otherwise, if we have come to a subaggregate, 661918334Speter and we don't have an element of its type, push into it. */ 662018334Speter else if (value != 0 && !constructor_no_implicit 662118334Speter && value != error_mark_node 662218334Speter && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype 662318334Speter && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE 662418334Speter || fieldcode == UNION_TYPE)) 662518334Speter { 662618334Speter push_init_level (1); 662718334Speter continue; 662818334Speter } 662918334Speter 663018334Speter if (value) 663118334Speter { 663218334Speter push_member_name (constructor_fields); 663318334Speter output_init_element (value, fieldtype, constructor_fields, 1); 663418334Speter RESTORE_SPELLING_DEPTH (constructor_depth); 663518334Speter } 663618334Speter else 663718334Speter /* Do the bookkeeping for an element that was 663818334Speter directly output as a constructor. */ 663918334Speter { 664018334Speter /* For a record, keep track of end position of last field. */ 664190075Sobrien if (DECL_SIZE (constructor_fields)) 664290075Sobrien constructor_bit_index 664390075Sobrien = size_binop (PLUS_EXPR, 664490075Sobrien bit_position (constructor_fields), 664590075Sobrien DECL_SIZE (constructor_fields)); 664618334Speter 664718334Speter constructor_unfilled_fields = TREE_CHAIN (constructor_fields); 664890075Sobrien /* Skip any nameless bit fields. */ 664990075Sobrien while (constructor_unfilled_fields != 0 665090075Sobrien && DECL_C_BIT_FIELD (constructor_unfilled_fields) 665190075Sobrien && DECL_NAME (constructor_unfilled_fields) == 0) 665290075Sobrien constructor_unfilled_fields = 665390075Sobrien TREE_CHAIN (constructor_unfilled_fields); 665418334Speter } 665518334Speter 665618334Speter constructor_fields = TREE_CHAIN (constructor_fields); 665718334Speter /* Skip any nameless bit fields at the beginning. */ 665850397Sobrien while (constructor_fields != 0 665950397Sobrien && DECL_C_BIT_FIELD (constructor_fields) 666018334Speter && DECL_NAME (constructor_fields) == 0) 666118334Speter constructor_fields = TREE_CHAIN (constructor_fields); 666218334Speter } 666390075Sobrien else if (TREE_CODE (constructor_type) == UNION_TYPE) 666418334Speter { 666518334Speter tree fieldtype; 666618334Speter enum tree_code fieldcode; 666718334Speter 666818334Speter if (constructor_fields == 0) 666918334Speter { 667052284Sobrien pedwarn_init ("excess elements in union initializer"); 667118334Speter break; 667218334Speter } 667318334Speter 667418334Speter fieldtype = TREE_TYPE (constructor_fields); 667518334Speter if (fieldtype != error_mark_node) 667618334Speter fieldtype = TYPE_MAIN_VARIANT (fieldtype); 667718334Speter fieldcode = TREE_CODE (fieldtype); 667818334Speter 667990075Sobrien /* Warn that traditional C rejects initialization of unions. 668090075Sobrien We skip the warning if the value is zero. This is done 668190075Sobrien under the assumption that the zero initializer in user 668290075Sobrien code appears conditioned on e.g. __STDC__ to avoid 668390075Sobrien "missing initializer" warnings and relies on default 668490075Sobrien initialization to zero in the traditional C case. 668590075Sobrien We also skip the warning if the initializer is designated, 668690075Sobrien again on the assumption that this must be conditional on 668790075Sobrien __STDC__ anyway (and we've already complained about the 668890075Sobrien member-designator already). */ 668990075Sobrien if (warn_traditional && !in_system_header && !constructor_designated 669090075Sobrien && !(value && (integer_zerop (value) || real_zerop (value)))) 669190075Sobrien warning ("traditional C rejects initialization of unions"); 669290075Sobrien 669318334Speter /* Accept a string constant to initialize a subarray. */ 669418334Speter if (value != 0 669518334Speter && fieldcode == ARRAY_TYPE 669618334Speter && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE 669718334Speter && string_flag) 669818334Speter value = orig_value; 669918334Speter /* Otherwise, if we have come to a subaggregate, 670018334Speter and we don't have an element of its type, push into it. */ 670118334Speter else if (value != 0 && !constructor_no_implicit 670218334Speter && value != error_mark_node 670318334Speter && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype 670418334Speter && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE 670518334Speter || fieldcode == UNION_TYPE)) 670618334Speter { 670718334Speter push_init_level (1); 670818334Speter continue; 670918334Speter } 671018334Speter 671118334Speter if (value) 671218334Speter { 671318334Speter push_member_name (constructor_fields); 671418334Speter output_init_element (value, fieldtype, constructor_fields, 1); 671518334Speter RESTORE_SPELLING_DEPTH (constructor_depth); 671618334Speter } 671718334Speter else 671818334Speter /* Do the bookkeeping for an element that was 671918334Speter directly output as a constructor. */ 672018334Speter { 672190075Sobrien constructor_bit_index = DECL_SIZE (constructor_fields); 672218334Speter constructor_unfilled_fields = TREE_CHAIN (constructor_fields); 672318334Speter } 672418334Speter 672518334Speter constructor_fields = 0; 672618334Speter } 672790075Sobrien else if (TREE_CODE (constructor_type) == ARRAY_TYPE) 672818334Speter { 672918334Speter tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); 673018334Speter enum tree_code eltcode = TREE_CODE (elttype); 673118334Speter 673218334Speter /* Accept a string constant to initialize a subarray. */ 673318334Speter if (value != 0 673418334Speter && eltcode == ARRAY_TYPE 673518334Speter && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE 673618334Speter && string_flag) 673718334Speter value = orig_value; 673818334Speter /* Otherwise, if we have come to a subaggregate, 673918334Speter and we don't have an element of its type, push into it. */ 674018334Speter else if (value != 0 && !constructor_no_implicit 674118334Speter && value != error_mark_node 674218334Speter && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype 674318334Speter && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE 674418334Speter || eltcode == UNION_TYPE)) 674518334Speter { 674618334Speter push_init_level (1); 674718334Speter continue; 674818334Speter } 674918334Speter 675018334Speter if (constructor_max_index != 0 675190075Sobrien && (tree_int_cst_lt (constructor_max_index, constructor_index) 675290075Sobrien || integer_all_onesp (constructor_max_index))) 675318334Speter { 675452284Sobrien pedwarn_init ("excess elements in array initializer"); 675518334Speter break; 675618334Speter } 675718334Speter 675890075Sobrien /* Now output the actual element. */ 675990075Sobrien if (value) 676050397Sobrien { 676190075Sobrien push_array_bounds (tree_low_cst (constructor_index, 0)); 676290075Sobrien output_init_element (value, elttype, constructor_index, 1); 676390075Sobrien RESTORE_SPELLING_DEPTH (constructor_depth); 676450397Sobrien } 676550397Sobrien 676690075Sobrien constructor_index 676790075Sobrien = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); 676818334Speter 676990075Sobrien if (! value) 677090075Sobrien /* If we are doing the bookkeeping for an element that was 677190075Sobrien directly output as a constructor, we must update 677290075Sobrien constructor_unfilled_index. */ 677390075Sobrien constructor_unfilled_index = constructor_index; 677418334Speter } 677596263Sobrien else if (TREE_CODE (constructor_type) == VECTOR_TYPE) 677696263Sobrien { 677796263Sobrien tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); 677818334Speter 677996263Sobrien /* Do a basic check of initializer size. Note that vectors 678096263Sobrien always have a fixed size derived from their type. */ 678196263Sobrien if (tree_int_cst_lt (constructor_max_index, constructor_index)) 678296263Sobrien { 678396263Sobrien pedwarn_init ("excess elements in vector initializer"); 678496263Sobrien break; 678596263Sobrien } 678696263Sobrien 678796263Sobrien /* Now output the actual element. */ 678896263Sobrien if (value) 678996263Sobrien output_init_element (value, elttype, constructor_index, 1); 679096263Sobrien 679196263Sobrien constructor_index 679296263Sobrien = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); 679396263Sobrien 679496263Sobrien if (! value) 679596263Sobrien /* If we are doing the bookkeeping for an element that was 679696263Sobrien directly output as a constructor, we must update 679796263Sobrien constructor_unfilled_index. */ 679896263Sobrien constructor_unfilled_index = constructor_index; 679996263Sobrien } 680096263Sobrien 680118334Speter /* Handle the sole element allowed in a braced initializer 680218334Speter for a scalar variable. */ 680390075Sobrien else if (constructor_fields == 0) 680418334Speter { 680552284Sobrien pedwarn_init ("excess elements in scalar initializer"); 680618334Speter break; 680718334Speter } 680890075Sobrien else 680990075Sobrien { 681090075Sobrien if (value) 681190075Sobrien output_init_element (value, constructor_type, NULL_TREE, 1); 681290075Sobrien constructor_fields = 0; 681390075Sobrien } 681418334Speter 681590075Sobrien /* Handle range initializers either at this level or anywhere higher 681690075Sobrien in the designator stack. */ 681790075Sobrien if (constructor_range_stack) 681890075Sobrien { 681990075Sobrien struct constructor_range_stack *p, *range_stack; 682090075Sobrien int finish = 0; 682190075Sobrien 682290075Sobrien range_stack = constructor_range_stack; 682390075Sobrien constructor_range_stack = 0; 682490075Sobrien while (constructor_stack != range_stack->stack) 682590075Sobrien { 682690075Sobrien if (!constructor_stack->implicit) 682790075Sobrien abort (); 682890075Sobrien process_init_element (pop_init_level (1)); 682990075Sobrien } 683090075Sobrien for (p = range_stack; 683190075Sobrien !p->range_end || tree_int_cst_equal (p->index, p->range_end); 683290075Sobrien p = p->prev) 683390075Sobrien { 683490075Sobrien if (!constructor_stack->implicit) 683590075Sobrien abort (); 683690075Sobrien process_init_element (pop_init_level (1)); 683790075Sobrien } 683890075Sobrien 683990075Sobrien p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node); 684090075Sobrien if (tree_int_cst_equal (p->index, p->range_end) && !p->prev) 684190075Sobrien finish = 1; 684290075Sobrien 684390075Sobrien while (1) 684490075Sobrien { 684590075Sobrien constructor_index = p->index; 684690075Sobrien constructor_fields = p->fields; 684790075Sobrien if (finish && p->range_end && p->index == p->range_start) 684890075Sobrien { 684990075Sobrien finish = 0; 685090075Sobrien p->prev = 0; 685190075Sobrien } 685290075Sobrien p = p->next; 685390075Sobrien if (!p) 685490075Sobrien break; 685590075Sobrien push_init_level (2); 685690075Sobrien p->stack = constructor_stack; 685790075Sobrien if (p->range_end && tree_int_cst_equal (p->index, p->range_end)) 685890075Sobrien p->index = p->range_start; 685990075Sobrien } 686090075Sobrien 686190075Sobrien if (!finish) 686290075Sobrien constructor_range_stack = range_stack; 686390075Sobrien continue; 686490075Sobrien } 686590075Sobrien 686618334Speter break; 686718334Speter } 686818334Speter 686990075Sobrien constructor_range_stack = 0; 687018334Speter} 687118334Speter 687290075Sobrien/* Build a simple asm-statement, from one string literal. */ 687390075Sobrientree 687490075Sobriensimple_asm_stmt (expr) 687590075Sobrien tree expr; 687690075Sobrien{ 687790075Sobrien STRIP_NOPS (expr); 687890075Sobrien 687990075Sobrien if (TREE_CODE (expr) == ADDR_EXPR) 688090075Sobrien expr = TREE_OPERAND (expr, 0); 688190075Sobrien 688290075Sobrien if (TREE_CODE (expr) == STRING_CST) 688390075Sobrien { 688490075Sobrien tree stmt; 688590075Sobrien 688690075Sobrien if (TREE_CHAIN (expr)) 688790075Sobrien expr = combine_strings (expr); 688890075Sobrien stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr, 688990075Sobrien NULL_TREE, NULL_TREE, 689090075Sobrien NULL_TREE)); 689190075Sobrien ASM_INPUT_P (stmt) = 1; 689290075Sobrien return stmt; 689390075Sobrien } 689490075Sobrien 689590075Sobrien error ("argument of `asm' is not a constant string"); 689690075Sobrien return NULL_TREE; 689790075Sobrien} 689890075Sobrien 689990075Sobrien/* Build an asm-statement, whose components are a CV_QUALIFIER, a 690090075Sobrien STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */ 690190075Sobrien 690290075Sobrientree 690390075Sobrienbuild_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers) 690490075Sobrien tree cv_qualifier; 690590075Sobrien tree string; 690690075Sobrien tree outputs; 690790075Sobrien tree inputs; 690890075Sobrien tree clobbers; 690990075Sobrien{ 691090075Sobrien tree tail; 691190075Sobrien 691290075Sobrien if (TREE_CHAIN (string)) 691390075Sobrien string = combine_strings (string); 691490075Sobrien if (TREE_CODE (string) != STRING_CST) 691590075Sobrien { 691690075Sobrien error ("asm template is not a string constant"); 691790075Sobrien return NULL_TREE; 691890075Sobrien } 691990075Sobrien 692090075Sobrien if (cv_qualifier != NULL_TREE 692190075Sobrien && cv_qualifier != ridpointers[(int) RID_VOLATILE]) 692290075Sobrien { 692390075Sobrien warning ("%s qualifier ignored on asm", 692490075Sobrien IDENTIFIER_POINTER (cv_qualifier)); 692590075Sobrien cv_qualifier = NULL_TREE; 692690075Sobrien } 692790075Sobrien 692890075Sobrien /* We can remove output conversions that change the type, 692990075Sobrien but not the mode. */ 693090075Sobrien for (tail = outputs; tail; tail = TREE_CHAIN (tail)) 693190075Sobrien { 693290075Sobrien tree output = TREE_VALUE (tail); 693390075Sobrien 693490075Sobrien STRIP_NOPS (output); 693590075Sobrien TREE_VALUE (tail) = output; 693690075Sobrien 693790075Sobrien /* Allow conversions as LHS here. build_modify_expr as called below 693890075Sobrien will do the right thing with them. */ 693990075Sobrien while (TREE_CODE (output) == NOP_EXPR 694090075Sobrien || TREE_CODE (output) == CONVERT_EXPR 694190075Sobrien || TREE_CODE (output) == FLOAT_EXPR 694290075Sobrien || TREE_CODE (output) == FIX_TRUNC_EXPR 694390075Sobrien || TREE_CODE (output) == FIX_FLOOR_EXPR 694490075Sobrien || TREE_CODE (output) == FIX_ROUND_EXPR 694590075Sobrien || TREE_CODE (output) == FIX_CEIL_EXPR) 694690075Sobrien output = TREE_OPERAND (output, 0); 694790075Sobrien 694890075Sobrien lvalue_or_else (TREE_VALUE (tail), "invalid lvalue in asm statement"); 694990075Sobrien } 695090075Sobrien 695190075Sobrien /* Remove output conversions that change the type but not the mode. */ 695290075Sobrien for (tail = outputs; tail; tail = TREE_CHAIN (tail)) 695390075Sobrien { 695490075Sobrien tree output = TREE_VALUE (tail); 695590075Sobrien STRIP_NOPS (output); 695690075Sobrien TREE_VALUE (tail) = output; 695790075Sobrien } 695890075Sobrien 695990075Sobrien /* Perform default conversions on array and function inputs. 696090075Sobrien Don't do this for other types as it would screw up operands 696190075Sobrien expected to be in memory. */ 696290075Sobrien for (tail = inputs; tail; tail = TREE_CHAIN (tail)) 696390075Sobrien TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail)); 696490075Sobrien 696590075Sobrien return add_stmt (build_stmt (ASM_STMT, cv_qualifier, string, 696690075Sobrien outputs, inputs, clobbers)); 696790075Sobrien} 696890075Sobrien 696918334Speter/* Expand an ASM statement with operands, handling output operands 697018334Speter that are not variables or INDIRECT_REFS by transforming such 697118334Speter cases into cases that expand_asm_operands can handle. 697218334Speter 697318334Speter Arguments are same as for expand_asm_operands. */ 697418334Speter 697518334Spetervoid 697618334Speterc_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) 697718334Speter tree string, outputs, inputs, clobbers; 697818334Speter int vol; 697990075Sobrien const char *filename; 698018334Speter int line; 698118334Speter{ 698218334Speter int noutputs = list_length (outputs); 698390075Sobrien int i; 698418334Speter /* o[I] is the place that output number I should be written. */ 698590075Sobrien tree *o = (tree *) alloca (noutputs * sizeof (tree)); 698690075Sobrien tree tail; 698718334Speter 698818334Speter /* Record the contents of OUTPUTS before it is modified. */ 698918334Speter for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) 699018334Speter o[i] = TREE_VALUE (tail); 699118334Speter 699290075Sobrien /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of 699390075Sobrien OUTPUTS some trees for where the values were actually stored. */ 699418334Speter expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); 699518334Speter 699618334Speter /* Copy all the intermediate outputs into the specified outputs. */ 699718334Speter for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) 699818334Speter { 699918334Speter if (o[i] != TREE_VALUE (tail)) 700018334Speter { 700118334Speter expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), 700250397Sobrien NULL_RTX, VOIDmode, EXPAND_NORMAL); 700318334Speter free_temp_slots (); 700490075Sobrien 700590075Sobrien /* Restore the original value so that it's correct the next 700690075Sobrien time we expand this function. */ 700790075Sobrien TREE_VALUE (tail) = o[i]; 700818334Speter } 700918334Speter /* Detect modification of read-only values. 701018334Speter (Otherwise done by build_modify_expr.) */ 701118334Speter else 701218334Speter { 701318334Speter tree type = TREE_TYPE (o[i]); 701418334Speter if (TREE_READONLY (o[i]) 701518334Speter || TYPE_READONLY (type) 701618334Speter || ((TREE_CODE (type) == RECORD_TYPE 701718334Speter || TREE_CODE (type) == UNION_TYPE) 701818334Speter && C_TYPE_FIELDS_READONLY (type))) 701918334Speter readonly_warning (o[i], "modification by `asm'"); 702018334Speter } 702118334Speter } 702218334Speter 702318334Speter /* Those MODIFY_EXPRs could do autoincrements. */ 702418334Speter emit_queue (); 702518334Speter} 702618334Speter 702718334Speter/* Expand a C `return' statement. 702818334Speter RETVAL is the expression for what to return, 702918334Speter or a null pointer for `return;' with no value. */ 703018334Speter 703190075Sobrientree 703218334Speterc_expand_return (retval) 703318334Speter tree retval; 703418334Speter{ 703518334Speter tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)); 703618334Speter 703718334Speter if (TREE_THIS_VOLATILE (current_function_decl)) 703818334Speter warning ("function declared `noreturn' has a `return' statement"); 703918334Speter 704018334Speter if (!retval) 704118334Speter { 704218334Speter current_function_returns_null = 1; 704390075Sobrien if ((warn_return_type || flag_isoc99) 704490075Sobrien && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE) 704590075Sobrien pedwarn_c99 ("`return' with no value, in function returning non-void"); 704618334Speter } 704718334Speter else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE) 704818334Speter { 704918334Speter current_function_returns_null = 1; 705018334Speter if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) 705118334Speter pedwarn ("`return' with a value, in function returning void"); 705218334Speter } 705318334Speter else 705418334Speter { 705552284Sobrien tree t = convert_for_assignment (valtype, retval, _("return"), 705618334Speter NULL_TREE, NULL_TREE, 0); 705718334Speter tree res = DECL_RESULT (current_function_decl); 705818334Speter tree inner; 705918334Speter 706096263Sobrien current_function_returns_value = 1; 706118334Speter if (t == error_mark_node) 706290075Sobrien return NULL_TREE; 706318334Speter 706418334Speter inner = t = convert (TREE_TYPE (res), t); 706518334Speter 706618334Speter /* Strip any conversions, additions, and subtractions, and see if 706718334Speter we are returning the address of a local variable. Warn if so. */ 706818334Speter while (1) 706918334Speter { 707018334Speter switch (TREE_CODE (inner)) 707118334Speter { 707218334Speter case NOP_EXPR: case NON_LVALUE_EXPR: case CONVERT_EXPR: 707318334Speter case PLUS_EXPR: 707418334Speter inner = TREE_OPERAND (inner, 0); 707518334Speter continue; 707618334Speter 707718334Speter case MINUS_EXPR: 707818334Speter /* If the second operand of the MINUS_EXPR has a pointer 707918334Speter type (or is converted from it), this may be valid, so 708018334Speter don't give a warning. */ 708118334Speter { 708218334Speter tree op1 = TREE_OPERAND (inner, 1); 708318334Speter 708418334Speter while (! POINTER_TYPE_P (TREE_TYPE (op1)) 708518334Speter && (TREE_CODE (op1) == NOP_EXPR 708618334Speter || TREE_CODE (op1) == NON_LVALUE_EXPR 708718334Speter || TREE_CODE (op1) == CONVERT_EXPR)) 708818334Speter op1 = TREE_OPERAND (op1, 0); 708918334Speter 709018334Speter if (POINTER_TYPE_P (TREE_TYPE (op1))) 709118334Speter break; 709218334Speter 709318334Speter inner = TREE_OPERAND (inner, 0); 709418334Speter continue; 709518334Speter } 709618334Speter 709718334Speter case ADDR_EXPR: 709818334Speter inner = TREE_OPERAND (inner, 0); 709918334Speter 710018334Speter while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r') 710118334Speter inner = TREE_OPERAND (inner, 0); 710218334Speter 710318334Speter if (TREE_CODE (inner) == VAR_DECL 710418334Speter && ! DECL_EXTERNAL (inner) 710518334Speter && ! TREE_STATIC (inner) 710618334Speter && DECL_CONTEXT (inner) == current_function_decl) 710718334Speter warning ("function returns address of local variable"); 710818334Speter break; 710950397Sobrien 711050397Sobrien default: 711150397Sobrien break; 711218334Speter } 711318334Speter 711418334Speter break; 711518334Speter } 711618334Speter 711790075Sobrien retval = build (MODIFY_EXPR, TREE_TYPE (res), res, t); 711818334Speter } 711990075Sobrien 712090075Sobrien return add_stmt (build_return_stmt (retval)); 712118334Speter} 712218334Speter 712390075Sobrienstruct c_switch { 712490075Sobrien /* The SWITCH_STMT being built. */ 712590075Sobrien tree switch_stmt; 712690075Sobrien /* A splay-tree mapping the low element of a case range to the high 712790075Sobrien element, or NULL_TREE if there is no high element. Used to 712890075Sobrien determine whether or not a new case label duplicates an old case 712990075Sobrien label. We need a tree, rather than simply a hash table, because 713090075Sobrien of the GNU case range extension. */ 713190075Sobrien splay_tree cases; 713290075Sobrien /* The next node on the stack. */ 713390075Sobrien struct c_switch *next; 713490075Sobrien}; 713518334Speter 713690075Sobrien/* A stack of the currently active switch statements. The innermost 713790075Sobrien switch statement is on the top of the stack. There is no need to 713890075Sobrien mark the stack for garbage collection because it is only active 713990075Sobrien during the processing of the body of a function, and we never 714090075Sobrien collect at that point. */ 714190075Sobrien 714290075Sobrienstatic struct c_switch *switch_stack; 714390075Sobrien 714490075Sobrien/* Start a C switch statement, testing expression EXP. Return the new 714590075Sobrien SWITCH_STMT. */ 714690075Sobrien 714718334Spetertree 714890075Sobrienc_start_case (exp) 714918334Speter tree exp; 715018334Speter{ 715190075Sobrien enum tree_code code; 715296263Sobrien tree type, orig_type = error_mark_node; 715390075Sobrien struct c_switch *cs; 715418334Speter 715590075Sobrien if (exp != error_mark_node) 715618334Speter { 715790075Sobrien code = TREE_CODE (TREE_TYPE (exp)); 715896263Sobrien orig_type = TREE_TYPE (exp); 715990075Sobrien 716096263Sobrien if (! INTEGRAL_TYPE_P (orig_type) 716190075Sobrien && code != ERROR_MARK) 716290075Sobrien { 716390075Sobrien error ("switch quantity not an integer"); 716490075Sobrien exp = integer_zero_node; 716590075Sobrien } 716690075Sobrien else 716790075Sobrien { 716890075Sobrien type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); 716990075Sobrien 717090075Sobrien if (warn_traditional && !in_system_header 717190075Sobrien && (type == long_integer_type_node 717290075Sobrien || type == long_unsigned_type_node)) 717390075Sobrien warning ("`long' switch expression not converted to `int' in ISO C"); 717490075Sobrien 717590075Sobrien exp = default_conversion (exp); 717690075Sobrien type = TREE_TYPE (exp); 717790075Sobrien } 717818334Speter } 717918334Speter 718090075Sobrien /* Add this new SWITCH_STMT to the stack. */ 718190075Sobrien cs = (struct c_switch *) xmalloc (sizeof (*cs)); 718296263Sobrien cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type); 718390075Sobrien cs->cases = splay_tree_new (case_compare, NULL, NULL); 718490075Sobrien cs->next = switch_stack; 718590075Sobrien switch_stack = cs; 718618334Speter 718790075Sobrien return add_stmt (switch_stack->switch_stmt); 718890075Sobrien} 718990075Sobrien 719090075Sobrien/* Process a case label. */ 719190075Sobrien 719290075Sobrientree 719390075Sobriendo_case (low_value, high_value) 719490075Sobrien tree low_value; 719590075Sobrien tree high_value; 719690075Sobrien{ 719790075Sobrien tree label = NULL_TREE; 719890075Sobrien 719990075Sobrien if (switch_stack) 720090075Sobrien { 720190075Sobrien label = c_add_case_label (switch_stack->cases, 720290075Sobrien SWITCH_COND (switch_stack->switch_stmt), 720390075Sobrien low_value, high_value); 720490075Sobrien if (label == error_mark_node) 720590075Sobrien label = NULL_TREE; 720618334Speter } 720790075Sobrien else if (low_value) 720890075Sobrien error ("case label not within a switch statement"); 720990075Sobrien else 721090075Sobrien error ("`default' label not within a switch statement"); 721118334Speter 721290075Sobrien return label; 721390075Sobrien} 721418334Speter 721590075Sobrien/* Finish the switch statement. */ 721690075Sobrien 721790075Sobrienvoid 721890075Sobrienc_finish_case () 721990075Sobrien{ 722090075Sobrien struct c_switch *cs = switch_stack; 722190075Sobrien 722290075Sobrien RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt)); 722390075Sobrien 722490075Sobrien /* Pop the stack. */ 722590075Sobrien switch_stack = switch_stack->next; 722690075Sobrien splay_tree_delete (cs->cases); 722790075Sobrien free (cs); 722818334Speter} 7229