install.texi (Installation): Remove obsolete description for libstdc++ which is now...
[platform/upstream/gcc.git] / gcc / c-common.c
index 4efa882..e07a7d3 100644 (file)
@@ -30,19 +30,37 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "expr.h"
 #include "c-common.h"
+#include "defaults.h"
 #include "tm_p.h"
 #include "intl.h"
 #include "diagnostic.h"
 #include "obstack.h"
-
-#if USE_CPPLIB
 #include "cpplib.h"
 cpp_reader  parse_in;
-#endif
 
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
 
+#ifndef WINT_TYPE
+#define WINT_TYPE "unsigned int"
+#endif
+
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)    \
+                    ? "int"                                    \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long int"                            \
+                       : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE)   \
+                    ? "unsigned int"                           \
+                    : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+                       ? "long unsigned int"                   \
+                       : "long long unsigned int"))
+#endif
+
 /* The following symbols are subsumed in the c_global_trees array, and
    listed here individually for documentation purposes.
 
@@ -155,6 +173,22 @@ int flag_no_nonansi_builtin;
 
 const char *flag_dump_translation_unit;
 
+/* Warn about *printf or *scanf format/argument anomalies. */
+
+int warn_format;
+
+/* Warn about Y2K problems with strftime formats.  */
+
+int warn_format_y2k;
+
+/* Warn about excess arguments to formats.  */
+
+int warn_format_extra_args;
+
+/* Warn about non-literal format arguments.  */
+
+int warn_format_nonliteral;
+
 /* Nonzero means warn about possible violations of sequence point rules.  */
 
 int warn_sequence_point;
@@ -2024,24 +2058,24 @@ status_warning VPARAMS ((int *status, const char *msgid, ...))
   va_list ap;
   diagnostic_context dc;
 
-  if (status)
-    *status = 1;
-  else
-    {
-      VA_START (ap, msgid);
+  VA_START (ap, msgid);
 
 #ifndef ANSI_PROTOTYPES
-      status = va_arg (ap, int *);
-      msgid = va_arg (ap, const char *);
+  status = va_arg (ap, int *);
+  msgid = va_arg (ap, const char *);
 #endif
 
+  if (status)
+    *status = 1;
+  else
+    {
       /* This duplicates the warning function behavior.  */
       set_diagnostic_context
        (&dc, msgid, &ap, input_filename, lineno, /* warn = */ 1);
       report_diagnostic (&dc);
-
-      va_end (ap);
     }
+
+  va_end (ap);
 }
 
 /* Variables used by the checking of $ operand number formats.  */
@@ -2303,7 +2337,7 @@ check_format_info (status, info, params)
       /* Functions taking a va_list normally pass a non-literal format
         string.  These functions typically are declared with
         first_arg_num == 0, so avoid warning in those cases.  */
-      if (info->first_arg_num != 0 && warn_format > 1)
+      if (info->first_arg_num != 0 && warn_format_nonliteral)
        status_warning (status, "format not a string literal, argument types not checked");
     }
 
@@ -2315,10 +2349,10 @@ check_format_info (status, info, params)
      If the format is an empty string, this should be counted similarly to the
      case of extra format arguments.  */
   if (res.number_extra_args > 0 && res.number_non_literal == 0
-      && res.number_other == 0)
+      && res.number_other == 0 && warn_format_extra_args)
     status_warning (status, "too many arguments for format");
   if (res.number_dollar_extra_args > 0 && res.number_non_literal == 0
-      && res.number_other == 0)
+      && res.number_other == 0 && warn_format_extra_args)
     status_warning (status, "unused arguments in $-style format");
   if (res.number_empty > 0 && res.number_non_literal == 0
       && res.number_other == 0)
@@ -2973,23 +3007,24 @@ check_format_info_main (status, res, info, format_chars, format_length,
        }
 
       /* Give Y2K warnings.  */
-      {
-       int y2k_level = 0;
-       if (strchr (fci->flags2, '4') != 0)
-         if (strchr (flag_chars, 'E') != 0)
+      if (warn_format_y2k)
+       {
+         int y2k_level = 0;
+         if (strchr (fci->flags2, '4') != 0)
+           if (strchr (flag_chars, 'E') != 0)
+             y2k_level = 3;
+           else
+             y2k_level = 2;
+         else if (strchr (fci->flags2, '3') != 0)
            y2k_level = 3;
-         else
+         else if (strchr (fci->flags2, '2') != 0)
            y2k_level = 2;
-       else if (strchr (fci->flags2, '3') != 0)
-         y2k_level = 3;
-       else if (strchr (fci->flags2, '2') != 0)
-         y2k_level = 2;
-       if (y2k_level == 3)
-         status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
-                         format_char);
-       else if (y2k_level == 2)
-         status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
-      }
+         if (y2k_level == 3)
+           status_warning (status, "`%%%c' yields only last 2 digits of year in some locales",
+                           format_char);
+         else if (y2k_level == 2)
+           status_warning (status, "`%%%c' yields only last 2 digits of year", format_char);
+       }
 
       if (strchr (fci->flags2, '[') != 0)
        {
@@ -3307,6 +3342,19 @@ check_format_types (status, types)
       }
     }
 }
+
+/* Set format warning options according to a -Wformat=n option.  */
+
+void
+set_Wformat (setting)
+     int setting;
+{
+  warn_format = setting;
+  warn_format_y2k = setting;
+  warn_format_extra_args = setting;
+  if (setting != 1)
+    warn_format_nonliteral = setting;
+}
 \f
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
@@ -4710,91 +4758,6 @@ truthvalue_conversion (expr)
   return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
 }
 \f
-#if !USE_CPPLIB
-/* Read the rest of a #-directive from input stream FINPUT.
-   In normal use, the directive name and the white space after it
-   have already been read, so they won't be included in the result.
-   We allow for the fact that the directive line may contain
-   a newline embedded within a character or string literal which forms
-   a part of the directive.
-
-   The value is a string in a reusable buffer.  It remains valid
-   only until the next time this function is called.
-
-   The terminating character ('\n' or EOF) is left in FINPUT for the
-   caller to re-read.  */
-
-char *
-get_directive_line (finput)
-     register FILE *finput;
-{
-  static char *directive_buffer = NULL;
-  static unsigned buffer_length = 0;
-  register char *p;
-  register char *buffer_limit;
-  register int looking_for = 0;
-  register int char_escaped = 0;
-
-  if (buffer_length == 0)
-    {
-      directive_buffer = (char *)xmalloc (128);
-      buffer_length = 128;
-    }
-
-  buffer_limit = &directive_buffer[buffer_length];
-
-  for (p = directive_buffer; ; )
-    {
-      int c;
-
-      /* Make buffer bigger if it is full.  */
-      if (p >= buffer_limit)
-        {
-         register unsigned bytes_used = (p - directive_buffer);
-
-         buffer_length *= 2;
-         directive_buffer
-           = (char *)xrealloc (directive_buffer, buffer_length);
-         p = &directive_buffer[bytes_used];
-         buffer_limit = &directive_buffer[buffer_length];
-        }
-
-      c = getc (finput);
-
-      /* Discard initial whitespace.  */
-      if ((c == ' ' || c == '\t') && p == directive_buffer)
-       continue;
-
-      /* Detect the end of the directive.  */
-      if (looking_for == 0
-         && (c == '\n' || c == EOF))
-       {
-          ungetc (c, finput);
-         c = '\0';
-       }
-
-      *p++ = c;
-
-      if (c == 0)
-       return directive_buffer;
-
-      /* Handle string and character constant syntax.  */
-      if (looking_for)
-       {
-         if (looking_for == c && !char_escaped)
-           looking_for = 0;    /* Found terminator... stop looking.  */
-       }
-      else
-        if (c == '\'' || c == '"')
-         looking_for = c;      /* Don't stop buffering until we see another
-                                  one of these (or an EOF).  */
-
-      /* Handle backslash.  */
-      char_escaped = (c == '\\' && ! char_escaped);
-    }
-}
-#endif /* USE_CPPLIB */
-\f
 /* Make a variant type in the proper way for C/C++, propagating qualifiers
    down to the element type of an array.  */
 
@@ -4975,8 +4938,10 @@ c_common_nodes_and_builtins ()
   tree int_ftype_cptr_cptr_sizet;
   tree int_ftype_string_string, string_ftype_ptr_ptr;
   tree string_ftype_string_int, string_ftype_string_string;
+  tree string_ftype_string_cstring_sizet, int_ftype_cstring_cstring_sizet;
   tree long_ftype_long;
   tree longlong_ftype_longlong;
+  tree intmax_ftype_intmax;
   /* Either char* or void*.  */
   tree traditional_ptr_type_node;
   /* Either const char* or const void*.  */
@@ -4986,6 +4951,23 @@ c_common_nodes_and_builtins ()
   tree va_list_ref_type_node;
   tree va_list_arg_type_node;
 
+  string_type_node = build_pointer_type (char_type_node);
+  const_string_type_node
+    = build_pointer_type (build_type_variant (char_type_node, 1, 0));
+
+  wint_type_node =
+    TREE_TYPE (identifier_global_value (get_identifier (WINT_TYPE)));
+
+  intmax_type_node =
+    TREE_TYPE (identifier_global_value (get_identifier (INTMAX_TYPE)));
+  uintmax_type_node =
+    TREE_TYPE (identifier_global_value (get_identifier (UINTMAX_TYPE)));
+
+  default_function_type = build_function_type (integer_type_node, NULL_TREE);
+  ptrdiff_type_node
+    = TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE)));
+  unsigned_ptrdiff_type_node = unsigned_type (ptrdiff_type_node);
+
   pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
                        va_list_type_node));
 
@@ -5056,6 +5038,11 @@ c_common_nodes_and_builtins ()
                           tree_cons (NULL_TREE, long_long_integer_type_node,
                                      endlink));
 
+  intmax_ftype_intmax
+    = build_function_type (intmax_type_node,
+                          tree_cons (NULL_TREE, intmax_type_node,
+                                     endlink));
+
   int_ftype_cptr_cptr_sizet
     = build_function_type (integer_type_node,
                           tree_cons (NULL_TREE, const_ptr_type_node,
@@ -5075,6 +5062,14 @@ c_common_nodes_and_builtins ()
                                                 const_string_type_node,
                                                 endlink)));
 
+  /* Prototype for strncpy.  */
+  string_ftype_string_cstring_sizet
+    = build_function_type (string_type_node,
+                          tree_cons (NULL_TREE, string_type_node,
+                                     tree_cons (NULL_TREE,
+                                                const_string_type_node,
+                                                sizetype_endlink)));
+
   traditional_len_type_node = ((flag_traditional && 
                                c_language != clk_cplusplus)
                               ? integer_type_node : sizetype);
@@ -5089,6 +5084,14 @@ c_common_nodes_and_builtins ()
                                                 const_string_type_node,
                                                 endlink)));
 
+  /* Prototype for strncmp.  */
+  int_ftype_cstring_cstring_sizet
+    = build_function_type (integer_type_node,
+                          tree_cons (NULL_TREE, const_string_type_node,
+                                     tree_cons (NULL_TREE,
+                                                const_string_type_node,
+                                                sizetype_endlink)));
+
   /* Prototype for strstr, strpbrk, etc.  */
   string_ftype_string_string
     = build_function_type (string_type_node,
@@ -5223,6 +5226,8 @@ c_common_nodes_and_builtins ()
                    BUILT_IN_NORMAL, NULL_PTR);
   builtin_function ("__builtin_llabs", longlong_ftype_longlong, BUILT_IN_LLABS,
                    BUILT_IN_NORMAL, NULL_PTR);
+  builtin_function ("__builtin_imaxabs", intmax_ftype_intmax, BUILT_IN_IMAXABS,
+                   BUILT_IN_NORMAL, NULL_PTR);
   builtin_function ("__builtin_saveregs", ptr_ftype, BUILT_IN_SAVEREGS,
                    BUILT_IN_NORMAL, NULL_PTR);
   builtin_function ("__builtin_classify_type", default_function_type,
@@ -5334,8 +5339,11 @@ c_common_nodes_and_builtins ()
                    BUILT_IN_INDEX, BUILT_IN_NORMAL, "index");
   builtin_function ("__builtin_rindex", string_ftype_string_int,
                    BUILT_IN_RINDEX, BUILT_IN_NORMAL, "rindex");
-  builtin_function ("__builtin_strcmp", int_ftype_string_string,
-                   BUILT_IN_STRCMP, BUILT_IN_NORMAL, "strcmp");
+  built_in_decls[BUILT_IN_STRCMP] =
+    builtin_function ("__builtin_strcmp", int_ftype_string_string,
+                     BUILT_IN_STRCMP, BUILT_IN_NORMAL, "strcmp");
+  builtin_function ("__builtin_strncmp", int_ftype_cstring_cstring_sizet,
+                   BUILT_IN_STRNCMP, BUILT_IN_NORMAL, "strncmp");
   builtin_function ("__builtin_strstr", string_ftype_string_string,
                    BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr");
   builtin_function ("__builtin_strpbrk", string_ftype_string_string,
@@ -5347,6 +5355,8 @@ c_common_nodes_and_builtins ()
                    BUILT_IN_STRRCHR, BUILT_IN_NORMAL, "strrchr");
   builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
                    BUILT_IN_STRCPY, BUILT_IN_NORMAL, "strcpy");
+  builtin_function ("__builtin_strncpy", string_ftype_string_cstring_sizet,
+                   BUILT_IN_STRNCPY, BUILT_IN_NORMAL, "strncpy");
   builtin_function ("__builtin_strlen", strlen_ftype,
                    BUILT_IN_STRLEN, BUILT_IN_NORMAL, "strlen");
   builtin_function ("__builtin_sqrtf", float_ftype_float,
@@ -5403,8 +5413,12 @@ c_common_nodes_and_builtins ()
       builtin_function ("labs", long_ftype_long, BUILT_IN_LABS,
                        BUILT_IN_NORMAL, NULL_PTR);
       if (flag_isoc99 || ! flag_no_nonansi_builtin)
-       builtin_function ("llabs", longlong_ftype_longlong, BUILT_IN_LLABS,
-                         BUILT_IN_NORMAL, NULL_PTR);
+       {
+         builtin_function ("llabs", longlong_ftype_longlong, BUILT_IN_LLABS,
+                           BUILT_IN_NORMAL, NULL_PTR);
+         builtin_function ("imaxabs", intmax_ftype_intmax, BUILT_IN_IMAXABS,
+                           BUILT_IN_NORMAL, NULL_PTR);
+       }
       builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY,
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP,
@@ -5413,6 +5427,8 @@ c_common_nodes_and_builtins ()
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP,
                        BUILT_IN_NORMAL, NULL_PTR);
+      builtin_function ("strncmp", int_ftype_cstring_cstring_sizet,
+                       BUILT_IN_STRNCMP, BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strstr", string_ftype_string_string, BUILT_IN_STRSTR,
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strchr", string_ftype_string_int, BUILT_IN_STRCHR,
@@ -5423,6 +5439,8 @@ c_common_nodes_and_builtins ()
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
                        BUILT_IN_NORMAL, NULL_PTR);
+      builtin_function ("strncpy", string_ftype_string_cstring_sizet,
+                       BUILT_IN_STRNCPY, BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN,
                        BUILT_IN_NORMAL, NULL_PTR);
       builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT,
@@ -5597,6 +5615,7 @@ expand_tree_builtin (function, params, coerced_params)
     case BUILT_IN_ABS:
     case BUILT_IN_LABS:
     case BUILT_IN_LLABS:
+    case BUILT_IN_IMAXABS:
     case BUILT_IN_FABS:
       if (coerced_params == 0)
        return integer_zero_node;