OSDN Git Service

* c-common.c (c_common_reswords): Add _Static_assert for C.
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index 4de92d0..942961d 100644 (file)
@@ -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 @@ along with GCC; see the file COPYING3.  If not see
 #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"
@@ -49,7 +48,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "real.h"
 #include "cgraph.h"
 #include "target-def.h"
-#include "gimple.h"
 #include "fixed-value.h"
 #include "libfuncs.h"
 
@@ -280,10 +278,14 @@ int flag_cond_mismatch;
 
 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 +426,6 @@ int flag_threadsafe_statics = 1;
 
 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 +528,7 @@ static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
 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 +563,7 @@ const struct c_common_resword c_common_reswords[] =
   { "_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 +657,7 @@ const struct c_common_resword c_common_reswords[] =
   { "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 },
@@ -710,6 +711,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 =
@@ -824,6 +830,10 @@ const struct attribute_spec c_common_attribute_table[] =
                              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 }
 };
 
@@ -840,6 +850,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
@@ -1219,6 +1242,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)
@@ -1235,8 +1259,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);
@@ -1293,6 +1319,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
@@ -1304,6 +1331,7 @@ 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
@@ -1333,6 +1361,7 @@ 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)
@@ -1372,12 +1401,14 @@ 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)
@@ -1409,12 +1440,15 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       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)
@@ -1513,7 +1547,7 @@ decl_constant_value_for_optimization (tree exp)
 void
 constant_expression_warning (tree value)
 {
-  if (warn_overflow && pedantic 
+  if (warn_overflow && pedantic
       && (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
          || TREE_CODE (value) == FIXED_CST
          || TREE_CODE (value) == VECTOR_CST
@@ -1556,12 +1590,12 @@ overflow_warning (location_t loc, tree value)
     case INTEGER_CST:
       warning_at (loc, OPT_Woverflow, "integer overflow in expression");
       break;
-      
+
     case REAL_CST:
       warning_at (loc, OPT_Woverflow,
                  "floating point overflow in expression");
       break;
-      
+
     case FIXED_CST:
       warning_at (loc, OPT_Woverflow, "fixed-point overflow in expression");
       break;
@@ -1569,7 +1603,7 @@ overflow_warning (location_t loc, tree value)
     case VECTOR_CST:
       warning_at (loc, OPT_Woverflow, "vector overflow in expression");
       break;
-      
+
     case COMPLEX_CST:
       if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST)
        warning_at (loc, OPT_Woverflow,
@@ -1591,7 +1625,7 @@ overflow_warning (location_t loc, tree value)
    had CODE_LEFT and CODE_RIGHT, into an expression of type TYPE.  */
 void
 warn_logical_operator (location_t location, enum tree_code code, tree type,
-                      enum tree_code code_left, tree op_left, 
+                      enum tree_code code_left, tree op_left,
                       enum tree_code ARG_UNUSED (code_right), tree op_right)
 {
   int or_op = (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR);
@@ -1648,12 +1682,12 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
 
   if (rhs && TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
     rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
-  
+
   /* If this is an OR operation, invert both sides; we will invert
      again at the end.  */
   if (or_op)
     in0_p = !in0_p, in1_p = !in1_p;
-  
+
   /* If both expressions are the same, if we can merge the ranges, and we
      can build the range test, return it or it inverted.  */
   if (lhs && rhs && operand_equal_p (lhs, rhs, 0)
@@ -1712,7 +1746,7 @@ strict_aliasing_warning (tree otype, tree type, tree expr)
        }
       else
         {
-          /* warn_strict_aliasing >= 3.   This includes the default (3).  
+          /* warn_strict_aliasing >= 3.   This includes the default (3).
              Only warn if the cast is dereferenced immediately.  */
           alias_set_type set1 =
            get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -1777,7 +1811,7 @@ check_main_parameter_types (tree decl)
        {
        case 1:
          if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-           pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %<int%>", 
+           pedwarn (input_location, OPT_Wmain, "first argument of %q+D should be %<int%>",
                    decl);
          break;
 
@@ -1872,7 +1906,7 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note)
    both args are zero-extended or both are sign-extended.
    Otherwise, we might change the result.
    Eg, (short)-1 | (unsigned short)-1 is (int)-1
-   but calculated in (unsigned short) it would be (unsigned short)-1.  
+   but calculated in (unsigned short) it would be (unsigned short)-1.
 */
 tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
 {
@@ -1887,13 +1921,13 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
      from signed char and that RESULT_TYPE is long long int.
      If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
      like
-     
+
      (long long int) (unsigned int) signed_char
 
      which get_narrower would narrow down to
-     
+
      (unsigned int) signed char
-     
+
      If we do not cast OP0 first, get_narrower would return
      signed_char, which is inconsistent with the case of the
      explicit cast.  */
@@ -1908,7 +1942,7 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
 
   /* Handle the case that OP0 (or OP1) does not *contain* a conversion
      but it *requires* conversion to FINAL_TYPE.  */
-  
+
   if ((TYPE_PRECISION (TREE_TYPE (op0))
        == TYPE_PRECISION (TREE_TYPE (arg0)))
       && TREE_TYPE (op0) != result_type)
@@ -1917,18 +1951,18 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
        == TYPE_PRECISION (TREE_TYPE (arg1)))
       && TREE_TYPE (op1) != result_type)
     unsigned1 = TYPE_UNSIGNED (TREE_TYPE (op1));
-  
+
   /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
-  
+
   /* For bitwise operations, signedness of nominal type
      does not matter.  Consider only how operands were extended.  */
   if (bitwise)
     uns = unsigned0;
-  
+
   /* Note that in all three cases below we refrain from optimizing
      an unsigned operation on sign-extended args.
      That would not be valid.  */
-  
+
   /* Both args variable: if both extended in same way
      from same width, do it in that width.
      Do it unsigned if args were zero-extended.  */
@@ -2007,7 +2041,7 @@ conversion_warning (tree type, tree expr)
       /* Conversion from boolean to a signed:1 bit-field (which only
         can hold the values 0 and -1) doesn't lose information - but
         it does change the value.  */
-      if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type)) 
+      if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
        warning (OPT_Wconversion,
                  "conversion to %qT from boolean expression", type);
       return;
@@ -2028,7 +2062,7 @@ conversion_warning (tree type, tree expr)
                && TREE_CODE (type) == INTEGER_TYPE
                && !int_fits_type_p (expr, type))
         {
-          if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type) 
+          if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type)
              && tree_int_cst_sgn (expr) < 0)
            warning (OPT_Wsign_conversion,
                     "negative integer implicitly converted to unsigned type");
@@ -2073,7 +2107,7 @@ conversion_warning (tree type, tree expr)
        tree op1 = TREE_OPERAND (expr, 1);
        tree op2 = TREE_OPERAND (expr, 2);
 
-       if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST 
+       if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST
             || TREE_CODE (op1) == COND_EXPR)
            && (TREE_CODE (op2) == REAL_CST || TREE_CODE (op2) == INTEGER_CST
                || TREE_CODE (op2) == COND_EXPR))
@@ -2100,15 +2134,15 @@ conversion_warning (tree type, tree expr)
          expr_type = TREE_TYPE (expr);
 
          /* Don't warn for short y; short x = ((int)y & 0xff);  */
-         if (TREE_CODE (expr) == BIT_AND_EXPR 
-               || TREE_CODE (expr) == BIT_IOR_EXPR 
+         if (TREE_CODE (expr) == BIT_AND_EXPR
+               || TREE_CODE (expr) == BIT_IOR_EXPR
              || TREE_CODE (expr) == BIT_XOR_EXPR)
            {
              /* If both args were extended from a shortest type,
                 use that type if that is safe.  */
-             expr_type = shorten_binary_op (expr_type, 
-                                            TREE_OPERAND (expr, 0), 
-                                            TREE_OPERAND (expr, 1), 
+             expr_type = shorten_binary_op (expr_type,
+                                            TREE_OPERAND (expr, 0),
+                                            TREE_OPERAND (expr, 1),
                                             /* bitwise */1);
 
              if (TREE_CODE (expr) == BIT_AND_EXPR)
@@ -2126,13 +2160,13 @@ conversion_warning (tree type, tree expr)
                       && int_fits_type_p (op0, c_common_unsigned_type (type)))
                      || (TREE_CODE (op1) == INTEGER_CST
                          && int_fits_type_p (op1, c_common_signed_type (type))
-                         && int_fits_type_p (op1, 
+                         && int_fits_type_p (op1,
                                              c_common_unsigned_type (type))))
                    return;
                  /* If constant is unsigned and fits in the target
                     type, then the result will also fit.  */
                  else if ((TREE_CODE (op0) == INTEGER_CST
-                           && unsigned0 
+                           && unsigned0
                            && int_fits_type_p (op0, type))
                           || (TREE_CODE (op1) == INTEGER_CST
                               && unsigned1
@@ -2141,7 +2175,7 @@ conversion_warning (tree type, tree expr)
                }
            }
           /* Warn for integer types converted to smaller integer types.  */
-         if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type)) 
+         if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
            give_warning = true;
 
          /* When they are the same width but different signedness,
@@ -2163,12 +2197,17 @@ conversion_warning (tree type, tree expr)
       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))
@@ -2216,7 +2255,7 @@ warnings_for_convert_and_check (tree type, tree expr, tree result)
           else
             conversion_warning (type, expr);
         }
-      else if (!int_fits_type_p (expr, c_common_unsigned_type (type))) 
+      else if (!int_fits_type_p (expr, c_common_unsigned_type (type)))
        warning (OPT_Woverflow,
                 "overflow in implicit constant conversion");
       /* No warning for converting 0x80000000 to int.  */
@@ -2265,7 +2304,7 @@ convert_and_check (tree type, tree expr)
 
   if (TREE_TYPE (expr) == type)
     return expr;
-  
+
   result = convert (type, expr);
 
   if (c_inhibit_evaluation_warnings == 0
@@ -2571,7 +2610,7 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
       {
        call_expr_arg_iterator iter;
        tree arg;
-       tmp_before = tmp_nosp = 0; 
+       tmp_before = tmp_nosp = 0;
        verify_tree (CALL_EXPR_FN (x), &tmp_before, &tmp_nosp, NULL_TREE);
        FOR_EACH_CALL_EXPR_ARG (arg, iter, x)
          {
@@ -3656,7 +3695,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
                  && !(TREE_CODE (primop0) == INTEGER_CST
                       && !TREE_OVERFLOW (convert (c_common_signed_type (type),
                                                   primop0))))
-               warning (OPT_Wtype_limits, 
+               warning (OPT_Wtype_limits,
                         "comparison of unsigned expression >= 0 is always true");
              value = truthvalue_true_node;
              break;
@@ -3666,7 +3705,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
                  && !(TREE_CODE (primop0) == INTEGER_CST
                       && !TREE_OVERFLOW (convert (c_common_signed_type (type),
                                                   primop0))))
-               warning (OPT_Wtype_limits, 
+               warning (OPT_Wtype_limits,
                         "comparison of unsigned expression < 0 is always false");
              value = truthvalue_false_node;
              break;
@@ -3708,19 +3747,19 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
 
   if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
     {
-      pedwarn (loc, 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 (loc, 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 (loc, 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;
     }
@@ -3772,12 +3811,18 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
                                             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)
@@ -3790,6 +3835,31 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
   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
@@ -3804,10 +3874,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;
 }
 
@@ -3861,7 +3928,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
       if (TREE_TYPE (expr) == truthvalue_type_node)
        return expr;
       expr = build2 (TREE_CODE (expr), truthvalue_type_node,
-                    c_common_truthvalue_conversion (location, 
+                    c_common_truthvalue_conversion (location,
                                                     TREE_OPERAND (expr, 0)),
                     c_common_truthvalue_conversion (location,
                                                     TREE_OPERAND (expr, 1)));
@@ -3954,7 +4021,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
        {
          expr = build2 (COMPOUND_EXPR, truthvalue_type_node,
                         TREE_OPERAND (expr, 1),
-                        c_common_truthvalue_conversion 
+                        c_common_truthvalue_conversion
                         (location, TREE_OPERAND (expr, 0)));
          goto ret;
        }
@@ -4150,6 +4217,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
@@ -4301,7 +4377,7 @@ c_sizeof_or_alignof_type (location_t loc,
       if (is_sizeof)
        {
          if (complain && (pedantic || warn_pointer_arith))
-           pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+           pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
                     "invalid application of %<sizeof%> to a function type");
           else if (!complain)
             return error_mark_node;
@@ -4314,7 +4390,7 @@ c_sizeof_or_alignof_type (location_t loc,
     {
       if (type_code == VOID_TYPE
          && complain && (pedantic || warn_pointer_arith))
-       pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+       pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
                 "invalid application of %qs to a void type", op_name);
       else if (!complain)
         return error_mark_node;
@@ -4325,7 +4401,7 @@ c_sizeof_or_alignof_type (location_t loc,
       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
     {
@@ -4710,7 +4786,7 @@ c_common_nodes_and_builtins (void)
 
   /* Only supported decimal floating point extension if the target
      actually supports underlying modes. */
-  if (targetm.scalar_mode_supported_p (SDmode) 
+  if (targetm.scalar_mode_supported_p (SDmode)
       && targetm.scalar_mode_supported_p (DDmode)
       && targetm.scalar_mode_supported_p (TDmode))
     {
@@ -5032,44 +5108,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;
 
@@ -5310,7 +5348,7 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type,
 
   /* Case ranges are a GNU extension.  */
   if (high_value)
-    pedwarn (loc, OPT_pedantic, 
+    pedwarn (loc, OPT_pedantic,
             "range expressions in switch statements are non-standard");
 
   type = TREE_TYPE (cond);
@@ -5636,7 +5674,7 @@ finish_label_address_expr (tree label, location_t loc)
     {
       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);
@@ -5776,6 +5814,20 @@ c_init_attributes (void)
 #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
@@ -6094,6 +6146,8 @@ handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args),
     {
       TREE_USED (node) = 1;
       DECL_PRESERVE_P (node) = 1;
+      if (TREE_CODE (node) == VAR_DECL)
+       DECL_READ_P (node) = 1;
     }
   else
     {
@@ -6120,7 +6174,12 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
          || 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);
@@ -6225,7 +6284,7 @@ handle_transparent_union_attribute (tree *node, tree name,
          *node = type = build_duplicate_type (type);
        }
 
-      TYPE_TRANSPARENT_UNION (type) = 1;
+      TYPE_TRANSPARENT_AGGR (type) = 1;
       return NULL_TREE;
     }
 
@@ -6247,7 +6306,7 @@ get_priority (tree args, bool is_destructor)
 
   if (!args)
     return DEFAULT_INIT_PRIORITY;
-  
+
   if (!SUPPORTS_INIT_PRIORITY)
     {
       if (is_destructor)
@@ -6271,12 +6330,12 @@ get_priority (tree args, bool is_destructor)
       if (is_destructor)
        warning (0,
                 "destructor priorities from 0 to %d are reserved "
-                "for the implementation", 
+                "for the implementation",
                 MAX_RESERVED_INIT_PRIORITY);
       else
        warning (0,
                 "constructor priorities from 0 to %d are reserved "
-                "for the implementation", 
+                "for the implementation",
                 MAX_RESERVED_INIT_PRIORITY);
     }
   return pri;
@@ -6455,9 +6514,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;
@@ -6555,7 +6615,7 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args,
              && current_function_decl != NULL_TREE
              && !TREE_STATIC (decl))
            {
-             error_at (DECL_SOURCE_LOCATION (decl), 
+             error_at (DECL_SOURCE_LOCATION (decl),
                        "section attribute cannot be specified for "
                        "local variables");
              *no_add_attrs = true;
@@ -6637,10 +6697,12 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
     }
   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);
@@ -6649,7 +6711,7 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
          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;
@@ -6721,11 +6783,11 @@ handle_alias_attribute (tree *node, tree name, tree args,
       *no_add_attrs = true;
     }
   else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
-      || (TREE_CODE (decl) != FUNCTION_DECL 
+      || (TREE_CODE (decl) != FUNCTION_DECL
          && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
       /* A static variable declaration is always a tentative definition,
         but the alias is a non-tentative definition which overrides.  */
-      || (TREE_CODE (decl) != FUNCTION_DECL 
+      || (TREE_CODE (decl) != FUNCTION_DECL
          && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl)))
     {
       error ("%q+D defined both normally and as an alias", decl);
@@ -7068,11 +7130,11 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
       tree position = TREE_VALUE (args);
 
       if (TREE_CODE (position) != INTEGER_CST
-         || TREE_INT_CST_HIGH (position) 
+         || TREE_INT_CST_HIGH (position)
          || TREE_INT_CST_LOW (position) < 1
          || TREE_INT_CST_LOW (position) > arg_count )
        {
-         warning (OPT_Wattributes, 
+         warning (OPT_Wattributes,
                   "alloc_size parameter outside range");
          *no_add_attrs = true;
          return NULL_TREE;
@@ -7081,6 +7143,20 @@ handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
   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.  */
 
@@ -7630,7 +7706,7 @@ handle_sentinel_attribute (tree *node, tree name, tree args,
 
       if (TREE_CODE (position) != INTEGER_CST)
        {
-         warning (OPT_Wattributes, 
+         warning (OPT_Wattributes,
                   "requested position is not an integer constant");
          *no_add_attrs = true;
        }
@@ -7656,10 +7732,10 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
                               bool * ARG_UNUSED (no_add_attrs))
 {
   tree params;
-  
+
   /* Ensure we have a function type.  */
   gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE);
-  
+
   params = TYPE_ARG_TYPES (*node);
   while (params && ! VOID_TYPE_P (TREE_VALUE (params)))
     params = TREE_CHAIN (params);
@@ -7802,6 +7878,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;
 
@@ -7950,21 +8028,24 @@ check_function_arguments_recurse (void (*callback)
   (*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;
@@ -7983,14 +8064,14 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
   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)
            {
@@ -8008,7 +8089,7 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
     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]));
@@ -8026,10 +8107,10 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
       return false;
 
     case BUILT_IN_FPCLASSIFY:
-      if (validate_nargs (fndecl, nargs, 6))
+      if (builtin_function_validate_nargs (fndecl, nargs, 6))
        {
          unsigned i;
-         
+
          for (i=0; i<5; i++)
            if (TREE_CODE (args[i]) != INTEGER_CST)
              {
@@ -8141,7 +8222,7 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
    TOKEN, which had the associated VALUE.  */
 
 void
-c_parse_error (const char *gmsgid, enum cpp_ttype token_type, 
+c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
               tree value, unsigned char token_flags)
 {
 #define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
@@ -8150,8 +8231,8 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
 
   if (token_type == CPP_EOF)
     message = catenate_messages (gmsgid, " at end of input");
-  else if (token_type == CPP_CHAR 
-          || token_type == CPP_WCHAR 
+  else if (token_type == CPP_CHAR
+          || token_type == CPP_WCHAR
           || token_type == CPP_CHAR16
           || token_type == CPP_CHAR32)
     {
@@ -8183,10 +8264,11 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
       free (message);
       message = NULL;
     }
-  else if (token_type == CPP_STRING 
-          || token_type == CPP_WSTRING 
+  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");
@@ -8219,8 +8301,52 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
 #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
@@ -8228,7 +8354,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
    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)
 {
@@ -8275,6 +8401,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
                                  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;
@@ -8330,15 +8458,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);
@@ -8371,6 +8498,48 @@ fold_offsetof_1 (tree expr, tree stop_ref)
        }
       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.  */
+      if (code == PLUS_EXPR && TREE_CODE (t) == INTEGER_CST)
+       {
+         tree upbound = array_ref_up_bound (expr);
+         if (upbound != NULL_TREE
+             && TREE_CODE (upbound) == INTEGER_CST
+             && !tree_int_cst_equal (upbound,
+                                     TYPE_MAX_VALUE (TREE_TYPE (upbound))))
+           {
+             upbound = size_binop (PLUS_EXPR, upbound,
+                                   build_int_cst (TREE_TYPE (upbound), 1));
+             if (tree_int_cst_lt (upbound, t))
+               {
+                 tree v;
+
+                 for (v = TREE_OPERAND (expr, 0);
+                      TREE_CODE (v) == COMPONENT_REF;
+                      v = TREE_OPERAND (v, 0))
+                   if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                       == RECORD_TYPE)
+                     {
+                       tree fld_chain = TREE_CHAIN (TREE_OPERAND (v, 1));
+                       for (; fld_chain; fld_chain = TREE_CHAIN (fld_chain))
+                         if (TREE_CODE (fld_chain) == FIELD_DECL)
+                           break;
+
+                       if (fld_chain)
+                         break;
+                     }
+                 /* Don't warn if the array might be considered a poor
+                    man's flexible array member with a very permissive
+                    definition thereof.  */
+                 if (TREE_CODE (v) == ARRAY_REF
+                     || TREE_CODE (v) == COMPONENT_REF)
+                   warning (OPT_Warray_bounds,
+                            "index %E denotes an offset "
+                            "greater than size of %qT",
+                            t, TREE_TYPE (TREE_OPERAND (expr, 0)));
+               }
+           }
+       }
       break;
 
     case COMPOUND_EXPR:
@@ -8506,7 +8675,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
@@ -8518,7 +8687,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
 
   /* Make sure we have the canonical MAIN_TYPE. */
   hashcode = iterative_hash_object (TYPE_HASH (unqual_elt), hashcode);
-  hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (main_type)), 
+  hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (main_type)),
                                    hashcode);
   main_type = type_hash_canon (hashcode, main_type);
 
@@ -8529,7 +8698,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
   else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type)
           || (TYPE_CANONICAL (TYPE_DOMAIN (main_type))
               != TYPE_DOMAIN (main_type)))
-    TYPE_CANONICAL (main_type) 
+    TYPE_CANONICAL (main_type)
       = build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)),
                          TYPE_CANONICAL (TYPE_DOMAIN (main_type)));
   else
@@ -8611,7 +8780,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params)
 {
   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 *"
@@ -8619,7 +8787,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params)
      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.  */
@@ -8644,7 +8811,6 @@ sync_resolve_params (tree orig_function, tree function, VEC(tree, gc) *params)
       VEC_replace (tree, params, parmnum, val);
 
       arg_types = TREE_CHAIN (arg_types);
-      number++;
     }
 
   /* The definition of these primitives is variadic, with the remaining
@@ -8824,7 +8990,7 @@ warn_about_parentheses (enum tree_code code,
         || ((CODE) != INTEGER_CST                                          \
             && (integer_onep (ARG) || integer_zerop (ARG))))
 
-  switch (code) 
+  switch (code)
     {
     case LSHIFT_EXPR:
       if (code_left == PLUS_EXPR || code_right == PLUS_EXPR)
@@ -8974,16 +9140,16 @@ warn_for_div_by_zero (location_t loc, tree divisor)
    The arguments of this function map directly to local variables
    of build_binary_op.  */
 
-void 
+void
 warn_for_sign_compare (location_t location,
-                      tree orig_op0, tree orig_op1, 
-                      tree op0, tree op1, 
+                      tree orig_op0, tree orig_op1,
+                      tree op0, tree op1,
                       tree result_type, enum tree_code resultcode)
 {
   int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0));
   int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1));
   int unsignedp0, unsignedp1;
-  
+
   /* In C++, check for comparison of different enum types.  */
   if (c_dialect_cxx()
       && TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE
@@ -9011,10 +9177,10 @@ warn_for_sign_compare (location_t location,
 
       if (op0_signed)
         sop = orig_op0, uop = orig_op1;
-      else 
+      else
         sop = orig_op1, uop = orig_op0;
 
-      STRIP_TYPE_NOPS (sop); 
+      STRIP_TYPE_NOPS (sop);
       STRIP_TYPE_NOPS (uop);
       base_type = (TREE_CODE (result_type) == COMPLEX_TYPE
                   ? TREE_TYPE (result_type) : result_type);
@@ -9040,23 +9206,23 @@ warn_for_sign_compare (location_t location,
                && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (uop)),
                                   c_common_signed_type (base_type)))
         /* OK */;
-      else 
+      else
         warning_at (location,
-                   OPT_Wsign_compare, 
+                   OPT_Wsign_compare,
                    "comparison between signed and unsigned integer expressions");
     }
-  
+
   /* Warn if two unsigned values are being compared in a size larger
      than their original size, and one (and only one) is the result of
      a `~' operator.  This comparison will always fail.
-     
+
      Also warn if one operand is a constant, and the constant does not
      have all bits set that are set in the ~ operand when it is
      extended.  */
 
   op0 = get_narrower (op0, &unsignedp0);
   op1 = get_narrower (op1, &unsignedp1);
-  
+
   if ((TREE_CODE (op0) == BIT_NOT_EXPR)
       ^ (TREE_CODE (op1) == BIT_NOT_EXPR))
     {
@@ -9071,7 +9237,7 @@ warn_for_sign_compare (location_t location,
           HOST_WIDE_INT constant, mask;
           int unsignedp;
           unsigned int bits;
-          
+
           if (host_integerp (op0, 0))
             {
               primop = op1;
@@ -9084,7 +9250,7 @@ warn_for_sign_compare (location_t location,
               unsignedp = unsignedp0;
               constant = tree_low_cst (op1, 0);
             }
-          
+
           bits = TYPE_PRECISION (TREE_TYPE (primop));
           if (bits < TYPE_PRECISION (result_type)
               && bits < HOST_BITS_PER_LONG && unsignedp)
@@ -9093,10 +9259,10 @@ warn_for_sign_compare (location_t location,
               if ((mask & constant) != mask)
                {
                  if (constant == 0)
-                   warning (OPT_Wsign_compare, 
+                   warning (OPT_Wsign_compare,
                             "promoted ~unsigned is always non-zero");
                  else
-                   warning_at (location, OPT_Wsign_compare, 
+                   warning_at (location, OPT_Wsign_compare,
                                "comparison of promoted ~unsigned with constant");
                }
             }