Annotation of GNUtools/cc/c-common.c, revision 1.1

1.1     ! root        1: /* Subroutines shared by all languages that are variants of C.
        !             2:    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: #include "config.h"
        !            21: #include "tree.h"
        !            22: #include "c-lex.h"
        !            23: #include "c-tree.h"
        !            24: #include "flags.h"
        !            25: #include "obstack.h"
        !            26: #include <stdio.h>
        !            27: #include <ctype.h>
        !            28: 
        !            29: extern struct obstack permanent_obstack;
        !            30: 
        !            31: static void declare_hidden_char_array PROTO((char *, char *));
        !            32: 
        !            33: /* Make bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
        !            34: 
        !            35: void
        !            36: declare_function_name ()
        !            37: {
        !            38:   char *name, *printable_name;
        !            39: 
        !            40:   if (current_function_decl == NULL)
        !            41:     {
        !            42:       name = "";
        !            43:       printable_name = "top level";
        !            44:     }
        !            45:   else
        !            46:     {
        !            47:       char *kind = "function";
        !            48:       if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
        !            49:        kind = "method";
        !            50:       /* Allow functions to be nameless (such as artificial ones).  */
        !            51:       if (DECL_NAME (current_function_decl))
        !            52:         name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
        !            53:       else
        !            54:        name = "";
        !            55:       printable_name = (*decl_printable_name) (current_function_decl, &kind);
        !            56:     }
        !            57: 
        !            58:   declare_hidden_char_array ("__FUNCTION__", name);
        !            59:   declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name);
        !            60: }
        !            61: 
        !            62: static void
        !            63: declare_hidden_char_array (name, value)
        !            64:      char *name, *value;
        !            65: {
        !            66:   tree decl, type, init;
        !            67:   int vlen;
        !            68: 
        !            69:   /* If the default size of char arrays isn't big enough for the name,
        !            70:      make a bigger one.  */
        !            71:   vlen = strlen (value) + 1;
        !            72:   type = char_array_type_node;
        !            73:   if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (type))) < vlen)
        !            74:     type = build_array_type (char_type_node,
        !            75:                             build_index_type (build_int_2 (vlen, 0)));
        !            76: 
        !            77:   push_obstacks_nochange ();
        !            78:   decl = build_decl (VAR_DECL, get_identifier (name), type);
        !            79:   TREE_STATIC (decl) = 1;
        !            80:   TREE_READONLY (decl) = 1;
        !            81:   TREE_ASM_WRITTEN (decl) = 1;
        !            82:   DECL_SOURCE_LINE (decl) = 0;
        !            83:   DECL_IN_SYSTEM_HEADER (decl) = 1;
        !            84:   DECL_IGNORED_P (decl) = 1;
        !            85:   init = build_string (vlen, value);
        !            86:   TREE_TYPE (init) = type;
        !            87:   DECL_INITIAL (decl) = init;
        !            88:   finish_decl (pushdecl (decl), init, NULL_TREE);
        !            89: }
        !            90: 
        !            91: /* Given a chain of STRING_CST nodes,
        !            92:    concatenate them into one STRING_CST
        !            93:    and give it a suitable array-of-chars data type.  */
        !            94: 
        !            95: tree
        !            96: combine_strings (strings)
        !            97:      tree strings;
        !            98: {
        !            99:   register tree value, t;
        !           100:   register int length = 1;
        !           101:   int wide_length = 0;
        !           102:   int wide_flag = 0;
        !           103:   int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
        !           104:   int nchars;
        !           105: 
        !           106:   if (TREE_CHAIN (strings))
        !           107:     {
        !           108:       /* More than one in the chain, so concatenate.  */
        !           109:       register char *p, *q;
        !           110: 
        !           111:       /* Don't include the \0 at the end of each substring,
        !           112:         except for the last one.
        !           113:         Count wide strings and ordinary strings separately.  */
        !           114:       for (t = strings; t; t = TREE_CHAIN (t))
        !           115:        {
        !           116:          if (TREE_TYPE (t) == wchar_array_type_node)
        !           117:            {
        !           118:              wide_length += (TREE_STRING_LENGTH (t) - wchar_bytes);
        !           119:              wide_flag = 1;
        !           120:            }
        !           121:          else
        !           122:            length += (TREE_STRING_LENGTH (t) - 1);
        !           123:        }
        !           124: 
        !           125:       /* If anything is wide, the non-wides will be converted,
        !           126:         which makes them take more space.  */
        !           127:       if (wide_flag)
        !           128:        length = length * wchar_bytes + wide_length;
        !           129: 
        !           130:       p = savealloc (length);
        !           131: 
        !           132:       /* Copy the individual strings into the new combined string.
        !           133:         If the combined string is wide, convert the chars to ints
        !           134:         for any individual strings that are not wide.  */
        !           135: 
        !           136:       q = p;
        !           137:       for (t = strings; t; t = TREE_CHAIN (t))
        !           138:        {
        !           139:          int len = (TREE_STRING_LENGTH (t)
        !           140:                     - ((TREE_TYPE (t) == wchar_array_type_node)
        !           141:                        ? wchar_bytes : 1));
        !           142:          if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag)
        !           143:            {
        !           144:              bcopy (TREE_STRING_POINTER (t), q, len);
        !           145:              q += len;
        !           146:            }
        !           147:          else
        !           148:            {
        !           149:              int i;
        !           150:              for (i = 0; i < len; i++)
        !           151:                ((int *) q)[i] = TREE_STRING_POINTER (t)[i];
        !           152:              q += len * wchar_bytes;
        !           153:            }
        !           154:        }
        !           155:       if (wide_flag)
        !           156:        {
        !           157:          int i;
        !           158:          for (i = 0; i < wchar_bytes; i++)
        !           159:            *q++ = 0;
        !           160:        }
        !           161:       else
        !           162:        *q = 0;
        !           163: 
        !           164:       value = make_node (STRING_CST);
        !           165:       TREE_STRING_POINTER (value) = p;
        !           166:       TREE_STRING_LENGTH (value) = length;
        !           167:       TREE_CONSTANT (value) = 1;
        !           168:     }
        !           169:   else
        !           170:     {
        !           171:       value = strings;
        !           172:       length = TREE_STRING_LENGTH (value);
        !           173:       if (TREE_TYPE (value) == wchar_array_type_node)
        !           174:        wide_flag = 1;
        !           175:     }
        !           176: 
        !           177:   /* Compute the number of elements, for the array type.  */ 
        !           178:   nchars = wide_flag ? length / wchar_bytes : length;
        !           179: 
        !           180:   /* Create the array type for the string constant.
        !           181:      -Wwrite-strings says make the string constant an array of const char
        !           182:      so that copying it to a non-const pointer will get a warning.  */
        !           183:   if (warn_write_strings
        !           184:       && (! flag_traditional  && ! flag_writable_strings))
        !           185:     {
        !           186:       tree elements
        !           187:        = build_type_variant (wide_flag ? wchar_type_node : char_type_node,
        !           188:                              1, 0);
        !           189:       TREE_TYPE (value)
        !           190:        = build_array_type (elements,
        !           191:                            build_index_type (build_int_2 (nchars - 1, 0)));
        !           192:     }
        !           193:   else
        !           194:     TREE_TYPE (value)
        !           195:       = build_array_type (wide_flag ? wchar_type_node : char_type_node,
        !           196:                          build_index_type (build_int_2 (nchars - 1, 0)));
        !           197:   TREE_CONSTANT (value) = 1;
        !           198:   TREE_STATIC (value) = 1;
        !           199:   return value;
        !           200: }
        !           201: 
        !           202: /* Process the attributes listed in ATTRIBUTES
        !           203:    and install them in DECL.  */
        !           204: 
        !           205: void
        !           206: decl_attributes (decl, attributes)
        !           207:      tree decl, attributes;
        !           208: {
        !           209:   tree a;
        !           210:   for (a = attributes; a; a = TREE_CHAIN (a))
        !           211:     if (TREE_VALUE (a) == get_identifier ("packed"))
        !           212:       {
        !           213:        if (TREE_CODE (decl) == FIELD_DECL)
        !           214:          DECL_PACKED (decl) = 1;
        !           215:        /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
        !           216:           used for DECL_REGISTER.  It wouldn't mean anything anyway.  */
        !           217:       }
        !           218:     else if (TREE_VALUE (a) == get_identifier ("noreturn")
        !           219:             || TREE_VALUE (a) == get_identifier ("volatile"))
        !           220:       {
        !           221:        if (TREE_CODE (decl) == FUNCTION_DECL)
        !           222:          TREE_THIS_VOLATILE (decl) = 1;
        !           223:       }
        !           224:     else if (TREE_VALUE (a) == get_identifier ("const"))
        !           225:       {
        !           226:        if (TREE_CODE (decl) == FUNCTION_DECL)
        !           227:          TREE_READONLY (decl) = 1;
        !           228:       }
        !           229:     else if (TREE_VALUE (a) == get_identifier ("offset"))
        !           230:       {
        !           231:        if (TREE_CODE (decl) == FIELD_DECL
        !           232:            || TREE_CODE (decl) == VAR_DECL)
        !           233:          TREE_SELF_OFFSET (decl) = 1;
        !           234:       }
        !           235:     else if (TREE_VALUE (a) != 0
        !           236:             && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
        !           237:             && TREE_PURPOSE (TREE_VALUE (a)) == get_identifier ("mode"))
        !           238:       {
        !           239:        int i;
        !           240:        char *specified_name
        !           241:          = IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (a)));
        !           242: 
        !           243:        /* Give this decl a type with the specified mode.  */
        !           244:        for (i = 0; i < NUM_MACHINE_MODES; i++)
        !           245:          if (!strcmp (specified_name, GET_MODE_NAME (i)))
        !           246:            {
        !           247:              tree type
        !           248:                = type_for_mode (i, TREE_UNSIGNED (TREE_TYPE (decl)));
        !           249:              if (type != 0)
        !           250:                {
        !           251:                  TREE_TYPE (decl) = type;
        !           252:                  DECL_SIZE (decl) = 0;
        !           253:                  layout_decl (decl, 0);
        !           254:                }
        !           255:              else
        !           256:                error ("no data type for mode `%s'", specified_name);
        !           257:              break;
        !           258:            }
        !           259:        if (i == NUM_MACHINE_MODES)
        !           260:          error ("unknown machine mode `%s'", specified_name);
        !           261:       }
        !           262:     else if (TREE_VALUE (a) != 0
        !           263:             && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
        !           264:             && TREE_PURPOSE (TREE_VALUE (a)) == get_identifier ("aligned"))
        !           265:       {
        !           266:        int align = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (a)))
        !           267:                    * BITS_PER_UNIT;
        !           268:        
        !           269:        if (exact_log2 (align) == -1)
        !           270:          error_with_decl (decl,
        !           271:                           "requested alignment of `%s' is not a power of 2");
        !           272:        else if (TREE_CODE (decl) != VAR_DECL
        !           273:                 && TREE_CODE (decl) != FIELD_DECL)
        !           274:          error_with_decl (decl,
        !           275:                           "alignment specified for `%s'");
        !           276:        else
        !           277:          DECL_ALIGN (decl) = align;
        !           278:       }
        !           279:     else if (TREE_VALUE (a) != 0
        !           280:             && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
        !           281:             && TREE_PURPOSE (TREE_VALUE (a)) == get_identifier ("format"))
        !           282:       {
        !           283:         tree list = TREE_VALUE (TREE_VALUE (a));
        !           284:         tree format_type = TREE_PURPOSE (list);
        !           285:        int format_num = TREE_INT_CST_LOW (TREE_PURPOSE (TREE_VALUE (list)));
        !           286:        int first_arg_num = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (list)));
        !           287:        int is_scan;
        !           288:        tree argument;
        !           289:        int arg_num;
        !           290:        
        !           291:        if (TREE_CODE (decl) != FUNCTION_DECL)
        !           292:          {
        !           293:            error_with_decl (decl,
        !           294:                             "argument format specified for non-function `%s'");
        !           295:            return;
        !           296:          }
        !           297:        
        !           298:        if (format_type == get_identifier ("printf"))
        !           299:          is_scan = 0;
        !           300:        else if (format_type == get_identifier ("scanf"))
        !           301:          is_scan = 1;
        !           302:        else
        !           303:          {
        !           304:            error_with_decl (decl, "unrecognized format specifier for `%s'");
        !           305:            return;
        !           306:          }
        !           307:        
        !           308:        if (first_arg_num != 0 && first_arg_num <= format_num)
        !           309:          {
        !           310:            error_with_decl (decl,
        !           311:                "format string arg follows the args to be formatted, for `%s'");
        !           312:            return;
        !           313:          }
        !           314: 
        !           315:        /* Verify that the format_num argument is actually a string, in case
        !           316:           the format attribute is in error.  */
        !           317:        argument = TYPE_ARG_TYPES (TREE_TYPE (decl));
        !           318:        for (arg_num = 1; ; ++arg_num)
        !           319:          {
        !           320:            if (argument == 0 || arg_num == format_num)
        !           321:              break;
        !           322:            argument = TREE_CHAIN (argument);
        !           323:          }
        !           324:        if (! argument
        !           325:            || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
        !           326:            || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
        !           327:                != char_type_node))
        !           328:          {
        !           329:            error_with_decl (decl,
        !           330:                             "format string arg not a string type, for `%s'");
        !           331:            return;
        !           332:          }
        !           333:        if (first_arg_num != 0)
        !           334:          {
        !           335:            /* Verify that first_arg_num points to the last arg, the ... */
        !           336:            while (argument)
        !           337:              arg_num++, argument = TREE_CHAIN (argument);
        !           338:            if (arg_num != first_arg_num)
        !           339:              {
        !           340:                error_with_decl (decl,
        !           341:                                 "args to be formatted is not ..., for `%s'");
        !           342:                return;
        !           343:              }
        !           344:          }
        !           345: 
        !           346:        record_function_format (DECL_NAME (decl), DECL_ASSEMBLER_NAME (decl),
        !           347:                                is_scan, format_num, first_arg_num);
        !           348:       }
        !           349: }
        !           350: 
        !           351: /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against
        !           352:    a parameter list.  */
        !           353: 
        !           354: #define T_I    &integer_type_node
        !           355: #define T_L    &long_integer_type_node
        !           356: #define T_S    &short_integer_type_node
        !           357: #define T_UI   &unsigned_type_node
        !           358: #define T_UL   &long_unsigned_type_node
        !           359: #define T_US   &short_unsigned_type_node
        !           360: #define T_F    &float_type_node
        !           361: #define T_D    &double_type_node
        !           362: #define T_LD   &long_double_type_node
        !           363: #define T_C    &char_type_node
        !           364: #define T_V    &void_type_node
        !           365: #define T_W    &wchar_type_node
        !           366: 
        !           367: typedef struct {
        !           368:   char *format_chars;
        !           369:   int pointer_count;
        !           370:   /* Type of argument if no length modifier is used.  */
        !           371:   tree *nolen;
        !           372:   /* Type of argument if length modifier for shortening is used.
        !           373:      If NULL, then this modifier is not allowed.  */
        !           374:   tree *hlen;
        !           375:   /* Type of argument if length modifier `l' is used.
        !           376:      If NULL, then this modifier is not allowed.  */
        !           377:   tree *llen;
        !           378:   /* Type of argument if length modifier `L' is used.
        !           379:      If NULL, then this modifier is not allowed.  */
        !           380:   tree *bigllen;
        !           381:   /* List of other modifier characters allowed with these options.  */
        !           382:   char *flag_chars;
        !           383: } format_char_info;
        !           384: 
        !           385: static format_char_info print_char_table[] = {
        !           386:   { "di",      0,      T_I,    T_I,    T_L,    NULL,   "-wp0 +"        },
        !           387:   { "oxX",     0,      T_UI,   T_UI,   T_UL,   NULL,   "-wp0#"         },
        !           388:   { "u",       0,      T_UI,   T_UI,   T_UL,   NULL,   "-wp0"          },
        !           389:   { "feEgG",   0,      T_D,    NULL,   NULL,   T_LD,   "-wp0 +#"       },
        !           390:   { "c",       0,      T_I,    NULL,   T_W,    NULL,   "-w"            },
        !           391:   { "C",       0,      T_W,    NULL,   NULL,   NULL,   "-w"            },
        !           392:   { "s",       1,      T_C,    NULL,   T_W,    NULL,   "-wp"           },
        !           393:   { "S",       1,      T_W,    NULL,   NULL,   NULL,   "-wp"           },
        !           394:   { "p",       1,      T_V,    NULL,   NULL,   NULL,   "-w"            },
        !           395:   { "n",       1,      T_I,    T_S,    T_L,    NULL,   ""              },
        !           396:   { NULL }
        !           397: };
        !           398: 
        !           399: static format_char_info scan_char_table[] = {
        !           400:   { "di",      1,      T_I,    T_S,    T_L,    NULL,   "*"     },
        !           401:   { "ouxX",    1,      T_UI,   T_US,   T_UL,   NULL,   "*"     },      
        !           402:   { "efgEG",   1,      T_F,    NULL,   T_D,    T_LD,   "*"     },
        !           403:   { "sc",      1,      T_C,    NULL,   T_W,    NULL,   "*"     },
        !           404:   { "[",       1,      T_C,    NULL,   NULL,   NULL,   "*"     },
        !           405:   { "C",       1,      T_W,    NULL,   NULL,   NULL,   "*"     },
        !           406:   { "S",       1,      T_W,    NULL,   NULL,   NULL,   "*"     },
        !           407:   { "p",       2,      T_V,    NULL,   NULL,   NULL,   "*"     },
        !           408:   { "n",       1,      T_I,    T_S,    T_L,    NULL,   ""      },
        !           409:   { NULL }
        !           410: };
        !           411: 
        !           412: typedef struct function_format_info {
        !           413:   struct function_format_info *next;  /* next structure on the list */
        !           414:   tree name;                   /* identifier such as "printf" */
        !           415:   tree assembler_name;         /* optional mangled identifier (for C++) */
        !           416:   int is_scan;                 /* TRUE if *scanf */
        !           417:   int format_num;              /* number of format argument */
        !           418:   int first_arg_num;           /* number of first arg (zero for varargs) */
        !           419: } function_format_info;
        !           420: 
        !           421: static function_format_info *function_format_list = NULL;
        !           422: 
        !           423: static void check_format_info PROTO((function_format_info *, tree));
        !           424: 
        !           425: /* Initialize the table of functions to perform format checking on.
        !           426:    The ANSI functions are always checked (whether <stdio.h> is
        !           427:    included or not), since it is common to call printf without
        !           428:    including <stdio.h>.  There shouldn't be a problem with this,
        !           429:    since ANSI reserves these function names whether you include the
        !           430:    header file or not.  In any case, the checking is harmless.  */
        !           431: 
        !           432: void
        !           433: init_function_format_info ()
        !           434: {
        !           435:   record_function_format (get_identifier ("printf"), NULL_TREE, 0, 1, 2);
        !           436:   record_function_format (get_identifier ("fprintf"), NULL_TREE, 0, 2, 3);
        !           437:   record_function_format (get_identifier ("sprintf"), NULL_TREE, 0, 2, 3);
        !           438:   record_function_format (get_identifier ("scanf"), NULL_TREE, 1, 1, 2);
        !           439:   record_function_format (get_identifier ("fscanf"), NULL_TREE, 1, 2, 3);
        !           440:   record_function_format (get_identifier ("sscanf"), NULL_TREE, 1, 2, 3);
        !           441:   record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
        !           442:   record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
        !           443:   record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
        !           444: }
        !           445: 
        !           446: /* Record information for argument format checking.  FUNCTION_IDENT is
        !           447:    the identifier node for the name of the function to check (its decl
        !           448:    need not exist yet).  IS_SCAN is true for scanf-type format checking;
        !           449:    false indicates printf-style format checking.  FORMAT_NUM is the number
        !           450:    of the argument which is the format control string (starting from 1).
        !           451:    FIRST_ARG_NUM is the number of the first actual argument to check
        !           452:    against teh format string, or zero if no checking is not be done
        !           453:    (e.g. for varargs such as vfprintf).  */
        !           454: 
        !           455: void
        !           456: record_function_format (name, assembler_name, is_scan,
        !           457:                        format_num, first_arg_num)
        !           458:       tree name;
        !           459:       tree assembler_name;
        !           460:       int is_scan;
        !           461:       int format_num;
        !           462:       int first_arg_num;
        !           463: {
        !           464:   function_format_info *info;
        !           465: 
        !           466:   /* Re-use existing structure if it's there.  */
        !           467: 
        !           468:   for (info = function_format_list; info; info = info->next)
        !           469:     {
        !           470:       if (info->name == name && info->assembler_name == assembler_name)
        !           471:        break;
        !           472:     }
        !           473:   if (! info)
        !           474:     {
        !           475:       info = (function_format_info *) xmalloc (sizeof (function_format_info));
        !           476:       info->next = function_format_list;
        !           477:       function_format_list = info;
        !           478: 
        !           479:       info->name = name;
        !           480:       info->assembler_name = assembler_name;
        !           481:     }
        !           482: 
        !           483:   info->is_scan = is_scan;
        !           484:   info->format_num = format_num;
        !           485:   info->first_arg_num = first_arg_num;
        !           486: }
        !           487: 
        !           488: static char    tfaff[] = "too few arguments for format";
        !           489: 
        !           490: /* Check the argument list of a call to printf, scanf, etc.
        !           491:    NAME is the function identifier.
        !           492:    ASSEMBLER_NAME is the function's assembler identifier.
        !           493:    (Either NAME or ASSEMBLER_NAME, but not both, may be NULL_TREE.)
        !           494:    PARAMS is the list of argument values.  */
        !           495: 
        !           496: void
        !           497: check_function_format (name, assembler_name, params)
        !           498:      tree name;
        !           499:      tree assembler_name;
        !           500:      tree params;
        !           501: {
        !           502:   function_format_info *info;
        !           503: 
        !           504:   /* See if this function is a format function.  */
        !           505:   for (info = function_format_list; info; info = info->next)
        !           506:     {
        !           507:       if (info->assembler_name
        !           508:          ? (info->assembler_name == assembler_name)
        !           509:          : (info->name == name))
        !           510:        {
        !           511:          /* Yup; check it.  */
        !           512:          check_format_info (info, params);
        !           513:          break;
        !           514:        }
        !           515:     }
        !           516: }
        !           517: 
        !           518: /* Check the argument list of a call to printf, scanf, etc.
        !           519:    INFO points to the function_format_info structure.
        !           520:    PARAMS is the list of argument values.  */
        !           521: 
        !           522: static void
        !           523: check_format_info (info, params)
        !           524:      function_format_info *info;
        !           525:      tree params;
        !           526: {
        !           527:   int i;
        !           528:   int arg_num;
        !           529:   int suppressed, wide, precise;
        !           530:   int length_char;
        !           531:   int format_char;
        !           532:   int format_length;
        !           533:   tree format_tree;
        !           534:   tree cur_param;
        !           535:   tree cur_type;
        !           536:   tree wanted_type;
        !           537:   tree first_fillin_param;
        !           538:   char *format_chars;
        !           539:   format_char_info *fci;
        !           540:   static char message[132];
        !           541:   char flag_chars[8];
        !           542:   int has_operand_number = 0;
        !           543: 
        !           544:   /* Skip to format argument.  If the argument isn't available, there's
        !           545:      no work for us to do; prototype checking will catch the problem.  */
        !           546:   for (arg_num = 1; ; ++arg_num)
        !           547:     {
        !           548:       if (params == 0)
        !           549:        return;
        !           550:       if (arg_num == info->format_num)
        !           551:        break;
        !           552:       params = TREE_CHAIN (params);
        !           553:     }
        !           554:   format_tree = TREE_VALUE (params);
        !           555:   params = TREE_CHAIN (params);
        !           556:   if (format_tree == 0)
        !           557:     return;
        !           558:   /* We can only check the format if it's a string constant.  */
        !           559:   while (TREE_CODE (format_tree) == NOP_EXPR)
        !           560:     format_tree = TREE_OPERAND (format_tree, 0); /* strip coercion */
        !           561:   if (format_tree == null_pointer_node)
        !           562:     {
        !           563:       warning ("null format string");
        !           564:       return;
        !           565:     }
        !           566:   if (TREE_CODE (format_tree) != ADDR_EXPR)
        !           567:     return;
        !           568:   format_tree = TREE_OPERAND (format_tree, 0);
        !           569:   if (TREE_CODE (format_tree) != STRING_CST)
        !           570:     return;
        !           571:   format_chars = TREE_STRING_POINTER (format_tree);
        !           572:   format_length = TREE_STRING_LENGTH (format_tree);
        !           573:   if (format_length <= 1)
        !           574:     warning ("zero-length format string");
        !           575:   if (format_chars[--format_length] != 0)
        !           576:     {
        !           577:       warning ("unterminated format string");
        !           578:       return;
        !           579:     }
        !           580:   /* Skip to first argument to check.  */
        !           581:   while (arg_num + 1 < info->first_arg_num)
        !           582:     {
        !           583:       if (params == 0)
        !           584:        return;
        !           585:       params = TREE_CHAIN (params);
        !           586:       ++arg_num;
        !           587:     }
        !           588: 
        !           589:   first_fillin_param = params;
        !           590:   while (1)
        !           591:     {
        !           592:       if (*format_chars == 0)
        !           593:        {
        !           594:          if (format_chars - TREE_STRING_POINTER (format_tree) != format_length)
        !           595:            warning ("embedded `\\0' in format");
        !           596:          if (info->first_arg_num != 0 && params != 0 && ! has_operand_number)
        !           597:            warning ("too many arguments for format");
        !           598:          return;
        !           599:        }
        !           600:       if (*format_chars++ != '%')
        !           601:        continue;
        !           602:       if (*format_chars == 0)
        !           603:        {
        !           604:          warning ("spurious trailing `%%' in format");
        !           605:          continue;
        !           606:        }
        !           607:       if (*format_chars == '%')
        !           608:        {
        !           609:          ++format_chars;
        !           610:          continue;
        !           611:        }
        !           612:       flag_chars[0] = 0;
        !           613:       suppressed = wide = precise = FALSE;
        !           614:       if (info->is_scan)
        !           615:        {
        !           616:          suppressed = *format_chars == '*';
        !           617:          if (suppressed)
        !           618:            ++format_chars;
        !           619:          while (isdigit (*format_chars))
        !           620:            ++format_chars;
        !           621:        }
        !           622:       else
        !           623:        {
        !           624:          /* See if we have a number followed by a dollar sign.  If we do,
        !           625:             it is an operand number, so set PARAMS to that operand.  */
        !           626:          if (*format_chars >= '0' && *format_chars <= '9')
        !           627:            {
        !           628:              char *p = format_chars;
        !           629: 
        !           630:              while (*p >= '0' && *p++ <= '9')
        !           631:                ;
        !           632: 
        !           633:              if (*p == '$')
        !           634:                {
        !           635:                  int opnum = atoi (format_chars);
        !           636: 
        !           637:                  params = first_fillin_param;
        !           638:                  format_chars = p + 1;
        !           639:                  has_operand_number = 1;
        !           640: 
        !           641:                  for (i = 1; i < opnum && params != 0; i++)
        !           642:                    params = TREE_CHAIN (params);
        !           643: 
        !           644:                  if (opnum == 0 || params == 0)
        !           645:                    {
        !           646:                      warning ("operand number out of range in format");
        !           647:                      return;
        !           648:                    }
        !           649:                }
        !           650:            }
        !           651: 
        !           652:          while (*format_chars != 0 && index (" +#0-", *format_chars) != 0)
        !           653:            {
        !           654:              if (index (flag_chars, *format_chars) != 0)
        !           655:                {
        !           656:                  sprintf (message, "repeated `%c' flag in format",
        !           657:                           *format_chars);
        !           658:                  warning (message);
        !           659:                }
        !           660:              i = strlen (flag_chars);
        !           661:              flag_chars[i++] = *format_chars++;
        !           662:              flag_chars[i] = 0;
        !           663:            }
        !           664:          /* "If the space and + flags both appear, 
        !           665:             the space flag will be ignored."  */
        !           666:          if (index (flag_chars, ' ') != 0
        !           667:              && index (flag_chars, '+') != 0)
        !           668:            warning ("use of both ` ' and `+' flags in format");
        !           669:          /* "If the 0 and - flags both appear,
        !           670:             the 0 flag will be ignored."  */
        !           671:          if (index (flag_chars, '0') != 0
        !           672:              && index (flag_chars, '-') != 0)
        !           673:            warning ("use of both `0' and `-' flags in format");
        !           674:          if (*format_chars == '*')
        !           675:            {
        !           676:              wide = TRUE;
        !           677:              /* "...a field width...may be indicated by an asterisk.
        !           678:                 In this case, an int argument supplies the field width..."  */
        !           679:              ++format_chars;
        !           680:              if (params == 0)
        !           681:                {
        !           682:                  warning (tfaff);
        !           683:                  return;
        !           684:                }
        !           685:              if (info->first_arg_num != 0)
        !           686:                {
        !           687:                  cur_param = TREE_VALUE (params);
        !           688:                  params = TREE_CHAIN (params);
        !           689:                  ++arg_num;
        !           690:                  /* size_t is generally not valid here.
        !           691:                     It will work on most machines, because size_t and int
        !           692:                     have the same mode.  But might as well warn anyway,
        !           693:                     since it will fail on other machines.  */
        !           694:                  if ((TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
        !           695:                       != integer_type_node)
        !           696:                      &&
        !           697:                      (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
        !           698:                       != unsigned_type_node))
        !           699:                    {
        !           700:                      sprintf (message,
        !           701:                               "field width is not type int (arg %d)",
        !           702:                               arg_num);
        !           703:                      warning (message);
        !           704:                    }
        !           705:                }
        !           706:            }
        !           707:          else
        !           708:            {
        !           709:              while (isdigit (*format_chars))
        !           710:                {
        !           711:                  wide = TRUE;
        !           712:                  ++format_chars;
        !           713:                }
        !           714:            }
        !           715:          if (*format_chars == '.')
        !           716:            {
        !           717:              precise = TRUE;
        !           718:              ++format_chars;
        !           719:              if (*format_chars != '*' && !isdigit (*format_chars))
        !           720:                warning ("`.' not followed by `*' or digit in format");
        !           721:              /* "...a...precision...may be indicated by an asterisk.
        !           722:                 In this case, an int argument supplies the...precision."  */
        !           723:              if (*format_chars == '*')
        !           724:                {
        !           725:                  if (info->first_arg_num != 0)
        !           726:                    {
        !           727:                      ++format_chars;
        !           728:                      if (params == 0)
        !           729:                        {
        !           730:                          warning (tfaff);
        !           731:                          return;
        !           732:                        }
        !           733:                      cur_param = TREE_VALUE (params);
        !           734:                      params = TREE_CHAIN (params);
        !           735:                      ++arg_num;
        !           736:                      if (TYPE_MAIN_VARIANT (TREE_TYPE (cur_param))
        !           737:                          != integer_type_node)
        !           738:                        {
        !           739:                          sprintf (message,
        !           740:                                   "field width is not type int (arg %d)",
        !           741:                                   arg_num);
        !           742:                          warning (message);
        !           743:                        }
        !           744:                    }
        !           745:                }
        !           746:              else
        !           747:                {
        !           748:                  while (isdigit (*format_chars))
        !           749:                    ++format_chars;
        !           750:                }
        !           751:            }
        !           752:        }
        !           753:       if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'L')
        !           754:        length_char = *format_chars++;
        !           755:       else
        !           756:        length_char = 0;
        !           757:       if (suppressed && length_char != 0)
        !           758:        {
        !           759:          sprintf (message,
        !           760:                   "use of `*' and `%c' together in format",
        !           761:                   length_char);
        !           762:          warning (message);
        !           763:        }
        !           764:       format_char = *format_chars;
        !           765:       if (format_char == 0)
        !           766:        {
        !           767:          warning ("conversion lacks type at end of format");
        !           768:          continue;
        !           769:        }
        !           770:       format_chars++;
        !           771:       fci = info->is_scan ? scan_char_table : print_char_table;
        !           772:       while (fci->format_chars != 0
        !           773:             && index (fci->format_chars, format_char) == 0)
        !           774:          ++fci;
        !           775:       if (fci->format_chars == 0)
        !           776:        {
        !           777:          if (format_char >= 040 && format_char < 0177)
        !           778:            sprintf (message,
        !           779:                     "unknown conversion type character `%c' in format",
        !           780:                     format_char);
        !           781:          else
        !           782:            sprintf (message,
        !           783:                     "unknown conversion type character 0x%x in format",
        !           784:                     format_char);
        !           785:          warning (message);
        !           786:          continue;
        !           787:        }
        !           788:       if (wide && index (fci->flag_chars, 'w') == 0)
        !           789:        {
        !           790:          sprintf (message, "width used with `%c' format",
        !           791:                   format_char);
        !           792:          warning (message);
        !           793:        }
        !           794:       if (precise && index (fci->flag_chars, 'p') == 0)
        !           795:        {
        !           796:          sprintf (message, "precision used with `%c' format",
        !           797:                   format_char);
        !           798:          warning (message);
        !           799:        }
        !           800:       if (info->is_scan && format_char == '[')
        !           801:        {
        !           802:          /* Skip over scan set, in case it happens to have '%' in it.  */
        !           803:          if (*format_chars == '^')
        !           804:            ++format_chars;
        !           805:          /* Find closing bracket; if one is hit immediately, then
        !           806:             it's part of the scan set rather than a terminator.  */
        !           807:          if (*format_chars == ']')
        !           808:            ++format_chars;
        !           809:          while (*format_chars && *format_chars != ']')
        !           810:            ++format_chars;
        !           811:          if (*format_chars != ']')
        !           812:              /* The end of the format string was reached.  */
        !           813:              warning ("no closing `]' for `%%[' format");
        !           814:        }
        !           815:       if (suppressed)
        !           816:        {
        !           817:          if (index (fci->flag_chars, '*') == 0)
        !           818:            {
        !           819:              sprintf (message,
        !           820:                       "suppression of `%c' conversion in format",
        !           821:                       format_char);
        !           822:              warning (message);
        !           823:            }
        !           824:          continue;
        !           825:        }
        !           826:       for (i = 0; flag_chars[i] != 0; ++i)
        !           827:        {
        !           828:          if (index (fci->flag_chars, flag_chars[i]) == 0)
        !           829:            {
        !           830:              sprintf (message, "flag `%c' used with type `%c'",
        !           831:                       flag_chars[i], format_char);
        !           832:              warning (message);
        !           833:            }
        !           834:        }
        !           835:       if (precise && index (flag_chars, '0') != 0
        !           836:          && (format_char == 'd' || format_char == 'i'
        !           837:              || format_char == 'o' || format_char == 'u'
        !           838:              || format_char == 'x' || format_char == 'x'))
        !           839:        {
        !           840:          sprintf (message,
        !           841:                   "precision and `0' flag not both allowed with `%c' format",
        !           842:                   format_char);
        !           843:          warning (message);
        !           844:        }
        !           845:       switch (length_char)
        !           846:        {
        !           847:        default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break;
        !           848:        case 'h': wanted_type = fci->hlen ? *(fci->hlen) : 0; break;
        !           849:        case 'l': wanted_type = fci->llen ? *(fci->llen) : 0; break;
        !           850:        case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
        !           851:        }
        !           852:       if (wanted_type == 0)
        !           853:        {
        !           854:          sprintf (message,
        !           855:                   "use of `%c' length character with `%c' type character",
        !           856:                   length_char, format_char);
        !           857:          warning (message);
        !           858:        }
        !           859: 
        !           860:       /*
        !           861:        ** XXX -- should kvetch about stuff such as
        !           862:        **      {
        !           863:        **              const int       i;
        !           864:        **
        !           865:        **              scanf ("%d", &i);
        !           866:        **      }
        !           867:        */
        !           868: 
        !           869:       /* Finally. . .check type of argument against desired type!  */
        !           870:       if (info->first_arg_num == 0)
        !           871:        continue;
        !           872:       if (params == 0)
        !           873:        {
        !           874:          warning (tfaff);
        !           875:          return;
        !           876:        }
        !           877:       cur_param = TREE_VALUE (params);
        !           878:       params = TREE_CHAIN (params);
        !           879:       ++arg_num;
        !           880:       cur_type = TREE_TYPE (cur_param);
        !           881: 
        !           882:       /* Check the types of any additional pointer arguments
        !           883:         that precede the "real" argument.  */
        !           884:       for (i = 0; i < fci->pointer_count; ++i)
        !           885:        {
        !           886:          if (TREE_CODE (cur_type) == POINTER_TYPE)
        !           887:            {
        !           888:              cur_type = TREE_TYPE (cur_type);
        !           889:              continue;
        !           890:            }
        !           891:          sprintf (message,
        !           892:                   "format argument is not a %s (arg %d)",
        !           893:                   ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"),
        !           894:                   arg_num);
        !           895:          warning (message);
        !           896:          break;
        !           897:        }
        !           898: 
        !           899:       /* Check the type of the "real" argument, if there's a type we want.  */
        !           900:       if (i == fci->pointer_count && wanted_type != 0
        !           901:          && wanted_type != TYPE_MAIN_VARIANT (cur_type)
        !           902:          /* If we want `void *', allow any pointer type.
        !           903:             (Anything else would already have got a warning.)  */
        !           904:          && ! (wanted_type == void_type_node
        !           905:                && fci->pointer_count > 0)
        !           906:          /* Don't warn about differences merely in signedness.  */
        !           907:          && !(TREE_CODE (wanted_type) == INTEGER_TYPE
        !           908:               && TREE_CODE (TYPE_MAIN_VARIANT (cur_type)) == INTEGER_TYPE
        !           909:               && (TREE_UNSIGNED (wanted_type)
        !           910:                   ? wanted_type == (cur_type = unsigned_type (cur_type))
        !           911:                   : wanted_type == (cur_type = signed_type (cur_type))))
        !           912:          /* Likewise, "signed char", "unsigned char" and "char" are
        !           913:             equivalent but the above test won't consider them equivalent.  */
        !           914:          && ! (wanted_type == char_type_node
        !           915:                && (TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node
        !           916:                    || TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node)))
        !           917:        {
        !           918:          register char *this;
        !           919:          register char *that;
        !           920:   
        !           921:          this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
        !           922:          that = 0;
        !           923:          if (TREE_CODE (cur_type) != ERROR_MARK
        !           924:              && TYPE_NAME (cur_type) != 0
        !           925:              && TREE_CODE (cur_type) != INTEGER_TYPE
        !           926:              && !(TREE_CODE (cur_type) == POINTER_TYPE
        !           927:                   && TREE_CODE (TREE_TYPE (cur_type)) == INTEGER_TYPE))
        !           928:            {
        !           929:              if (TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL
        !           930:                  && DECL_NAME (TYPE_NAME (cur_type)) != 0)
        !           931:                that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
        !           932:              else
        !           933:                that = IDENTIFIER_POINTER (TYPE_NAME (cur_type));
        !           934:            }
        !           935: 
        !           936:          /* A nameless type can't possibly match what the format wants.
        !           937:             So there will be a warning for it.
        !           938:             Make up a string to describe vaguely what it is.  */
        !           939:          if (that == 0)
        !           940:            {
        !           941:              if (TREE_CODE (cur_type) == POINTER_TYPE)
        !           942:                that = "pointer";
        !           943:              else
        !           944:                that = "different type";
        !           945:            }
        !           946: 
        !           947:          /* Make the warning better in case of mismatch of int vs long.  */
        !           948:          if (TREE_CODE (cur_type) == INTEGER_TYPE
        !           949:              && TREE_CODE (wanted_type) == INTEGER_TYPE
        !           950:              && TYPE_PRECISION (cur_type) == TYPE_PRECISION (wanted_type)
        !           951:              && TYPE_NAME (cur_type) != 0
        !           952:              && TREE_CODE (TYPE_NAME (cur_type)) == TYPE_DECL)
        !           953:            that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (cur_type)));
        !           954: 
        !           955:          if (strcmp (this, that) != 0)
        !           956:            {
        !           957:              sprintf (message, "%s format, %s arg (arg %d)",
        !           958:                        this, that, arg_num);
        !           959:              warning (message);
        !           960:            }
        !           961:        }
        !           962:     }
        !           963: }
        !           964: 
        !           965: /* Print a warning if a constant expression had overflow in folding.
        !           966:    Invoke this function on every expression that the language
        !           967:    requires to be a constant expression.
        !           968:    Note the ANSI C standard says it is erroneous for a
        !           969:    constant expression to overflow.  */
        !           970: 
        !           971: void
        !           972: constant_expression_warning (value)
        !           973:      tree value;
        !           974: {
        !           975:   if (TREE_CODE (value) == INTEGER_CST && TREE_CONSTANT_OVERFLOW (value))
        !           976:     if (pedantic)
        !           977:       pedwarn ("overflow in constant expression");
        !           978: }
        !           979: 
        !           980: /* Print a warning if an expression had overflow in folding.
        !           981:    Invoke this function on every expression that
        !           982:    (1) appears in the source code, and
        !           983:    (2) might be a constant expression that overflowed, and
        !           984:    (3) is not already checked by convert_and_check;
        !           985:    however, do not invoke this function on operands of explicit casts.  */
        !           986: 
        !           987: void
        !           988: overflow_warning (value)
        !           989:      tree value;
        !           990: {
        !           991:   if (TREE_CODE (value) == INTEGER_CST && TREE_OVERFLOW (value))
        !           992:     {
        !           993:       TREE_OVERFLOW (value) = 0;
        !           994:       warning ("integer overflow in expression");
        !           995:     }
        !           996: }
        !           997: 
        !           998: /* Print a warning if a large constant is truncated to unsigned,
        !           999:    or if -Wconversion is used and a constant < 0 is converted to unsigned.
        !          1000:    Invoke this function on every expression that might be implicitly
        !          1001:    converted to an unsigned type.  */
        !          1002: 
        !          1003: void
        !          1004: unsigned_conversion_warning (result, operand)
        !          1005:      tree result, operand;
        !          1006: {
        !          1007:   if (TREE_CODE (operand) == INTEGER_CST
        !          1008:       && TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
        !          1009:       && TREE_UNSIGNED (TREE_TYPE (result))
        !          1010:       && !int_fits_type_p (operand, TREE_TYPE (result)))
        !          1011:     {
        !          1012:       if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result))))
        !          1013:        /* This detects cases like converting -129 or 256 to unsigned char.  */
        !          1014:        warning ("large integer implicitly truncated to unsigned type");
        !          1015:       else if (warn_conversion)
        !          1016:        warning ("negative integer implicitly converted to unsigned type");
        !          1017:     }
        !          1018: }
        !          1019: 
        !          1020: /* Convert EXPR to TYPE, warning about conversion problems with constants.
        !          1021:    Invoke this function on every expression that is converted implicitly,
        !          1022:    i.e. because of language rules and not because of an explicit cast.  */
        !          1023: 
        !          1024: tree
        !          1025: convert_and_check (type, expr)
        !          1026:      tree type, expr;
        !          1027: {
        !          1028:   tree t = convert (type, expr);
        !          1029:   if (TREE_CODE (t) == INTEGER_CST)
        !          1030:     {
        !          1031:       if (TREE_OVERFLOW (t))
        !          1032:        {
        !          1033:          TREE_OVERFLOW (t) = 0;
        !          1034: 
        !          1035:          /* No warning for converting 0x80000000 to int.  */
        !          1036:          if (!(TREE_UNSIGNED (type) < TREE_UNSIGNED (TREE_TYPE (expr))
        !          1037:                && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
        !          1038:                && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
        !          1039:            /* If EXPR fits in the unsigned version of TYPE,
        !          1040:               don't warn unless pedantic.  */
        !          1041:            if (pedantic
        !          1042:                || TREE_UNSIGNED (type)
        !          1043:                || ! int_fits_type_p (expr, unsigned_type (type)))
        !          1044:              warning ("overflow in implicit constant conversion");
        !          1045:        }
        !          1046:       else
        !          1047:        unsigned_conversion_warning (t, expr);
        !          1048:     }
        !          1049:   return t;
        !          1050: }
        !          1051: 
        !          1052: void
        !          1053: c_expand_expr_stmt (expr)
        !          1054:      tree expr;
        !          1055: {
        !          1056:   /* Do default conversion if safe and possibly important,
        !          1057:      in case within ({...}).  */
        !          1058:   if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE && lvalue_p (expr))
        !          1059:       || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
        !          1060:     expr = default_conversion (expr);
        !          1061: 
        !          1062:   if (TREE_TYPE (expr) != error_mark_node
        !          1063:       && TYPE_SIZE (TREE_TYPE (expr)) == 0
        !          1064:       && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
        !          1065:     error ("expression statement has incomplete type");
        !          1066: 
        !          1067:   expand_expr_stmt (expr);
        !          1068: }
        !          1069: 
        !          1070: /* Validate the expression after `case' and apply default promotions.  */
        !          1071: 
        !          1072: tree
        !          1073: check_case_value (value)
        !          1074:      tree value;
        !          1075: {
        !          1076:   if (value == NULL_TREE)
        !          1077:     return value;
        !          1078: 
        !          1079:   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
        !          1080:   STRIP_TYPE_NOPS (value);
        !          1081: 
        !          1082:   if (TREE_CODE (value) != INTEGER_CST
        !          1083:       && value != error_mark_node)
        !          1084:     {
        !          1085:       error ("case label does not reduce to an integer constant");
        !          1086:       value = error_mark_node;
        !          1087:     }
        !          1088:   else
        !          1089:     /* Promote char or short to int.  */
        !          1090:     value = default_conversion (value);
        !          1091: 
        !          1092:   constant_expression_warning (value);
        !          1093: 
        !          1094:   return value;
        !          1095: }
        !          1096: 
        !          1097: /* Return an integer type with BITS bits of precision,
        !          1098:    that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */
        !          1099: 
        !          1100: tree
        !          1101: type_for_size (bits, unsignedp)
        !          1102:      unsigned bits;
        !          1103:      int unsignedp;
        !          1104: {
        !          1105:   if (bits == TYPE_PRECISION (signed_char_type_node))
        !          1106:     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
        !          1107: 
        !          1108:   if (bits == TYPE_PRECISION (short_integer_type_node))
        !          1109:     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
        !          1110: 
        !          1111:   if (bits == TYPE_PRECISION (integer_type_node))
        !          1112:     return unsignedp ? unsigned_type_node : integer_type_node;
        !          1113: 
        !          1114:   if (bits == TYPE_PRECISION (long_integer_type_node))
        !          1115:     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
        !          1116: 
        !          1117:   if (bits == TYPE_PRECISION (long_long_integer_type_node))
        !          1118:     return (unsignedp ? long_long_unsigned_type_node
        !          1119:            : long_long_integer_type_node);
        !          1120: 
        !          1121:   if (bits <= TYPE_PRECISION (intQI_type_node))
        !          1122:     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
        !          1123: 
        !          1124:   if (bits <= TYPE_PRECISION (intHI_type_node))
        !          1125:     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
        !          1126: 
        !          1127:   if (bits <= TYPE_PRECISION (intSI_type_node))
        !          1128:     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
        !          1129: 
        !          1130:   if (bits <= TYPE_PRECISION (intDI_type_node))
        !          1131:     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
        !          1132: 
        !          1133:   return 0;
        !          1134: }
        !          1135: 
        !          1136: /* Return a data type that has machine mode MODE.
        !          1137:    If the mode is an integer,
        !          1138:    then UNSIGNEDP selects between signed and unsigned types.  */
        !          1139: 
        !          1140: tree
        !          1141: type_for_mode (mode, unsignedp)
        !          1142:      enum machine_mode mode;
        !          1143:      int unsignedp;
        !          1144: {
        !          1145:   if (mode == TYPE_MODE (signed_char_type_node))
        !          1146:     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
        !          1147: 
        !          1148:   if (mode == TYPE_MODE (short_integer_type_node))
        !          1149:     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
        !          1150: 
        !          1151:   if (mode == TYPE_MODE (integer_type_node))
        !          1152:     return unsignedp ? unsigned_type_node : integer_type_node;
        !          1153: 
        !          1154:   if (mode == TYPE_MODE (long_integer_type_node))
        !          1155:     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
        !          1156: 
        !          1157:   if (mode == TYPE_MODE (long_long_integer_type_node))
        !          1158:     return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
        !          1159: 
        !          1160:   if (mode == TYPE_MODE (intQI_type_node))
        !          1161:     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
        !          1162: 
        !          1163:   if (mode == TYPE_MODE (intHI_type_node))
        !          1164:     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
        !          1165: 
        !          1166:   if (mode == TYPE_MODE (intSI_type_node))
        !          1167:     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
        !          1168: 
        !          1169:   if (mode == TYPE_MODE (intDI_type_node))
        !          1170:     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
        !          1171: 
        !          1172:   if (mode == TYPE_MODE (float_type_node))
        !          1173:     return float_type_node;
        !          1174: 
        !          1175:   if (mode == TYPE_MODE (double_type_node))
        !          1176:     return double_type_node;
        !          1177: 
        !          1178:   if (mode == TYPE_MODE (long_double_type_node))
        !          1179:     return long_double_type_node;
        !          1180: 
        !          1181:   if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
        !          1182:     return build_pointer_type (char_type_node);
        !          1183: 
        !          1184:   if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
        !          1185:     return build_pointer_type (integer_type_node);
        !          1186: 
        !          1187:   return 0;
        !          1188: }
        !          1189: 
        !          1190: /* Print an error message for invalid operands to arith operation CODE.
        !          1191:    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
        !          1192: 
        !          1193: void
        !          1194: binary_op_error (code)
        !          1195:      enum tree_code code;
        !          1196: {
        !          1197:   register char *opname;
        !          1198:   switch (code)
        !          1199:     {
        !          1200:     case NOP_EXPR:
        !          1201:       error ("invalid truth-value expression");
        !          1202:       return;
        !          1203: 
        !          1204:     case PLUS_EXPR:
        !          1205:       opname = "+"; break;
        !          1206:     case MINUS_EXPR:
        !          1207:       opname = "-"; break;
        !          1208:     case MULT_EXPR:
        !          1209:       opname = "*"; break;
        !          1210:     case MAX_EXPR:
        !          1211:       opname = "max"; break;
        !          1212:     case MIN_EXPR:
        !          1213:       opname = "min"; break;
        !          1214:     case EQ_EXPR:
        !          1215:       opname = "=="; break;
        !          1216:     case NE_EXPR:
        !          1217:       opname = "!="; break;
        !          1218:     case LE_EXPR:
        !          1219:       opname = "<="; break;
        !          1220:     case GE_EXPR:
        !          1221:       opname = ">="; break;
        !          1222:     case LT_EXPR:
        !          1223:       opname = "<"; break;
        !          1224:     case GT_EXPR:
        !          1225:       opname = ">"; break;
        !          1226:     case LSHIFT_EXPR:
        !          1227:       opname = "<<"; break;
        !          1228:     case RSHIFT_EXPR:
        !          1229:       opname = ">>"; break;
        !          1230:     case TRUNC_MOD_EXPR:
        !          1231:     case FLOOR_MOD_EXPR:
        !          1232:       opname = "%"; break;
        !          1233:     case TRUNC_DIV_EXPR:
        !          1234:     case FLOOR_DIV_EXPR:
        !          1235:       opname = "/"; break;
        !          1236:     case BIT_AND_EXPR:
        !          1237:       opname = "&"; break;
        !          1238:     case BIT_IOR_EXPR:
        !          1239:       opname = "|"; break;
        !          1240:     case TRUTH_ANDIF_EXPR:
        !          1241:       opname = "&&"; break;
        !          1242:     case TRUTH_ORIF_EXPR:
        !          1243:       opname = "||"; break;
        !          1244:     case BIT_XOR_EXPR:
        !          1245:       opname = "^"; break;
        !          1246:     case LROTATE_EXPR:
        !          1247:     case RROTATE_EXPR:
        !          1248:       opname = "rotate"; break;
        !          1249:     }
        !          1250:   error ("invalid operands to binary %s", opname);
        !          1251: }
        !          1252: 
        !          1253: /* Subroutine of build_binary_op, used for comparison operations.
        !          1254:    See if the operands have both been converted from subword integer types
        !          1255:    and, if so, perhaps change them both back to their original type.
        !          1256:    This function is also responsible for converting the two operands
        !          1257:    to the proper common type for comparison.
        !          1258: 
        !          1259:    The arguments of this function are all pointers to local variables
        !          1260:    of build_binary_op: OP0_PTR is &OP0, OP1_PTR is &OP1,
        !          1261:    RESTYPE_PTR is &RESULT_TYPE and RESCODE_PTR is &RESULTCODE.
        !          1262: 
        !          1263:    If this function returns nonzero, it means that the comparison has
        !          1264:    a constant value.  What this function returns is an expression for
        !          1265:    that value.  */
        !          1266: 
        !          1267: tree
        !          1268: shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
        !          1269:      tree *op0_ptr, *op1_ptr;
        !          1270:      tree *restype_ptr;
        !          1271:      enum tree_code *rescode_ptr;
        !          1272: {
        !          1273:   register tree type;
        !          1274:   tree op0 = *op0_ptr;
        !          1275:   tree op1 = *op1_ptr;
        !          1276:   int unsignedp0, unsignedp1;
        !          1277:   int real1, real2;
        !          1278:   tree primop0, primop1;
        !          1279:   enum tree_code code = *rescode_ptr;
        !          1280: 
        !          1281:   /* Throw away any conversions to wider types
        !          1282:      already present in the operands.  */
        !          1283: 
        !          1284:   primop0 = get_narrower (op0, &unsignedp0);
        !          1285:   primop1 = get_narrower (op1, &unsignedp1);
        !          1286: 
        !          1287:   /* Handle the case that OP0 does not *contain* a conversion
        !          1288:      but it *requires* conversion to FINAL_TYPE.  */
        !          1289: 
        !          1290:   if (op0 == primop0 && TREE_TYPE (op0) != *restype_ptr)
        !          1291:     unsignedp0 = TREE_UNSIGNED (TREE_TYPE (op0));
        !          1292:   if (op1 == primop1 && TREE_TYPE (op1) != *restype_ptr)
        !          1293:     unsignedp1 = TREE_UNSIGNED (TREE_TYPE (op1));
        !          1294: 
        !          1295:   /* If one of the operands must be floated, we cannot optimize.  */
        !          1296:   real1 = TREE_CODE (TREE_TYPE (primop0)) == REAL_TYPE;
        !          1297:   real2 = TREE_CODE (TREE_TYPE (primop1)) == REAL_TYPE;
        !          1298: 
        !          1299:   /* If first arg is constant, swap the args (changing operation
        !          1300:      so value is preserved), for canonicalization.  */
        !          1301: 
        !          1302:   if (TREE_CONSTANT (primop0))
        !          1303:     {
        !          1304:       register tree tem = primop0;
        !          1305:       register int temi = unsignedp0;
        !          1306:       primop0 = primop1;
        !          1307:       primop1 = tem;
        !          1308:       tem = op0;
        !          1309:       op0 = op1;
        !          1310:       op1 = tem;
        !          1311:       *op0_ptr = op0;
        !          1312:       *op1_ptr = op1;
        !          1313:       unsignedp0 = unsignedp1;
        !          1314:       unsignedp1 = temi;
        !          1315:       temi = real1;
        !          1316:       real1 = real2;
        !          1317:       real2 = temi;
        !          1318: 
        !          1319:       switch (code)
        !          1320:        {
        !          1321:        case LT_EXPR:
        !          1322:          code = GT_EXPR;
        !          1323:          break;
        !          1324:        case GT_EXPR:
        !          1325:          code = LT_EXPR;
        !          1326:          break;
        !          1327:        case LE_EXPR:
        !          1328:          code = GE_EXPR;
        !          1329:          break;
        !          1330:        case GE_EXPR:
        !          1331:          code = LE_EXPR;
        !          1332:          break;
        !          1333:        }
        !          1334:       *rescode_ptr = code;
        !          1335:     }
        !          1336: 
        !          1337:   /* If comparing an integer against a constant more bits wide,
        !          1338:      maybe we can deduce a value of 1 or 0 independent of the data.
        !          1339:      Or else truncate the constant now
        !          1340:      rather than extend the variable at run time.
        !          1341: 
        !          1342:      This is only interesting if the constant is the wider arg.
        !          1343:      Also, it is not safe if the constant is unsigned and the
        !          1344:      variable arg is signed, since in this case the variable
        !          1345:      would be sign-extended and then regarded as unsigned.
        !          1346:      Our technique fails in this case because the lowest/highest
        !          1347:      possible unsigned results don't follow naturally from the
        !          1348:      lowest/highest possible values of the variable operand.
        !          1349:      For just EQ_EXPR and NE_EXPR there is another technique that
        !          1350:      could be used: see if the constant can be faithfully represented
        !          1351:      in the other operand's type, by truncating it and reextending it
        !          1352:      and see if that preserves the constant's value.  */
        !          1353: 
        !          1354:   if (!real1 && !real2
        !          1355:       && TREE_CODE (primop1) == INTEGER_CST
        !          1356:       && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr))
        !          1357:     {
        !          1358:       int min_gt, max_gt, min_lt, max_lt;
        !          1359:       tree maxval, minval;
        !          1360:       /* 1 if comparison is nominally unsigned.  */
        !          1361:       int unsignedp = TREE_UNSIGNED (*restype_ptr);
        !          1362:       tree val;
        !          1363: 
        !          1364:       type = signed_or_unsigned_type (unsignedp0, TREE_TYPE (primop0));
        !          1365: 
        !          1366:       maxval = TYPE_MAX_VALUE (type);
        !          1367:       minval = TYPE_MIN_VALUE (type);
        !          1368: 
        !          1369:       if (unsignedp && !unsignedp0)
        !          1370:        *restype_ptr = signed_type (*restype_ptr);
        !          1371: 
        !          1372:       if (TREE_TYPE (primop1) != *restype_ptr)
        !          1373:        primop1 = convert (*restype_ptr, primop1);
        !          1374:       if (type != *restype_ptr)
        !          1375:        {
        !          1376:          minval = convert (*restype_ptr, minval);
        !          1377:          maxval = convert (*restype_ptr, maxval);
        !          1378:        }
        !          1379: 
        !          1380:       if (unsignedp && unsignedp0)
        !          1381:        {
        !          1382:          min_gt = INT_CST_LT_UNSIGNED (primop1, minval);
        !          1383:          max_gt = INT_CST_LT_UNSIGNED (primop1, maxval);
        !          1384:          min_lt = INT_CST_LT_UNSIGNED (minval, primop1);
        !          1385:          max_lt = INT_CST_LT_UNSIGNED (maxval, primop1);
        !          1386:        }
        !          1387:       else
        !          1388:        {
        !          1389:          min_gt = INT_CST_LT (primop1, minval);
        !          1390:          max_gt = INT_CST_LT (primop1, maxval);
        !          1391:          min_lt = INT_CST_LT (minval, primop1);
        !          1392:          max_lt = INT_CST_LT (maxval, primop1);
        !          1393:        }
        !          1394: 
        !          1395:       val = 0;
        !          1396:       /* This used to be a switch, but Genix compiler can't handle that.  */
        !          1397:       if (code == NE_EXPR)
        !          1398:        {
        !          1399:          if (max_lt || min_gt)
        !          1400:            val = integer_one_node;
        !          1401:        }
        !          1402:       else if (code == EQ_EXPR)
        !          1403:        {
        !          1404:          if (max_lt || min_gt)
        !          1405:            val = integer_zero_node;
        !          1406:        }
        !          1407:       else if (code == LT_EXPR)
        !          1408:        {
        !          1409:          if (max_lt)
        !          1410:            val = integer_one_node;
        !          1411:          if (!min_lt)
        !          1412:            val = integer_zero_node;
        !          1413:        }
        !          1414:       else if (code == GT_EXPR)
        !          1415:        {
        !          1416:          if (min_gt)
        !          1417:            val = integer_one_node;
        !          1418:          if (!max_gt)
        !          1419:            val = integer_zero_node;
        !          1420:        }
        !          1421:       else if (code == LE_EXPR)
        !          1422:        {
        !          1423:          if (!max_gt)
        !          1424:            val = integer_one_node;
        !          1425:          if (min_gt)
        !          1426:            val = integer_zero_node;
        !          1427:        }
        !          1428:       else if (code == GE_EXPR)
        !          1429:        {
        !          1430:          if (!min_lt)
        !          1431:            val = integer_one_node;
        !          1432:          if (max_lt)
        !          1433:            val = integer_zero_node;
        !          1434:        }
        !          1435: 
        !          1436:       /* If primop0 was sign-extended and unsigned comparison specd,
        !          1437:         we did a signed comparison above using the signed type bounds.
        !          1438:         But the comparison we output must be unsigned.
        !          1439: 
        !          1440:         Also, for inequalities, VAL is no good; but if the signed
        !          1441:         comparison had *any* fixed result, it follows that the
        !          1442:         unsigned comparison just tests the sign in reverse
        !          1443:         (positive values are LE, negative ones GE).
        !          1444:         So we can generate an unsigned comparison
        !          1445:         against an extreme value of the signed type.  */
        !          1446: 
        !          1447:       if (unsignedp && !unsignedp0)
        !          1448:        {
        !          1449:          if (val != 0)
        !          1450:            switch (code)
        !          1451:              {
        !          1452:              case LT_EXPR:
        !          1453:              case GE_EXPR:
        !          1454:                primop1 = TYPE_MIN_VALUE (type);
        !          1455:                val = 0;
        !          1456:                break;
        !          1457: 
        !          1458:              case LE_EXPR:
        !          1459:              case GT_EXPR:
        !          1460:                primop1 = TYPE_MAX_VALUE (type);
        !          1461:                val = 0;
        !          1462:                break;
        !          1463:              }
        !          1464:          type = unsigned_type (type);
        !          1465:        }
        !          1466: 
        !          1467:       if (!max_gt && !unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
        !          1468:        {
        !          1469:          /* This is the case of (char)x >?< 0x80, which people used to use
        !          1470:             expecting old C compilers to change the 0x80 into -0x80.  */
        !          1471:          if (val == integer_zero_node)
        !          1472:            warning ("comparison is always 0 due to limited range of data type");
        !          1473:          if (val == integer_one_node)
        !          1474:            warning ("comparison is always 1 due to limited range of data type");
        !          1475:        }
        !          1476: 
        !          1477:       if (!min_lt && unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
        !          1478:        {
        !          1479:          /* This is the case of (unsigned char)x >?< -1 or < 0.  */
        !          1480:          if (val == integer_zero_node)
        !          1481:            warning ("comparison is always 0 due to limited range of data type");
        !          1482:          if (val == integer_one_node)
        !          1483:            warning ("comparison is always 1 due to limited range of data type");
        !          1484:        }
        !          1485: 
        !          1486:       if (val != 0)
        !          1487:        {
        !          1488:          /* Don't forget to evaluate PRIMOP0 if it has side effects.  */
        !          1489:          if (TREE_SIDE_EFFECTS (primop0))
        !          1490:            return build (COMPOUND_EXPR, TREE_TYPE (val), primop0, val);
        !          1491:          return val;
        !          1492:        }
        !          1493: 
        !          1494:       /* Value is not predetermined, but do the comparison
        !          1495:         in the type of the operand that is not constant.
        !          1496:         TYPE is already properly set.  */
        !          1497:     }
        !          1498:   else if (real1 && real2
        !          1499:           && (TYPE_PRECISION (TREE_TYPE (primop0))
        !          1500:               == TYPE_PRECISION (TREE_TYPE (primop1))))
        !          1501:     type = TREE_TYPE (primop0);
        !          1502: 
        !          1503:   /* If args' natural types are both narrower than nominal type
        !          1504:      and both extend in the same manner, compare them
        !          1505:      in the type of the wider arg.
        !          1506:      Otherwise must actually extend both to the nominal
        !          1507:      common type lest different ways of extending
        !          1508:      alter the result.
        !          1509:      (eg, (short)-1 == (unsigned short)-1  should be 0.)  */
        !          1510: 
        !          1511:   else if (unsignedp0 == unsignedp1 && real1 == real2
        !          1512:           && TYPE_PRECISION (TREE_TYPE (primop0)) < TYPE_PRECISION (*restype_ptr)
        !          1513:           && TYPE_PRECISION (TREE_TYPE (primop1)) < TYPE_PRECISION (*restype_ptr))
        !          1514:     {
        !          1515:       type = common_type (TREE_TYPE (primop0), TREE_TYPE (primop1));
        !          1516:       type = signed_or_unsigned_type (unsignedp0
        !          1517:                                      || TREE_UNSIGNED (*restype_ptr),
        !          1518:                                      type);
        !          1519:       /* Make sure shorter operand is extended the right way
        !          1520:         to match the longer operand.  */
        !          1521:       primop0 = convert (signed_or_unsigned_type (unsignedp0, TREE_TYPE (primop0)),
        !          1522:                         primop0);
        !          1523:       primop1 = convert (signed_or_unsigned_type (unsignedp1, TREE_TYPE (primop1)),
        !          1524:                         primop1);
        !          1525:     }
        !          1526:   else
        !          1527:     {
        !          1528:       /* Here we must do the comparison on the nominal type
        !          1529:         using the args exactly as we received them.  */
        !          1530:       type = *restype_ptr;
        !          1531:       primop0 = op0;
        !          1532:       primop1 = op1;
        !          1533: 
        !          1534:       if (!real1 && !real2 && integer_zerop (primop1)
        !          1535:          && TREE_UNSIGNED (TREE_TYPE (primop0)))
        !          1536:        {
        !          1537:          tree value = 0;
        !          1538:          switch (code)
        !          1539:            {
        !          1540:            case GE_EXPR:
        !          1541:              if (extra_warnings)
        !          1542:                warning ("unsigned value >= 0 is always 1");
        !          1543:              value = integer_one_node;
        !          1544:              break;
        !          1545: 
        !          1546:            case LT_EXPR:
        !          1547:              if (extra_warnings)
        !          1548:                warning ("unsigned value < 0 is always 0");
        !          1549:              value = integer_zero_node;
        !          1550:            }
        !          1551: 
        !          1552:          if (value != 0)
        !          1553:            {
        !          1554:              /* Don't forget to evaluate PRIMOP0 if it has side effects.  */
        !          1555:              if (TREE_SIDE_EFFECTS (primop0))
        !          1556:                return build (COMPOUND_EXPR, TREE_TYPE (value),
        !          1557:                              primop0, value);
        !          1558:              return value;
        !          1559:            }
        !          1560:        }
        !          1561:     }
        !          1562: 
        !          1563:   *op0_ptr = convert (type, primop0);
        !          1564:   *op1_ptr = convert (type, primop1);
        !          1565: 
        !          1566:   *restype_ptr = integer_type_node;
        !          1567: 
        !          1568:   return 0;
        !          1569: }
        !          1570: 
        !          1571: /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
        !          1572:    or validate its data type for an `if' or `while' statement or ?..: exp.
        !          1573: 
        !          1574:    This preparation consists of taking the ordinary
        !          1575:    representation of an expression expr and producing a valid tree
        !          1576:    boolean expression describing whether expr is nonzero.  We could
        !          1577:    simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
        !          1578:    but we optimize comparisons, &&, ||, and !.
        !          1579: 
        !          1580:    The resulting type should always be `integer_type_node'.  */
        !          1581: 
        !          1582: tree
        !          1583: truthvalue_conversion (expr)
        !          1584:      tree expr;
        !          1585: {
        !          1586:   register enum tree_code code;
        !          1587: 
        !          1588:   if (TREE_CODE (expr) == ERROR_MARK)
        !          1589:     return expr;
        !          1590: 
        !          1591: #if 0 /* This appears to be wrong for C++.  */
        !          1592:   /* These really should return error_mark_node after 2.4 is stable.
        !          1593:      But not all callers handle ERROR_MARK properly.  */
        !          1594:   switch (TREE_CODE (TREE_TYPE (expr)))
        !          1595:     {
        !          1596:     case RECORD_TYPE:
        !          1597:       error ("struct type value used where scalar is required");
        !          1598:       return integer_zero_node;
        !          1599: 
        !          1600:     case UNION_TYPE:
        !          1601:       error ("union type value used where scalar is required");
        !          1602:       return integer_zero_node;
        !          1603: 
        !          1604:     case ARRAY_TYPE:
        !          1605:       error ("array type value used where scalar is required");
        !          1606:       return integer_zero_node;
        !          1607: 
        !          1608:     default:
        !          1609:       break;
        !          1610:     }
        !          1611: #endif /* 0 */
        !          1612: 
        !          1613:   switch (TREE_CODE (expr))
        !          1614:     {
        !          1615:       /* It is simpler and generates better code to have only TRUTH_*_EXPR
        !          1616:         or comparison expressions as truth values at this level.  */
        !          1617: #if 0
        !          1618:     case COMPONENT_REF:
        !          1619:       /* A one-bit unsigned bit-field is already acceptable.  */
        !          1620:       if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
        !          1621:          && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
        !          1622:        return expr;
        !          1623:       break;
        !          1624: #endif
        !          1625: 
        !          1626:     case EQ_EXPR:
        !          1627:       /* It is simpler and generates better code to have only TRUTH_*_EXPR
        !          1628:         or comparison expressions as truth values at this level.  */
        !          1629: #if 0
        !          1630:       if (integer_zerop (TREE_OPERAND (expr, 1)))
        !          1631:        return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
        !          1632: #endif
        !          1633:     case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
        !          1634:     case TRUTH_ANDIF_EXPR:
        !          1635:     case TRUTH_ORIF_EXPR:
        !          1636:     case TRUTH_AND_EXPR:
        !          1637:     case TRUTH_OR_EXPR:
        !          1638:     case TRUTH_XOR_EXPR:
        !          1639:     case ERROR_MARK:
        !          1640:       return expr;
        !          1641: 
        !          1642:     case INTEGER_CST:
        !          1643:       return integer_zerop (expr) ? integer_zero_node : integer_one_node;
        !          1644: 
        !          1645:     case REAL_CST:
        !          1646:       return real_zerop (expr) ? integer_zero_node : integer_one_node;
        !          1647: 
        !          1648:     case ADDR_EXPR:
        !          1649:       if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
        !          1650:        return build (COMPOUND_EXPR, integer_type_node,
        !          1651:                      TREE_OPERAND (expr, 0), integer_one_node);
        !          1652:       else
        !          1653:        return integer_one_node;
        !          1654: 
        !          1655:     case COMPLEX_EXPR:
        !          1656:       return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
        !          1657:                               ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
        !          1658:                              truthvalue_conversion (TREE_OPERAND (expr, 0)),
        !          1659:                              truthvalue_conversion (TREE_OPERAND (expr, 1)),
        !          1660:                              0);
        !          1661: 
        !          1662:     case NEGATE_EXPR:
        !          1663:     case ABS_EXPR:
        !          1664:     case FLOAT_EXPR:
        !          1665:     case FFS_EXPR:
        !          1666:       /* These don't change whether an object is non-zero or zero.  */
        !          1667:       return truthvalue_conversion (TREE_OPERAND (expr, 0));
        !          1668: 
        !          1669:     case LROTATE_EXPR:
        !          1670:     case RROTATE_EXPR:
        !          1671:       /* These don't change whether an object is zero or non-zero, but
        !          1672:         we can't ignore them if their second arg has side-effects.  */
        !          1673:       if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
        !          1674:        return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
        !          1675:                      truthvalue_conversion (TREE_OPERAND (expr, 0)));
        !          1676:       else
        !          1677:        return truthvalue_conversion (TREE_OPERAND (expr, 0));
        !          1678:       
        !          1679:     case COND_EXPR:
        !          1680:       /* Distribute the conversion into the arms of a COND_EXPR.  */
        !          1681:       return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
        !          1682:                          truthvalue_conversion (TREE_OPERAND (expr, 1)),
        !          1683:                          truthvalue_conversion (TREE_OPERAND (expr, 2))));
        !          1684: 
        !          1685:     case CONVERT_EXPR:
        !          1686:       /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
        !          1687:         since that affects how `default_conversion' will behave.  */
        !          1688:       if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
        !          1689:          || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
        !          1690:        break;
        !          1691:       /* fall through... */
        !          1692:     case NOP_EXPR:
        !          1693:       /* If this is widening the argument, we can ignore it.  */
        !          1694:       if (TYPE_PRECISION (TREE_TYPE (expr))
        !          1695:          >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
        !          1696:        return truthvalue_conversion (TREE_OPERAND (expr, 0));
        !          1697:       break;
        !          1698: 
        !          1699:     case MINUS_EXPR:
        !          1700:       /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
        !          1701:         this case.  */
        !          1702:       if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
        !          1703:          && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
        !          1704:        break;
        !          1705:       /* fall through... */
        !          1706:     case BIT_XOR_EXPR:
        !          1707:       /* This and MINUS_EXPR can be changed into a comparison of the
        !          1708:         two objects.  */
        !          1709:       if (TREE_TYPE (TREE_OPERAND (expr, 0))
        !          1710:          == TREE_TYPE (TREE_OPERAND (expr, 1)))
        !          1711:        return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
        !          1712:                                TREE_OPERAND (expr, 1), 1);
        !          1713:       return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
        !          1714:                              fold (build1 (NOP_EXPR,
        !          1715:                                            TREE_TYPE (TREE_OPERAND (expr, 0)),
        !          1716:                                            TREE_OPERAND (expr, 1))), 1);
        !          1717: 
        !          1718:     case MODIFY_EXPR:
        !          1719:       if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
        !          1720:        warning ("suggest parentheses around assignment used as truth value");
        !          1721:       break;
        !          1722:     }
        !          1723: 
        !          1724:   if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
        !          1725:     return (build_binary_op
        !          1726:            ((TREE_SIDE_EFFECTS (expr)
        !          1727:              ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
        !          1728:             truthvalue_conversion (build_unary_op (REALPART_EXPR, expr, 0)),
        !          1729:             truthvalue_conversion (build_unary_op (IMAGPART_EXPR, expr, 0)),
        !          1730:             0));
        !          1731: 
        !          1732:   return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
        !          1733: }
        !          1734: 
        !          1735: /* Read the rest of a #-directive from input stream FINPUT.
        !          1736:    In normal use, the directive name and the white space after it
        !          1737:    have already been read, so they won't be included in the result.
        !          1738:    We allow for the fact that the directive line may contain
        !          1739:    a newline embedded within a character or string literal which forms
        !          1740:    a part of the directive.
        !          1741: 
        !          1742:    The value is a string in a reusable buffer.  It remains valid
        !          1743:    only until the next time this function is called.  */
        !          1744: 
        !          1745: char *
        !          1746: get_directive_line (finput)
        !          1747:      register FILE *finput;
        !          1748: {
        !          1749:   static char *directive_buffer = NULL;
        !          1750:   static unsigned buffer_length = 0;
        !          1751:   register char *p;
        !          1752:   register char *buffer_limit;
        !          1753:   register int looking_for = 0;
        !          1754:   register int char_escaped = 0;
        !          1755: 
        !          1756:   if (buffer_length == 0)
        !          1757:     {
        !          1758:       directive_buffer = (char *)xmalloc (128);
        !          1759:       buffer_length = 128;
        !          1760:     }
        !          1761: 
        !          1762:   buffer_limit = &directive_buffer[buffer_length];
        !          1763: 
        !          1764:   for (p = directive_buffer; ; )
        !          1765:     {
        !          1766:       int c;
        !          1767: 
        !          1768:       /* Make buffer bigger if it is full.  */
        !          1769:       if (p >= buffer_limit)
        !          1770:         {
        !          1771:          register unsigned bytes_used = (p - directive_buffer);
        !          1772: 
        !          1773:          buffer_length *= 2;
        !          1774:          directive_buffer
        !          1775:            = (char *)xrealloc (directive_buffer, buffer_length);
        !          1776:          p = &directive_buffer[bytes_used];
        !          1777:          buffer_limit = &directive_buffer[buffer_length];
        !          1778:         }
        !          1779: 
        !          1780:       c = getc (finput);
        !          1781: 
        !          1782:       /* Discard initial whitespace.  */
        !          1783:       if ((c == ' ' || c == '\t') && p == directive_buffer)
        !          1784:        continue;
        !          1785: 
        !          1786:       /* Detect the end of the directive.  */
        !          1787:       if (c == '\n' && looking_for == 0)
        !          1788:        {
        !          1789:           ungetc (c, finput);
        !          1790:          c = '\0';
        !          1791:        }
        !          1792: 
        !          1793:       *p++ = c;
        !          1794: 
        !          1795:       if (c == 0)
        !          1796:        return directive_buffer;
        !          1797: 
        !          1798:       /* Handle string and character constant syntax.  */
        !          1799:       if (looking_for)
        !          1800:        {
        !          1801:          if (looking_for == c && !char_escaped)
        !          1802:            looking_for = 0;    /* Found terminator... stop looking.  */
        !          1803:        }
        !          1804:       else
        !          1805:         if (c == '\'' || c == '"')
        !          1806:          looking_for = c;      /* Don't stop buffering until we see another
        !          1807:                                   another one of these (or an EOF).  */
        !          1808: 
        !          1809:       /* Handle backslash.  */
        !          1810:       char_escaped = (c == '\\' && ! char_escaped);
        !          1811:     }
        !          1812: }
        !          1813: 
        !          1814: /* Make a variant type in the proper way for C/C++, propagating qualifiers
        !          1815:    down to the element type of an array.  */
        !          1816: 
        !          1817: tree
        !          1818: c_build_type_variant (type, constp, volatilep)
        !          1819:      tree type;
        !          1820:      int constp, volatilep;
        !          1821: {
        !          1822:   if (TREE_CODE (type) == ARRAY_TYPE)
        !          1823:     {
        !          1824:       tree real_main_variant = TYPE_MAIN_VARIANT (type);
        !          1825: 
        !          1826:       push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
        !          1827:       type = build_array_type (c_build_type_variant (TREE_TYPE (type),
        !          1828:                                                     constp, volatilep),
        !          1829:                               TYPE_DOMAIN (type));
        !          1830:       TYPE_MAIN_VARIANT (type) = real_main_variant;
        !          1831:       pop_obstacks ();
        !          1832:     }
        !          1833:   return build_type_variant (type, constp, volatilep);
        !          1834: }
        !          1835: 
        !          1836: tree
        !          1837: maybe_objc_method_name (decl)
        !          1838:     tree decl;
        !          1839: {
        !          1840: #ifdef OBJC_TREE_CODES
        !          1841:   if (TREE_CODE (decl) == INSTANCE_METHOD_DECL 
        !          1842:       || TREE_CODE (decl) == CLASS_METHOD_DECL)
        !          1843:     return 1;
        !          1844: #endif
        !          1845:   return 0;
        !          1846: }
        !          1847: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.