OSDN Git Service

* pa.c (following_call): Fail if the CALL_INSN is an indirect
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index c74a1a8..c282f16 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines shared by all languages that are variants of C.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -37,6 +37,10 @@ Boston, MA 02111-1307, USA.  */
 
 extern struct obstack permanent_obstack;
 
+/* Nonzero means the expression being parsed will never be evaluated.
+   This is a count, since unevaluated expressions can nest.  */
+int skip_evaluation;
+
 enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
            A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
            A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
@@ -61,15 +65,12 @@ declare_function_name ()
     }
   else
     {
-      char *kind = "function";
-      if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
-       kind = "method";
       /* Allow functions to be nameless (such as artificial ones).  */
       if (DECL_NAME (current_function_decl))
         name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
       else
        name = "";
-      printable_name = (*decl_printable_name) (current_function_decl, &kind);
+      printable_name = (*decl_printable_name) (current_function_decl, 2);
     }
 
   declare_hidden_char_array ("__FUNCTION__", name);
@@ -284,7 +285,7 @@ init_attributes ()
 /* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
    and install them in NODE, which is either a DECL (including a TYPE_DECL)
    or a TYPE.  PREFIX_ATTRIBUTES can appear after the declaration specifiers
-   and declaration modifiers but before the declaration proper. */
+   and declaration modifiers but before the declaration proper.  */
 
 void
 decl_attributes (node, attributes, prefix_attributes)
@@ -498,7 +499,8 @@ decl_attributes (node, attributes, prefix_attributes)
              && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
            {
              if (TREE_CODE (decl) == VAR_DECL 
-                 && current_function_decl != NULL_TREE)
+                 && current_function_decl != NULL_TREE
+                 && ! TREE_STATIC (decl))
                error_with_decl (decl,
                  "section attribute cannot be specified for local variables");
              /* The decl may have already been given a section attribute from
@@ -645,7 +647,7 @@ decl_attributes (node, attributes, prefix_attributes)
                if (first_arg_num != 0)
                  {
                    /* Verify that first_arg_num points to the last arg,
-                      the ... */
+                      the ...  */
                    while (argument)
                      arg_num++, argument = TREE_CHAIN (argument);
                  if (arg_num != first_arg_num)
@@ -732,7 +734,7 @@ decl_attributes (node, attributes, prefix_attributes)
 
        case A_ALIAS:
          if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
-             || TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))
+             || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
            error_with_decl (decl,
                             "`%s' defined both normally and as an alias");
          else if (decl_function_context (decl) == 0)
@@ -751,6 +753,76 @@ decl_attributes (node, attributes, prefix_attributes)
        }
     }
 }
+
+/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
+   lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
+
+   The head of the declspec list is stored in DECLSPECS.
+   The head of the attribute list is stored in PREFIX_ATTRIBUTES.
+
+   Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
+   the list elements.  We drop the containing TREE_LIST nodes and link the
+   resulting attributes together the way decl_attributes expects them.  */
+
+void
+split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
+     tree specs_attrs;
+     tree *declspecs, *prefix_attributes;
+{
+  tree t, s, a, next, specs, attrs;
+
+  /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
+  if (specs_attrs != NULL_TREE
+      && TREE_CODE (specs_attrs) != TREE_LIST)
+    {
+      *declspecs = specs_attrs;
+      *prefix_attributes = NULL_TREE;
+      return;
+    }
+
+  /* Remember to keep the lists in the same order, element-wise.  */
+
+  specs = s = NULL_TREE;
+  attrs = a = NULL_TREE;
+  for (t = specs_attrs; t; t = next)
+    {
+      next = TREE_CHAIN (t);
+      /* Declspecs have a non-NULL TREE_VALUE.  */
+      if (TREE_VALUE (t) != NULL_TREE)
+       {
+         if (specs == NULL_TREE)
+           specs = s = t;
+         else
+           {
+             TREE_CHAIN (s) = t;
+             s = t;
+           }
+       }
+      else
+       {
+         if (attrs == NULL_TREE)
+           attrs = a = TREE_PURPOSE (t);
+         else
+           {
+             TREE_CHAIN (a) = TREE_PURPOSE (t);
+             a = TREE_PURPOSE (t);
+           }
+         /* More attrs can be linked here, move A to the end.  */
+         while (TREE_CHAIN (a) != NULL_TREE)
+           a = TREE_CHAIN (a);
+       }
+    }
+
+  /* Terminate the lists.  */
+  if (s != NULL_TREE)
+    TREE_CHAIN (s) = NULL_TREE;
+  if (a != NULL_TREE)
+    TREE_CHAIN (a) = NULL_TREE;
+
+  /* All done.  */
+  *declspecs = specs;
+  *prefix_attributes = attrs;
+}
 \f
 /* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against
    a parameter list.  */
@@ -922,7 +994,7 @@ record_function_format (name, assembler_name, is_scan,
    the number of the argument which is the format control string (starting
    from 1).  */
 
-void
+static void
 record_international_format (name, assembler_name, format_num)
       tree name;
       tree assembler_name;
@@ -1324,6 +1396,8 @@ check_format_info (info, params)
          sprintf (message, "`a' flag used with `%c' format",
                   format_char);
          warning (message);
+         /* To simplify the following code.  */
+         aflag = 0;
        }
       if (info->is_scan && format_char == '[')
        {
@@ -1366,7 +1440,7 @@ check_format_info (info, params)
              || format_char == 'x' || format_char == 'x'))
        {
          sprintf (message,
-                  "precision and `0' flag not both allowed with `%c' format",
+                  "`0' flag ignored with precision specifier and `%c' format",
                   format_char);
          warning (message);
        }
@@ -1413,7 +1487,7 @@ check_format_info (info, params)
 
       /* Check the types of any additional pointer arguments
         that precede the "real" argument.  */
-      for (i = 0; i < fci->pointer_count; ++i)
+      for (i = 0; i < fci->pointer_count + aflag; ++i)
        {
          if (TREE_CODE (cur_type) == POINTER_TYPE)
            {
@@ -1424,7 +1498,8 @@ check_format_info (info, params)
            {
              sprintf (message,
                       "format argument is not a %s (arg %d)",
-                      ((fci->pointer_count == 1) ? "pointer" : "pointer to a pointer"),
+                      ((fci->pointer_count + aflag == 1)
+                       ? "pointer" : "pointer to a pointer"),
                       arg_num);
              warning (message);
            }
@@ -1432,7 +1507,7 @@ check_format_info (info, params)
        }
 
       /* Check the type of the "real" argument, if there's a type we want.  */
-      if (i == fci->pointer_count && wanted_type != 0
+      if (i == fci->pointer_count + aflag && wanted_type != 0
          && TREE_CODE (cur_type) != ERROR_MARK
          && wanted_type != TYPE_MAIN_VARIANT (cur_type)
          /* If we want `void *', allow any pointer type.
@@ -1531,7 +1606,8 @@ overflow_warning (value)
       && TREE_OVERFLOW (value))
     {
       TREE_OVERFLOW (value) = 0;
-      warning ("integer overflow in expression");
+      if (skip_evaluation == 0)
+       warning ("integer overflow in expression");
     }
   else if ((TREE_CODE (value) == REAL_CST
            || (TREE_CODE (value) == COMPLEX_CST
@@ -1539,7 +1615,8 @@ overflow_warning (value)
           && TREE_OVERFLOW (value))
     {
       TREE_OVERFLOW (value) = 0;
-      warning ("floating point overflow in expression");
+      if (skip_evaluation == 0)
+       warning ("floating point overflow in expression");
     }
 }
 
@@ -1555,6 +1632,7 @@ unsigned_conversion_warning (result, operand)
   if (TREE_CODE (operand) == INTEGER_CST
       && TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
       && TREE_UNSIGNED (TREE_TYPE (result))
+      && skip_evaluation == 0
       && !int_fits_type_p (operand, TREE_TYPE (result)))
     {
       if (!int_fits_type_p (operand, signed_type (TREE_TYPE (result))))
@@ -1590,10 +1668,11 @@ convert_and_check (type, expr)
                && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
            /* If EXPR fits in the unsigned version of TYPE,
               don't warn unless pedantic.  */
-           if (pedantic
-               || TREE_UNSIGNED (type)
-               || ! int_fits_type_p (expr, unsigned_type (type)))
-             warning ("overflow in implicit constant conversion");
+           if ((pedantic
+                || TREE_UNSIGNED (type)
+                || ! int_fits_type_p (expr, unsigned_type (type)))
+               && skip_evaluation == 0)
+               warning ("overflow in implicit constant conversion");
        }
       else
        unsigned_conversion_warning (t, expr);
@@ -2292,7 +2371,7 @@ truthvalue_conversion (expr)
       if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
          || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
        break;
-      /* fall through... */
+      /* fall through...  */
     case NOP_EXPR:
       /* If this is widening the argument, we can ignore it.  */
       if (TYPE_PRECISION (TREE_TYPE (expr))
@@ -2306,7 +2385,7 @@ truthvalue_conversion (expr)
       if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
          && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
        break;
-      /* fall through... */
+      /* fall through...  */
     case BIT_XOR_EXPR:
       /* This and MINUS_EXPR can be changed into a comparison of the
         two objects.  */
@@ -2435,27 +2514,8 @@ c_build_type_variant (type, constp, volatilep)
      int constp, volatilep;
 {
   if (TREE_CODE (type) == ARRAY_TYPE)
-    {
-      tree real_main_variant = TYPE_MAIN_VARIANT (type);
-
-      push_obstacks (TYPE_OBSTACK (real_main_variant),
-                    TYPE_OBSTACK (real_main_variant));
-      type = build_array_type (c_build_type_variant (TREE_TYPE (type),
-                                                    constp, volatilep),
-                              TYPE_DOMAIN (type));
-
-      /* TYPE must be on same obstack as REAL_MAIN_VARIANT.  If not,
-        make a copy.  (TYPE might have come from the hash table and
-        REAL_MAIN_VARIANT might be in some function's obstack.)  */
-
-      if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant))
-       {
-         type = copy_node (type);
-         TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0;
-       }
-
-      TYPE_MAIN_VARIANT (type) = real_main_variant;
-      pop_obstacks ();
-    }
+    return build_array_type (c_build_type_variant (TREE_TYPE (type),
+                                                  constp, volatilep),
+                            TYPE_DOMAIN (type));
   return build_type_variant (type, constp, volatilep);
 }