Annotation of gcc/c-common.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

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