diff gcc/c-common.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children
line wrap: on
line diff
--- a/gcc/c-common.c	Fri Feb 12 23:41:23 2010 +0900
+++ b/gcc/c-common.c	Mon May 24 12:47:05 2010 +0900
@@ -1,6 +1,6 @@
 /* Subroutines shared by all languages that are variants of C.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -30,8 +30,7 @@
 #include "c-pragma.h"
 #include "rtl.h"
 #include "ggc.h"
-#include "varray.h"
-#include "expr.h"
+#include "expr.h" /* For vector_mode_valid_p */
 #include "c-common.h"
 #include "tm_p.h"
 #include "obstack.h"
@@ -46,11 +45,8 @@
 #include "hashtab.h"
 #include "tree-mudflap.h"
 #include "opts.h"
-#include "real.h"
 #include "cgraph.h"
 #include "target-def.h"
-#include "gimple.h"
-#include "fixed-value.h"
 #include "libfuncs.h"
 
 cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
@@ -280,10 +276,14 @@
 
 int flag_isoc94;
 
-/* Nonzero means use the ISO C99 dialect of C.  */
+/* Nonzero means use the ISO C99 (or C1X) dialect of C.  */
 
 int flag_isoc99;
 
+/* Nonzero means use the ISO C1X dialect of C.  */
+
+int flag_isoc1x;
+
 /* Nonzero means that we have builtin functions, and main is an int.  */
 
 int flag_hosted = 1;
@@ -424,10 +424,6 @@
 
 int flag_pretty_templates = 1;
 
-/* Nonzero means warn about implicit declarations.  */
-
-int warn_implicit = 1;
-
 /* Maximum template instantiation depth.  This limit exists to limit the
    time it takes to notice infinite template instantiations; the default
    value of 1024 is likely to be in the next C++ standard.  */
@@ -530,6 +526,7 @@
 static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
 static tree handle_target_attribute (tree *, tree, tree, int, bool *);
 static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
+static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
 
 static void check_function_nonnull (tree, int, tree *);
 static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -564,6 +561,7 @@
   { "_Fract",           RID_FRACT,     D_CONLY | D_EXT },
   { "_Accum",           RID_ACCUM,     D_CONLY | D_EXT },
   { "_Sat",             RID_SAT,       D_CONLY | D_EXT },
+  { "_Static_assert",   RID_STATIC_ASSERT, D_CONLY },
   { "__FUNCTION__",	RID_FUNCTION_NAME, 0 },
   { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof",	RID_ALIGNOF,	0 },
@@ -657,6 +655,7 @@
   { "mutable",		RID_MUTABLE,	D_CXXONLY | D_CXXWARN },
   { "namespace",	RID_NAMESPACE,	D_CXXONLY | D_CXXWARN },
   { "new",		RID_NEW,	D_CXXONLY | D_CXXWARN },
+  { "nullptr",		RID_NULLPTR,	D_CXXONLY | D_CXX0X | D_CXXWARN },
   { "operator",		RID_OPERATOR,	D_CXXONLY | D_CXXWARN },
   { "private",		RID_PRIVATE,	D_CXX_OBJC | D_CXXWARN },
   { "protected",	RID_PROTECTED,	D_CXX_OBJC | D_CXXWARN },
@@ -829,6 +828,10 @@
 			      handle_target_attribute },
   { "optimize",               1, -1, true, false, false,
 			      handle_optimize_attribute },
+  /* For internal use (marking of builtins and runtime functions) only.
+     The name contains space to prevent its usage in source code.  */
+  { "fn spec",	 	      1, 1, false, true, true,
+			      handle_fnspec_attribute },
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
@@ -2192,12 +2195,17 @@
       else if (TREE_CODE (expr_type) == INTEGER_TYPE
                && TREE_CODE (type) == REAL_TYPE)
         {
-          tree type_low_bound = TYPE_MIN_VALUE (expr_type);
-          tree type_high_bound = TYPE_MAX_VALUE (expr_type);
-          REAL_VALUE_TYPE real_low_bound
-	    = real_value_from_int_cst (0, type_low_bound);
-          REAL_VALUE_TYPE real_high_bound
-	    = real_value_from_int_cst (0, type_high_bound);
+	  tree type_low_bound, type_high_bound;
+          REAL_VALUE_TYPE real_low_bound, real_high_bound;
+
+	  /* Don't warn about char y = 0xff; float x = (int) y;  */
+	  expr = get_unwidened (expr, 0);
+	  expr_type = TREE_TYPE (expr);
+
+          type_low_bound = TYPE_MIN_VALUE (expr_type);
+          type_high_bound = TYPE_MAX_VALUE (expr_type);
+          real_low_bound = real_value_from_int_cst (0, type_low_bound);
+          real_high_bound = real_value_from_int_cst (0, type_high_bound);
 
           if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
               || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
@@ -3801,12 +3809,18 @@
 					     TYPE_UNSIGNED (sizetype)), intop);
 
   /* Replace the integer argument with a suitable product by the object size.
-     Do this multiplication as signed, then convert to the appropriate
-     type for the pointer operation.  */
-  intop = convert (sizetype,
-		   build_binary_op (loc,
-				    MULT_EXPR, intop,
-				    convert (TREE_TYPE (intop), size_exp), 1));
+     Do this multiplication as signed, then convert to the appropriate type
+     for the pointer operation and disregard an overflow that occured only
+     because of the sign-extension change in the latter conversion.  */
+  {
+    tree t = build_binary_op (loc,
+			      MULT_EXPR, intop,
+			      convert (TREE_TYPE (intop), size_exp), 1);
+    intop = convert (sizetype, t);
+    if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t))
+      intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop),
+				  TREE_INT_CST_HIGH (intop));
+  }
 
   /* Create the sum or difference.  */
   if (resultcode == MINUS_EXPR)
@@ -4385,7 +4399,7 @@
       if (complain)
 	error_at (loc, "invalid application of %qs to incomplete type %qT ",
 		  op_name, type);
-      value = size_zero_node;
+      return error_mark_node;
     }
   else
     {
@@ -5658,7 +5672,7 @@
     {
       TREE_USED (label) = 1;
       result = build1 (ADDR_EXPR, ptr_type_node, label);
-      /* The current function in not necessarily uninlinable.
+      /* The current function is not necessarily uninlinable.
 	 Computed gotos are incompatible with inlining, but the value
 	 here could be used only in a diagnostic, for example.  */
       protected_set_expr_location (result, loc);
@@ -5798,6 +5812,20 @@
 #undef DEF_ATTR_TREE_LIST
 }
 
+/* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
+   identifier as an argument, so the front end shouldn't look it up.  */
+
+bool
+attribute_takes_identifier_p (const_tree attr_id)
+{
+  if (is_attribute_p ("mode", attr_id)
+      || is_attribute_p ("format", attr_id)
+      || is_attribute_p ("cleanup", attr_id))
+    return true;
+  else
+    return targetm.attribute_takes_identifier_p (attr_id);
+}
+
 /* Attribute handlers common to C front ends.  */
 
 /* Handle a "packed" attribute; arguments as in
@@ -6116,6 +6144,8 @@
     {
       TREE_USED (node) = 1;
       DECL_PRESERVE_P (node) = 1;
+      if (TREE_CODE (node) == VAR_DECL)
+	DECL_READ_P (node) = 1;
     }
   else
     {
@@ -6142,7 +6172,12 @@
 	  || TREE_CODE (decl) == FUNCTION_DECL
 	  || TREE_CODE (decl) == LABEL_DECL
 	  || TREE_CODE (decl) == TYPE_DECL)
-	TREE_USED (decl) = 1;
+	{
+	  TREE_USED (decl) = 1;
+	  if (TREE_CODE (decl) == VAR_DECL
+	      || TREE_CODE (decl) == PARM_DECL)
+	    DECL_READ_P (decl) = 1;
+	}
       else
 	{
 	  warning (OPT_Wattributes, "%qE attribute ignored", name);
@@ -6247,7 +6282,7 @@
 	  *node = type = build_duplicate_type (type);
 	}
 
-      TYPE_TRANSPARENT_UNION (type) = 1;
+      TYPE_TRANSPARENT_AGGR (type) = 1;
       return NULL_TREE;
     }
 
@@ -6660,10 +6695,12 @@
     }
   else if (is_type)
     {
+      if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+	/* OK, modify the type in place.  */;
       /* If we have a TYPE_DECL, then copy the type, so that we
 	 don't accidentally modify a builtin type.  See pushdecl.  */
-      if (decl && TREE_TYPE (decl) != error_mark_node
-	  && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
+      else if (decl && TREE_TYPE (decl) != error_mark_node
+	       && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
 	{
 	  tree tt = TREE_TYPE (decl);
 	  *type = build_variant_type_copy (*type);
@@ -6672,7 +6709,7 @@
 	  TREE_USED (*type) = TREE_USED (decl);
 	  TREE_TYPE (decl) = *type;
 	}
-      else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+      else
 	*type = build_variant_type_copy (*type);
 
       TYPE_ALIGN (*type) = (1U << i) * BITS_PER_UNIT;
@@ -7104,6 +7141,20 @@
   return NULL_TREE;
 }
 
+/* Handle a "fn spec" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name),
+			 tree args, int ARG_UNUSED (flags),
+			 bool *no_add_attrs ATTRIBUTE_UNUSED)
+{
+  gcc_assert (args
+	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
+	      && !TREE_CHAIN (args));
+  return NULL_TREE;
+}
+
 /* Handle a "returns_twice" attribute; arguments as in
    struct attribute_spec.handler.  */
 
@@ -7975,21 +8026,24 @@
   (*callback) (ctx, param, param_num);
 }
 
-/* Checks the number of arguments NARGS against the required number
-   REQUIRED and issues an error if there is a mismatch.  Returns true
-   if the number of arguments is correct, otherwise false.  */
+/* Checks for a builtin function FNDECL that the number of arguments
+   NARGS against the required number REQUIRED and issues an error if
+   there is a mismatch.  Returns true if the number of arguments is
+   correct, otherwise false.  */
 
 static bool
-validate_nargs (tree fndecl, int nargs, int required)
+builtin_function_validate_nargs (tree fndecl, int nargs, int required)
 {
   if (nargs < required)
     {
-      error ("not enough arguments to function %qE", fndecl);
+      error_at (input_location,
+		"not enough arguments to function %qE", fndecl);
       return false;
     }
   else if (nargs > required)
     {
-      error ("too many arguments to function %qE", fndecl);
+      error_at (input_location,
+		"too many arguments to function %qE", fndecl);
       return false;
     }
   return true;
@@ -8008,14 +8062,14 @@
   switch (DECL_FUNCTION_CODE (fndecl))
     {
     case BUILT_IN_CONSTANT_P:
-      return validate_nargs (fndecl, nargs, 1);
+      return builtin_function_validate_nargs (fndecl, nargs, 1);
 
     case BUILT_IN_ISFINITE:
     case BUILT_IN_ISINF:
     case BUILT_IN_ISINF_SIGN:
     case BUILT_IN_ISNAN:
     case BUILT_IN_ISNORMAL:
-      if (validate_nargs (fndecl, nargs, 1))
+      if (builtin_function_validate_nargs (fndecl, nargs, 1))
 	{
 	  if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE)
 	    {
@@ -8033,7 +8087,7 @@
     case BUILT_IN_ISLESSEQUAL:
     case BUILT_IN_ISLESSGREATER:
     case BUILT_IN_ISUNORDERED:
-      if (validate_nargs (fndecl, nargs, 2))
+      if (builtin_function_validate_nargs (fndecl, nargs, 2))
 	{
 	  enum tree_code code0, code1;
 	  code0 = TREE_CODE (TREE_TYPE (args[0]));
@@ -8051,7 +8105,7 @@
       return false;
 
     case BUILT_IN_FPCLASSIFY:
-      if (validate_nargs (fndecl, nargs, 6))
+      if (builtin_function_validate_nargs (fndecl, nargs, 6))
 	{
 	  unsigned i;
 
@@ -8245,8 +8299,52 @@
 #undef catenate_messages
 }
 
+/* Mapping for cpp message reasons to the options that enable them.  */
+
+struct reason_option_codes_t
+{
+  const int reason;		/* cpplib message reason.  */
+  const int option_code;	/* gcc option that controls this message.  */
+};
+
+static const struct reason_option_codes_t option_codes[] = {
+  {CPP_W_DEPRECATED,			OPT_Wdeprecated},
+  {CPP_W_COMMENTS,			OPT_Wcomments},
+  {CPP_W_TRIGRAPHS,			OPT_Wtrigraphs},
+  {CPP_W_MULTICHAR,			OPT_Wmultichar},
+  {CPP_W_TRADITIONAL,			OPT_Wtraditional},
+  {CPP_W_LONG_LONG,			OPT_Wlong_long},
+  {CPP_W_ENDIF_LABELS,			OPT_Wendif_labels},
+  {CPP_W_VARIADIC_MACROS,		OPT_Wvariadic_macros},
+  {CPP_W_BUILTIN_MACRO_REDEFINED,	OPT_Wbuiltin_macro_redefined},
+  {CPP_W_UNDEF,				OPT_Wundef},
+  {CPP_W_UNUSED_MACROS,			OPT_Wunused_macros},
+  {CPP_W_CXX_OPERATOR_NAMES,		OPT_Wc___compat},
+  {CPP_W_NORMALIZE,			OPT_Wnormalized_},
+  {CPP_W_INVALID_PCH,			OPT_Winvalid_pch},
+  {CPP_W_WARNING_DIRECTIVE,		OPT_Wcpp},
+  {CPP_W_NONE,				0}
+};
+
+/* Return the gcc option code associated with the reason for a cpp
+   message, or 0 if none.  */
+
+static int
+c_option_controlling_cpp_error (int reason)
+{
+  const struct reason_option_codes_t *entry;
+
+  for (entry = option_codes; entry->reason != CPP_W_NONE; entry++)
+    {
+      if (entry->reason == reason)
+	return entry->option_code;
+    }
+  return 0;
+}
+
 /* Callback from cpp_error for PFILE to print diagnostics from the
-   preprocessor.  The diagnostic is of type LEVEL, at location
+   preprocessor.  The diagnostic is of type LEVEL, with REASON set
+   to the reason code if LEVEL is represents a warning, at location
    LOCATION unless this is after lexing and the compiler's location
    should be used instead, with column number possibly overridden by
    COLUMN_OVERRIDE if not zero; MSG is the translated message and AP
@@ -8254,7 +8352,7 @@
    otherwise.  */
 
 bool
-c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
 	     location_t location, unsigned int column_override,
 	     const char *msg, va_list *ap)
 {
@@ -8301,6 +8399,8 @@
 				  location, dlevel);
   if (column_override)
     diagnostic_override_column (&diagnostic, column_override);
+  diagnostic_override_option_index (&diagnostic,
+                                    c_option_controlling_cpp_error (reason));
   ret = report_diagnostic (&diagnostic);
   if (level == CPP_DL_WARNING_SYSHDR)
     warn_system_headers = save_warn_system_headers;
@@ -8678,7 +8778,6 @@
 {
   tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
   tree ptype;
-  int number;
   unsigned int parmnum;
 
   /* We've declared the implementation functions to use "volatile void *"
@@ -8686,7 +8785,6 @@
      call to check_function_arguments what ever type the user used.  */
   arg_types = TREE_CHAIN (arg_types);
   ptype = TREE_TYPE (TREE_TYPE (VEC_index (tree, params, 0)));
-  number = 2;
 
   /* For the rest of the values, we need to cast these to FTYPE, so that we
      don't get warnings for passing pointer types, etc.  */
@@ -8711,7 +8809,6 @@
       VEC_replace (tree, params, parmnum, val);
 
       arg_types = TREE_CHAIN (arg_types);
-      number++;
     }
 
   /* The definition of these primitives is variadic, with the remaining