OSDN Git Service

* config.gcc (vax-*-linux*): Keep the original contents of
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index 069452c..50f316d 100644 (file)
@@ -428,11 +428,11 @@ int flag_pretty_templates = 1;
 
 int warn_implicit = 1;
 
-/* Maximum template instantiation depth.  This limit is rather
-   arbitrary, but it exists to limit the time it takes to notice
-   infinite template instantiations.  */
+/* 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.  */
 
-int max_tinst_depth = 500;
+int max_tinst_depth = 1024;
 
 
 
@@ -482,6 +482,7 @@ static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
 static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
 static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
 static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
 static tree handle_always_inline_attribute (tree *, tree, tree, int,
                                            bool *);
 static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
@@ -618,6 +619,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__typeof__",      RID_TYPEOF,     0 },
   { "__volatile",      RID_VOLATILE,   0 },
   { "__volatile__",    RID_VOLATILE,   0 },
+  { "alignof",         RID_ALIGNOF,    D_CXXONLY | D_CXX0X | D_CXXWARN },
   { "asm",             RID_ASM,        D_ASM },
   { "auto",            RID_AUTO,       0 },
   { "bool",            RID_BOOL,       D_CXXONLY | D_CXXWARN },
@@ -629,6 +631,7 @@ const struct c_common_resword c_common_reswords[] =
   { "char32_t",                RID_CHAR32,     D_CXXONLY | D_CXX0X | D_CXXWARN },
   { "class",           RID_CLASS,      D_CXX_OBJC | D_CXXWARN },
   { "const",           RID_CONST,      0 },
+  { "constexpr",       RID_CONSTEXPR,  D_CXXONLY | D_CXX0X | D_CXXWARN },
   { "const_cast",      RID_CONSTCAST,  D_CXXONLY | D_CXXWARN },
   { "continue",                RID_CONTINUE,   0 },
   { "decltype",         RID_DECLTYPE,   D_CXXONLY | D_CXX0X | D_CXXWARN },
@@ -707,6 +710,11 @@ const struct c_common_resword c_common_reswords[] =
   { "inout",           RID_INOUT,              D_OBJC },
   { "oneway",          RID_ONEWAY,             D_OBJC },
   { "out",             RID_OUT,                D_OBJC },
+
+#ifdef TARGET_ADDR_SPACE_KEYWORDS
+  /* Any address space keywords recognized by the target.  */
+  TARGET_ADDR_SPACE_KEYWORDS,
+#endif
 };
 
 const unsigned int num_c_common_reswords =
@@ -733,6 +741,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_noreturn_attribute },
   { "noinline",               0, 0, true,  false, false,
                              handle_noinline_attribute },
+  { "noclone",                0, 0, true,  false, false,
+                             handle_noclone_attribute },
   { "always_inline",          0, 0, true,  false, false,
                              handle_always_inline_attribute },
   { "gnu_inline",             0, 0, true,  false, false,
@@ -835,6 +845,19 @@ const struct attribute_spec c_common_format_attribute_table[] =
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
+/* Return identifier for address space AS.  */
+const char *
+c_addr_space_name (addr_space_t as)
+{
+  unsigned int i;
+
+  for (i = 0; i < num_c_common_reswords; i++)
+    if (c_common_reswords[i].rid == RID_FIRST_ADDR_SPACE + as)
+      return c_common_reswords[i].word;
+
+  gcc_unreachable ();
+}
+
 /* Push current bindings for the function name VAR_DECLS.  */
 
 void
@@ -1086,6 +1109,7 @@ c_fully_fold (tree expr, bool in_init, bool *maybe_const)
   tree eptype = NULL_TREE;
   bool dummy = true;
   bool maybe_const_itself = true;
+  location_t loc = EXPR_LOCATION (expr);
 
   /* This function is not relevant to C++ because C++ folds while
      parsing, and may need changes to be correct for C++ when C++
@@ -1103,7 +1127,7 @@ c_fully_fold (tree expr, bool in_init, bool *maybe_const)
   ret = c_fully_fold_internal (expr, in_init, maybe_const,
                               &maybe_const_itself);
   if (eptype)
-    ret = fold_convert (eptype, ret);
+    ret = fold_convert_loc (loc, eptype, ret);
   *maybe_const &= maybe_const_itself;
   return ret;
 }
@@ -1129,6 +1153,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
   bool op0_const = true, op1_const = true, op2_const = true;
   bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
   bool nowarning = TREE_NO_WARNING (expr);
+  int unused_p;
 
   /* This function is not relevant to C++ because C++ folds while
      parsing, and may need changes to be correct for C++ when C++
@@ -1212,6 +1237,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       op2 = TREE_OPERAND (expr, 2);
       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
                                   maybe_const_itself);
+      STRIP_TYPE_NOPS (op0);
       if (op0 != orig_op0)
        ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2);
       if (ret != expr)
@@ -1228,8 +1254,10 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       op3 = TREE_OPERAND (expr, 3);
       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
                                   maybe_const_itself);
+      STRIP_TYPE_NOPS (op0);
       op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
                                   maybe_const_itself);
+      STRIP_TYPE_NOPS (op1);
       op1 = decl_constant_value_for_optimization (op1);
       if (op0 != orig_op0 || op1 != orig_op1)
        ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3);
@@ -1286,6 +1314,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       orig_op1 = op1 = TREE_OPERAND (expr, 1);
       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
                                   maybe_const_itself);
+      STRIP_TYPE_NOPS (op0);
       if (code != MODIFY_EXPR
          && code != PREDECREMENT_EXPR
          && code != PREINCREMENT_EXPR
@@ -1297,13 +1326,18 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       if (code != MODIFY_EXPR)
        op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
                                     maybe_const_itself);
+      STRIP_TYPE_NOPS (op1);
       op1 = decl_constant_value_for_optimization (op1);
       if (op0 != orig_op0 || op1 != orig_op1 || in_init)
        ret = in_init
-         ? fold_build2_initializer (code, TREE_TYPE (expr), op0, op1)
-         : fold_build2 (code, TREE_TYPE (expr), op0, op1);
+         ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
+         : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
       else
        ret = fold (expr);
+      if (TREE_OVERFLOW_P (ret)
+         && !TREE_OVERFLOW_P (op0)
+         && !TREE_OVERFLOW_P (op1))
+       overflow_warning (EXPR_LOCATION (expr), ret);
       goto out;
 
     case INDIRECT_REF:
@@ -1322,12 +1356,13 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       orig_op0 = op0 = TREE_OPERAND (expr, 0);
       op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
                                   maybe_const_itself);
+      STRIP_TYPE_NOPS (op0);
       if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
        op0 = decl_constant_value_for_optimization (op0);
       if (op0 != orig_op0 || in_init)
        ret = in_init
-         ? fold_build1_initializer (code, TREE_TYPE (expr), op0)
-         : fold_build1 (code, TREE_TYPE (expr), op0);
+         ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
+         : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
       else
        ret = fold (expr);
       if (code == INDIRECT_REF
@@ -1338,6 +1373,20 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
          TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
          TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
        }
+      switch (code)
+       {
+       case FIX_TRUNC_EXPR:
+       case FLOAT_EXPR:
+       CASE_CONVERT:
+         /* Don't warn about explicit conversions.  We will already
+            have warned about suspect implicit conversions.  */
+         break;
+
+       default:
+         if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0))
+           overflow_warning (EXPR_LOCATION (expr), ret);
+         break;
+       }
       goto out;
 
     case TRUTH_ANDIF_EXPR:
@@ -1347,11 +1396,20 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       orig_op0 = op0 = TREE_OPERAND (expr, 0);
       orig_op1 = op1 = TREE_OPERAND (expr, 1);
       op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
+      STRIP_TYPE_NOPS (op0);
+
+      unused_p = (op0 == (code == TRUTH_ANDIF_EXPR
+                         ? truthvalue_false_node
+                         : truthvalue_true_node));
+      c_inhibit_evaluation_warnings += unused_p;
       op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
+      STRIP_TYPE_NOPS (op1);
+      c_inhibit_evaluation_warnings -= unused_p;
+
       if (op0 != orig_op0 || op1 != orig_op1 || in_init)
        ret = in_init
-         ? fold_build2_initializer (code, TREE_TYPE (expr), op0, op1)
-         : fold_build2 (code, TREE_TYPE (expr), op0, op1);
+         ? fold_build2_initializer_loc (loc, code, TREE_TYPE (expr), op0, op1)
+         : fold_build2_loc (loc, code, TREE_TYPE (expr), op0, op1);
       else
        ret = fold (expr);
       *maybe_const_operands &= op0_const;
@@ -1376,10 +1434,20 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       orig_op1 = op1 = TREE_OPERAND (expr, 1);
       orig_op2 = op2 = TREE_OPERAND (expr, 2);
       op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self);
+
+      STRIP_TYPE_NOPS (op0);
+      c_inhibit_evaluation_warnings += (op0 == truthvalue_false_node);
       op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self);
+      STRIP_TYPE_NOPS (op1);
+      c_inhibit_evaluation_warnings -= (op0 == truthvalue_false_node);
+
+      c_inhibit_evaluation_warnings += (op0 == truthvalue_true_node);
       op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self);
+      STRIP_TYPE_NOPS (op2);
+      c_inhibit_evaluation_warnings -= (op0 == truthvalue_true_node);
+
       if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2)
-       ret = fold_build3 (code, TREE_TYPE (expr), op0, op1, op2);
+       ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2);
       else
        ret = fold (expr);
       *maybe_const_operands &= op0_const;
@@ -1620,7 +1688,8 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
   if (lhs && rhs && operand_equal_p (lhs, rhs, 0)
       && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
                       in1_p, low1, high1)
-      && 0 != (tem = build_range_check (type, lhs, in_p, low, high)))
+      && 0 != (tem = build_range_check (UNKNOWN_LOCATION,
+                                       type, lhs, in_p, low, high)))
     {
       if (TREE_CODE (tem) != INTEGER_CST)
        return;
@@ -3658,7 +3727,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
    of pointer PTROP and integer INTOP.  */
 
 tree
-pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
+pointer_int_sum (location_t loc, enum tree_code resultcode,
+                tree ptrop, tree intop)
 {
   tree size_exp, ret;
 
@@ -3667,19 +3737,19 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
 
   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
     {
-      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer of type %<void *%> used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
     {
-      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer to a function used in arithmetic");
       size_exp = integer_one_node;
     }
   else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
     {
-      pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+      pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
               "pointer to member function used in arithmetic");
       size_exp = integer_one_node;
     }
@@ -3734,21 +3804,46 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
      Do this multiplication as signed, then convert to the appropriate
      type for the pointer operation.  */
   intop = convert (sizetype,
-                  build_binary_op (EXPR_LOCATION (intop),
+                  build_binary_op (loc,
                                    MULT_EXPR, intop,
                                    convert (TREE_TYPE (intop), size_exp), 1));
 
   /* Create the sum or difference.  */
   if (resultcode == MINUS_EXPR)
-    intop = fold_build1 (NEGATE_EXPR, sizetype, intop);
+    intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop);
 
-  ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);
+  ret = fold_build2_loc (loc, POINTER_PLUS_EXPR, result_type, ptrop, intop);
 
   fold_undefer_and_ignore_overflow_warnings ();
 
   return ret;
 }
 \f
+/* Wrap a C_MAYBE_CONST_EXPR around an expression that is fully folded
+   and if NON_CONST is known not to be permitted in an evaluated part
+   of a constant expression.  */
+
+tree
+c_wrap_maybe_const (tree expr, bool non_const)
+{
+  bool nowarning = TREE_NO_WARNING (expr);
+  location_t loc = EXPR_LOCATION (expr);
+
+  /* This should never be called for C++.  */
+  if (c_dialect_cxx ())
+    gcc_unreachable ();
+
+  /* The result of folding may have a NOP_EXPR to set TREE_NO_WARNING.  */
+  STRIP_TYPE_NOPS (expr);
+  expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
+  C_MAYBE_CONST_EXPR_NON_CONST (expr) = non_const;
+  if (nowarning)
+    TREE_NO_WARNING (expr) = 1;
+  protected_set_expr_location (expr, loc);
+
+  return expr;
+}
+
 /* Wrap a SAVE_EXPR around EXPR, if appropriate.  Like save_expr, but
    for C folds the inside expression and wraps a C_MAYBE_CONST_EXPR
    around the SAVE_EXPR if needed so that c_fully_fold does not need
@@ -3763,10 +3858,7 @@ c_save_expr (tree expr)
   expr = c_fully_fold (expr, false, &maybe_const);
   expr = save_expr (expr);
   if (!maybe_const)
-    {
-      expr = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (expr), NULL, expr);
-      C_MAYBE_CONST_EXPR_NON_CONST (expr) = 1;
-    }
+    expr = c_wrap_maybe_const (expr, true);
   return expr;
 }
 
@@ -3925,7 +4017,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
       /* Distribute the conversion into the arms of a COND_EXPR.  */
       if (c_dialect_cxx ())
        {
-         expr = fold_build3 (COND_EXPR, truthvalue_type_node,
+         expr = fold_build3_loc (location, COND_EXPR, truthvalue_type_node,
                              TREE_OPERAND (expr, 0),
                              c_common_truthvalue_conversion (location,
                                                              TREE_OPERAND (expr,
@@ -4109,6 +4201,15 @@ c_common_get_alias_set (tree t)
   tree u;
   PTR *slot;
 
+  /* For VLAs, use the alias set of the element type rather than the
+     default of alias set 0 for types compared structurally.  */
+  if (TYPE_P (t) && TYPE_STRUCTURAL_EQUALITY_P (t))
+    {
+      if (TREE_CODE (t) == ARRAY_TYPE)
+       return get_alias_set (TREE_TYPE (t));
+      return -1;
+    }
+
   /* Permit type-punning when accessing a union, provided the access
      is directly through the union.  For example, this code does not
      permit taking the address of a union member and then storing
@@ -4290,9 +4391,9 @@ c_sizeof_or_alignof_type (location_t loc,
     {
       if (is_sizeof)
        /* Convert in case a char is more than one unit.  */
-       value = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-                           size_int (TYPE_PRECISION (char_type_node)
-                                     / BITS_PER_UNIT));
+       value = size_binop_loc (loc, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+                               size_int (TYPE_PRECISION (char_type_node)
+                                         / BITS_PER_UNIT));
       else
        value = size_int (TYPE_ALIGN_UNIT (type));
     }
@@ -4301,7 +4402,7 @@ c_sizeof_or_alignof_type (location_t loc,
      TYPE_IS_SIZETYPE means that certain things (like overflow) will
      never happen.  However, this node should really have type
      `size_t', which is just a typedef for an ordinary integer type.  */
-  value = fold_convert (size_type_node, value);
+  value = fold_convert_loc (loc, size_type_node, value);
   gcc_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)));
 
   return value;
@@ -4352,7 +4453,7 @@ c_alignof_expr (location_t loc, tree expr)
   else
     return c_alignof (loc, TREE_TYPE (expr));
 
-  return fold_convert (size_type_node, t);
+  return fold_convert_loc (loc, size_type_node, t);
 }
 \f
 /* Handle C and C++ default attributes.  */
@@ -4991,44 +5092,6 @@ c_common_nodes_and_builtins (void)
   memset (builtin_types, 0, sizeof (builtin_types));
 }
 
-/* Look up the function in built_in_decls that corresponds to DECL
-   and set ASMSPEC as its user assembler name.  DECL must be a
-   function decl that declares a builtin.  */
-
-void
-set_builtin_user_assembler_name (tree decl, const char *asmspec)
-{
-  tree builtin;
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-             && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-             && asmspec != 0);
-
-  builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
-  set_user_assembler_name (builtin, asmspec);
-  switch (DECL_FUNCTION_CODE (decl))
-    {
-    case BUILT_IN_MEMCPY:
-      init_block_move_fn (asmspec);
-      memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
-      break;
-    case BUILT_IN_MEMSET:
-      init_block_clear_fn (asmspec);
-      memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
-      break;
-    case BUILT_IN_MEMMOVE:
-      memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
-      break;
-    case BUILT_IN_MEMCMP:
-      memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
-      break;
-    case BUILT_IN_ABORT:
-      abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
-      break;
-    default:
-      break;
-    }
-}
-
 /* The number of named compound-literals generated thus far.  */
 static GTY(()) int compound_literal_number;
 
@@ -5628,11 +5691,11 @@ boolean_increment (enum tree_code code, tree arg)
       break;
     case PREDECREMENT_EXPR:
       val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg,
-                   invert_truthvalue (arg));
+                   invert_truthvalue_loc (input_location, arg));
       break;
     case POSTDECREMENT_EXPR:
       val = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg,
-                   invert_truthvalue (arg));
+                   invert_truthvalue_loc (input_location, arg));
       arg = save_expr (arg);
       val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), val, arg);
       val = build2 (COMPOUND_EXPR, TREE_TYPE (arg), arg, val);
@@ -5910,6 +5973,23 @@ handle_noinline_attribute (tree *node, tree name,
   return NULL_TREE;
 }
 
+/* Handle a "noclone" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_noclone_attribute (tree *node, tree name,
+                         tree ARG_UNUSED (args),
+                         int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "always_inline" attribute; arguments as in
    struct attribute_spec.handler.  */
 
@@ -6397,9 +6477,10 @@ handle_mode_attribute (tree *node, tree name, tree args,
 
       if (POINTER_TYPE_P (type))
        {
+         addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
          tree (*fn)(tree, enum machine_mode, bool);
 
-         if (!targetm.valid_pointer_mode (mode))
+         if (!targetm.addr_space.valid_pointer_mode (mode, as))
            {
              error ("invalid pointer mode %qs", p);
              return NULL_TREE;
@@ -7744,6 +7825,8 @@ parse_optimize_options (tree args, bool attr_p)
   /* Now parse the options.  */
   decode_options (opt_argc, opt_argv);
 
+  targetm.override_options_after_change();
+
   /* Don't allow changing -fstrict-aliasing.  */
   flag_strict_aliasing = saved_flag_strict_aliasing;
 
@@ -8128,7 +8211,8 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
   else if (token_type == CPP_STRING 
           || token_type == CPP_WSTRING 
           || token_type == CPP_STRING16
-          || token_type == CPP_STRING32)
+          || token_type == CPP_STRING32
+          || token_type == CPP_UTF8STRING)
     message = catenate_messages (gmsgid, " before string constant");
   else if (token_type == CPP_NUMBER)
     message = catenate_messages (gmsgid, " before numeric constant");
@@ -8223,69 +8307,6 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
   return ret;
 }
 
-/* Walk a gimplified function and warn for functions whose return value is
-   ignored and attribute((warn_unused_result)) is set.  This is done before
-   inlining, so we don't have to worry about that.  */
-
-void
-c_warn_unused_result (gimple_seq seq)
-{
-  tree fdecl, ftype;
-  gimple_stmt_iterator i;
-
-  for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
-    {
-      gimple g = gsi_stmt (i);
-
-      switch (gimple_code (g))
-       {
-       case GIMPLE_BIND:
-         c_warn_unused_result (gimple_bind_body (g));
-         break;
-       case GIMPLE_TRY:
-         c_warn_unused_result (gimple_try_eval (g));
-         c_warn_unused_result (gimple_try_cleanup (g));
-         break;
-       case GIMPLE_CATCH:
-         c_warn_unused_result (gimple_catch_handler (g));
-         break;
-       case GIMPLE_EH_FILTER:
-         c_warn_unused_result (gimple_eh_filter_failure (g));
-         break;
-
-       case GIMPLE_CALL:
-         if (gimple_call_lhs (g))
-           break;
-
-         /* This is a naked call, as opposed to a GIMPLE_CALL with an
-            LHS.  All calls whose value is ignored should be
-            represented like this.  Look for the attribute.  */
-         fdecl = gimple_call_fndecl (g);
-         ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g)));
-
-         if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
-           {
-             location_t loc = gimple_location (g);
-
-             if (fdecl)
-               warning_at (loc, OPT_Wunused_result, 
-                           "ignoring return value of %qD, "
-                           "declared with attribute warn_unused_result",
-                           fdecl);
-             else
-               warning_at (loc, OPT_Wunused_result,
-                           "ignoring return value of function "
-                           "declared with attribute warn_unused_result");
-           }
-         break;
-
-       default:
-         /* Not a container, not a call, or a call whose value is used.  */
-         break;
-       }
-    }
-}
-
 /* Convert a character from the host to the target execution character
    set.  cpplib handles this, mostly.  */
 
@@ -8335,15 +8356,14 @@ fold_offsetof_1 (tree expr, tree stop_ref)
       error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
       return error_mark_node;
 
-    case INTEGER_CST:
-      gcc_assert (integer_zerop (expr));
-      return size_zero_node;
-
     case NOP_EXPR:
     case INDIRECT_REF:
-      base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
-      gcc_assert (base == error_mark_node || base == size_zero_node);
-      return base;
+      if (!integer_zerop (TREE_OPERAND (expr, 0)))
+       {
+         error ("cannot apply %<offsetof%> to a non constant address");
+         return error_mark_node;
+       }
+      return size_zero_node;
 
     case COMPONENT_REF:
       base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
@@ -8357,9 +8377,10 @@ fold_offsetof_1 (tree expr, tree stop_ref)
                 "member %qD", t);
          return error_mark_node;
        }
-      off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
-                       size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
-                                 / BITS_PER_UNIT));
+      off = size_binop_loc (input_location, PLUS_EXPR, DECL_FIELD_OFFSET (t),
+                           size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t),
+                                                   1)
+                                     / BITS_PER_UNIT));
       break;
 
     case ARRAY_REF:
@@ -8371,10 +8392,21 @@ fold_offsetof_1 (tree expr, tree stop_ref)
       if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
        {
          code = MINUS_EXPR;
-         t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
+         t = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (t), t);
        }
       t = convert (sizetype, t);
       off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
+
+      /* Check if the offset goes beyond the upper bound of the array.  */
+      {
+       tree nelts = array_type_nelts (TREE_TYPE (TREE_OPERAND (expr, 0)));
+        HOST_WIDE_INT index = int_cst_value (t);
+       if (index > int_cst_value (nelts))
+         warning (OPT_Warray_bounds,
+                  "index " HOST_WIDE_INT_PRINT_DEC " denotes an offset "
+                  "greater than size of %qT",
+                  index, TREE_TYPE (TREE_OPERAND (expr, 0)));
+      }
       break;
 
     case COMPOUND_EXPR:
@@ -8464,9 +8496,9 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
              bool fold_p = false;
 
              if (VEC_index (constructor_elt, v, 0)->index)
-               maxindex = fold_convert (sizetype,
-                                        VEC_index (constructor_elt,
-                                                   v, 0)->index);
+               maxindex = fold_convert_loc (input_location, sizetype,
+                                            VEC_index (constructor_elt,
+                                                       v, 0)->index);
              curindex = maxindex;
 
              for (cnt = 1;
@@ -8480,7 +8512,8 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
                    {
                      if (fold_p)
                        curindex = fold_convert (sizetype, curindex);
-                     curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
+                     curindex = size_binop (PLUS_EXPR, curindex,
+                                            size_one_node);
                    }
                  if (tree_int_cst_lt (maxindex, curindex))
                    maxindex = curindex, fold_p = curfold_p;
@@ -8509,7 +8542,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
   if (quals == 0)
     unqual_elt = elt;
   else
-    unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
+    unqual_elt = c_build_qualified_type (elt, KEEP_QUAL_ADDR_SPACE (quals));
 
   /* Using build_distinct_type_copy and modifying things afterward instead
      of using build_array_type to create a new type preserves all of the
@@ -9186,6 +9219,31 @@ is_typedef_decl (tree x)
           && DECL_ORIGINAL_TYPE (x) != NULL_TREE);
 }
 
+/* Record the types used by the current global variable declaration
+   being parsed, so that we can decide later to emit their debug info.
+   Those types are in types_used_by_cur_var_decl, and we are going to
+   store them in the types_used_by_vars_hash hash table.
+   DECL is the declaration of the global variable that has been parsed.  */
+
+void
+record_types_used_by_current_var_decl (tree decl)
+{
+  gcc_assert (decl && DECL_P (decl) && TREE_STATIC (decl));
+
+  if (types_used_by_cur_var_decl)
+    {
+      tree node;
+      for (node = types_used_by_cur_var_decl;
+          node;
+          node = TREE_CHAIN (node))
+      {
+       tree type = TREE_PURPOSE (node);
+       types_used_by_var_decl_insert (type, decl);
+      }
+      types_used_by_cur_var_decl = NULL;
+    }
+}
+
 /* The C and C++ parsers both use vectors to hold function arguments.
    For efficiency, we keep a cache of unused vectors.  This is the
    cache.  */