OSDN Git Service

2010-04-09 Manuel López-Ibáñez <manu@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cp / typeck.c
index 54ccbfe..383754b 100644 (file)
@@ -61,7 +61,6 @@ static void casts_away_constness_r (tree *, tree *);
 static bool casts_away_constness (tree, tree);
 static void maybe_warn_about_returning_address_of_local (tree);
 static tree lookup_destructor (tree, tree, tree);
-static void warn_args_num (location_t, tree, bool);
 static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
                               tsubst_flags_t);
 
@@ -633,10 +632,10 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
 
       if (DERIVED_FROM_P (class1, class2))
        t2 = (build_pointer_type
-             (cp_build_qualified_type (class1, cp_type_quals (class2))));
+             (cp_build_qualified_type (class1, TYPE_QUALS (class2))));
       else if (DERIVED_FROM_P (class2, class1))
        t1 = (build_pointer_type
-             (cp_build_qualified_type (class2, cp_type_quals (class1))));
+             (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
       else
         {
           if (complain & tf_error)
@@ -810,7 +809,6 @@ merge_types (tree t1, tree t2)
        tree valtype = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
        tree p1 = TYPE_ARG_TYPES (t1);
        tree p2 = TYPE_ARG_TYPES (t2);
-       tree parms;
        tree rval, raises;
 
        /* Save space: see if the result is identical to one of the args.  */
@@ -822,25 +820,21 @@ merge_types (tree t1, tree t2)
        /* Simple way if one arg fails to specify argument types.  */
        if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
          {
-           parms = p2;
-           raises = TYPE_RAISES_EXCEPTIONS (t2);
+           rval = build_function_type (valtype, p2);
+           if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
+             rval = build_exception_variant (rval, raises);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
-       else if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
+       raises = TYPE_RAISES_EXCEPTIONS (t1);
+       if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
          {
-           parms = p1;
-           raises = TYPE_RAISES_EXCEPTIONS (t1);
-         }
-       else
-         {
-           parms = commonparms (p1, p2);
-           /* In cases where we're merging a real declaration with a
-              built-in declaration, t1 is the real one.  */
-           raises = TYPE_RAISES_EXCEPTIONS (t1);
+           rval = build_function_type (valtype, p1);
+           if (raises)
+             rval = build_exception_variant (rval, raises);
+           return cp_build_type_attribute_variant (rval, attributes);
          }
 
-       rval = build_function_type (valtype, parms);
-       gcc_assert (type_memfn_quals (t1) == type_memfn_quals (t2));
-       rval = apply_memfn_quals (rval, type_memfn_quals (t1));
+       rval = build_function_type (valtype, commonparms (p1, p2));
        t1 = build_exception_variant (rval, raises);
        break;
       }
@@ -1161,7 +1155,6 @@ static bool
 incompatible_dependent_types_p (tree t1, tree t2)
 {
   tree tparms1 = NULL_TREE, tparms2 = NULL_TREE;
-  bool t1_typedef_variant_p, t2_typedef_variant_p;
 
   if (!uses_template_parms (t1) || !uses_template_parms (t2))
     return false;
@@ -1174,22 +1167,10 @@ incompatible_dependent_types_p (tree t1, tree t2)
        return true;
     }
 
-  t1_typedef_variant_p = typedef_variant_p (t1);
-  t2_typedef_variant_p = typedef_variant_p (t2);
-
   /* Either T1 or T2 must be a typedef.  */
-  if (!t1_typedef_variant_p && !t2_typedef_variant_p)
+  if (!typedef_variant_p (t1) && !typedef_variant_p (t2))
     return false;
 
-  if (!t1_typedef_variant_p || !t2_typedef_variant_p)
-    /* Either T1 or T2 is not a typedef so we cannot compare the
-       the template parms of the typedefs of T1 and T2.
-       At this point, if the main variant type of T1 and T2 are equal
-       it means the two types can't be incompatible, from the perspective
-       of this function.  */
-    if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
-      return false;
-
   /* So if we reach this point, it means either T1 or T2 is a typedef variant.
      Let's compare their template parameters.  */
 
@@ -1250,20 +1231,11 @@ structural_comptypes (tree t1, tree t2, int strict)
   /* Qualifiers must match.  For array types, we will check when we
      recur on the array element types.  */
   if (TREE_CODE (t1) != ARRAY_TYPE
-      && cp_type_quals (t1) != cp_type_quals (t2))
-    return false;
-  if (TREE_CODE (t1) == FUNCTION_TYPE
-      && type_memfn_quals (t1) != type_memfn_quals (t2))
+      && TYPE_QUALS (t1) != TYPE_QUALS (t2))
     return false;
   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
     return false;
 
-  /* If T1 and T2 are dependent typedefs then check upfront that
-     the template parameters of their typedef DECLs match before
-     going down checking their subtypes.  */
-  if (incompatible_dependent_types_p (t1, t2))
-    return false;
-
   /* Allow for two different type nodes which have essentially the same
      definition.  Note that we already checked for equality of the type
      qualifiers (just above).  */
@@ -1272,6 +1244,11 @@ structural_comptypes (tree t1, tree t2, int strict)
       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return true;
 
+  /* If T1 and T2 are dependent typedefs then check upfront that
+     the template parameters of their typedef DECLs match before
+     going down checking their subtypes.  */
+  if (incompatible_dependent_types_p (t1, t2))
+    return false;
 
   /* Compare the types.  Break out if they could be the same.  */
   switch (TREE_CODE (t1))
@@ -1639,8 +1616,6 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
       && DECL_TEMPLATE_INSTANTIATION (e))
     instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
 
-  e = mark_type_use (e);
-
   if (TREE_CODE (e) == COMPONENT_REF
       && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
       && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
@@ -1696,8 +1671,6 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
       return e;
     }
 
-  e = mark_type_use (e);
-
   if (TREE_CODE (e) == VAR_DECL)
     t = size_int (DECL_ALIGN_UNIT (e));
   else if (TREE_CODE (e) == COMPONENT_REF
@@ -1847,9 +1820,7 @@ unlowered_expr_type (const_tree exp)
    in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
    function-to-pointer conversions.  In addition, manifest constants
    are replaced by their values, and bitfield references are converted
-   to their declared types. Note that this function does not perform the
-   lvalue-to-rvalue conversion for class types. If you need that conversion
-   to for class types, then you probably need to use force_rvalue.
+   to their declared types.
 
    Although the returned value is being used as an rvalue, this
    function does not wrap the returned expression in a
@@ -1866,8 +1837,6 @@ decay_conversion (tree exp)
   if (type == error_mark_node)
     return error_mark_node;
 
-  exp = mark_rvalue_use (exp);
-
   exp = resolve_nondeduced_context (exp);
   if (type_unknown_p (exp))
     {
@@ -1992,8 +1961,6 @@ perform_integral_promotions (tree expr)
   tree type;
   tree promoted_type;
 
-  expr = mark_rvalue_use (expr);
-
   /* [conv.prom]
 
      If the bitfield has an enumerated type, it is treated as any
@@ -2035,7 +2002,7 @@ string_conv_p (const_tree totype, const_tree exp, int warn)
   else
     {
       /* Is this a string constant which has decayed to 'const char *'?  */
-      t = build_pointer_type (cp_build_qualified_type (t, TYPE_QUAL_CONST));
+      t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
       if (!same_type_p (TREE_TYPE (exp), t))
        return 0;
       STRIP_NOPS (exp);
@@ -2868,15 +2835,13 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
    LOC is the location to use in building the array reference.  */
 
 tree
-cp_build_array_ref (location_t loc, tree array, tree idx,
-                   tsubst_flags_t complain)
+build_array_ref (location_t loc, tree array, tree idx)
 {
   tree ret;
 
   if (idx == 0)
     {
-      if (complain & tf_error)
-       error_at (loc, "subscript missing in array reference");
+      error_at (loc, "subscript missing in array reference");
       return error_mark_node;
     }
 
@@ -2890,8 +2855,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
     {
     case COMPOUND_EXPR:
       {
-       tree value = cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-                                        complain);
+       tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx);
        ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
                      TREE_OPERAND (array, 0), value);
        SET_EXPR_LOCATION (ret, loc);
@@ -2901,10 +2865,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
     case COND_EXPR:
       ret = build_conditional_expr
              (TREE_OPERAND (array, 0),
-              cp_build_array_ref (loc, TREE_OPERAND (array, 1), idx,
-                                  complain),
-              cp_build_array_ref (loc, TREE_OPERAND (array, 2), idx,
-                                  complain),
+              build_array_ref (loc, TREE_OPERAND (array, 1), idx),
+              build_array_ref (loc, TREE_OPERAND (array, 2), idx),
               tf_warning_or_error);
       protected_set_expr_location (ret, loc);
       return ret;
@@ -2921,8 +2883,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 
       if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
        {
-         if (complain & tf_error)
-           error_at (loc, "array subscript is not an integer");
+         error_at (loc, "array subscript is not an integer");
          return error_mark_node;
        }
 
@@ -2958,7 +2919,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
            return error_mark_node;
        }
 
-      if (!lvalue_p (array) && (complain & tf_error))
+      if (!lvalue_p (array))
        pedwarn (loc, OPT_pedantic, 
                 "ISO C++ forbids subscripting non-lvalue array");
 
@@ -2970,8 +2931,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
          tree foo = array;
          while (TREE_CODE (foo) == COMPONENT_REF)
            foo = TREE_OPERAND (foo, 0);
-         if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)
-             && (complain & tf_warning))
+         if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
            warning_at (loc, OPT_Wextra,
                        "subscripting array declared %<register%>");
        }
@@ -3008,14 +2968,12 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 
     if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE)
       {
-       if (complain & tf_error)
-         error_at (loc, "subscripted value is neither array nor pointer");
+       error_at (loc, "subscripted value is neither array nor pointer");
        return error_mark_node;
       }
     if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
       {
-       if (complain & tf_error)
-         error_at (loc, "array subscript is not an integer");
+       error_at (loc, "array subscript is not an integer");
        return error_mark_node;
       }
 
@@ -3023,21 +2981,13 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
 
     ret = cp_build_indirect_ref (cp_build_binary_op (input_location,
                                                     PLUS_EXPR, ar, ind,
-                                                    complain),
+                                                    tf_warning_or_error),
                                  RO_ARRAY_INDEXING,
-                                 complain);
+                                 tf_warning_or_error);
     protected_set_expr_location (ret, loc);
     return ret;
   }
 }
-
-/* Entry point for Obj-C++.  */
-
-tree
-build_array_ref (location_t loc, tree array, tree idx)
-{
-  return cp_build_array_ref (loc, array, idx, tf_warning_or_error);
-}
 \f
 /* Resolve a pointer to member function.  INSTANCE is the object
    instance to use, if the member points to a virtual member.
@@ -3322,44 +3272,6 @@ cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
   return ret;
 }
 \f
-/* Subroutine of convert_arguments.
-   Warn about wrong number of args are genereted. */
-
-static void
-warn_args_num (location_t loc, tree fndecl, bool too_many_p)
-{
-  if (fndecl)
-    {
-      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
-       {
-         if (DECL_NAME (fndecl) == NULL_TREE
-             || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
-           error_at (loc,
-                     too_many_p
-                     ? G_("too many arguments to constructor %q#D")
-                     : G_("too few arguments to constructor %q#D"),
-                     fndecl);
-         else
-           error_at (loc,
-                     too_many_p
-                     ? G_("too many arguments to member function %q#D")
-                     : G_("too few arguments to member function %q#D"),
-                     fndecl);
-       }
-      else
-       error_at (loc,
-                 too_many_p
-                 ? G_("too many arguments to function %q#D")
-                 : G_("too few arguments to function %q#D"),
-                 fndecl);
-      inform (DECL_SOURCE_LOCATION (fndecl),
-             "declared here");
-    }
-  else
-    error_at (loc, too_many_p ? G_("too many arguments to function")
-                             : G_("too few arguments to function"));
-}
-
 /* Convert the actual parameter expressions in the list VALUES to the
    types in the list TYPELIST.  The converted expressions are stored
    back in the VALUES vector.
@@ -3381,11 +3293,26 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
                   int flags, tsubst_flags_t complain)
 {
   tree typetail;
+  const char *called_thing = 0;
   unsigned int i;
 
   /* Argument passing is always copy-initialization.  */
   flags |= LOOKUP_ONLYCONVERTING;
 
+  if (fndecl)
+    {
+      if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
+       {
+         if (DECL_NAME (fndecl) == NULL_TREE
+             || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl)))
+           called_thing = "constructor";
+         else
+           called_thing = "member function";
+       }
+      else
+       called_thing = "function";
+    }
+
   for (i = 0, typetail = typelist;
        i < VEC_length (tree, *values);
        i++)
@@ -3400,7 +3327,15 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
        {
           if (complain & tf_error)
             {
-             warn_args_num (input_location, fndecl, /*too_many_p=*/true);
+              if (fndecl)
+                {
+                  error_at (input_location, "too many arguments to %s %q#D", 
+                           called_thing, fndecl);
+                 inform (DECL_SOURCE_LOCATION (fndecl),
+                         "declared here");
+                }
+              else
+                error ("too many arguments to function");
               return i;
             }
           else
@@ -3505,7 +3440,17 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
       else
        {
           if (complain & tf_error)
-           warn_args_num (input_location, fndecl, /*too_many_p=*/false);
+            {
+              if (fndecl)
+                {
+                  error_at (input_location, "too few arguments to %s %q#D", 
+                           called_thing, fndecl);
+                 inform (DECL_SOURCE_LOCATION (fndecl),
+                         "declared here");
+                }
+              else
+                error ("too few arguments to function");
+            }
          return -1;
        }
     }
@@ -4018,9 +3963,6 @@ cp_build_binary_op (location_t location,
            }
          result_type = type1;
        }
-      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
-       /* One of the operands must be of nullptr_t type.  */
-        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -4212,21 +4154,18 @@ cp_build_binary_op (location_t location,
        }
 
       build_type = boolean_type_node;
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == ENUMERAL_TYPE)
-          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-              || code1 == ENUMERAL_TYPE))
+      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
+          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (type0, type1, op0, op1,
                                              CPO_COMPARISON, complain);
-      else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
+      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
+              && integer_zerop (op1))
        result_type = type0;
-      else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
+      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
+              && integer_zerop (op0))
        result_type = type1;
-      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
-       /* One of the operands must be of nullptr_t type.  */
-        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -4846,8 +4785,6 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
       if (val != 0)
        return val;
 
-      arg = mark_lvalue_use (arg);
-
       /* Increment or decrement the real part of the value,
         and don't change the imaginary part.  */
       if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
@@ -4981,8 +4918,6 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 
       argtype = lvalue_type (arg);
 
-      arg = mark_lvalue_use (arg);
-
       if (TREE_CODE (arg) == OFFSET_REF)
        goto offset_ref;
 
@@ -6049,11 +5984,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
 
   /* [expr.reinterpret.cast]
      A pointer can be converted to any integral type large enough to
-     hold it. ... A value of type std::nullptr_t can be converted to
-     an integral type; the conversion has the same meaning and
-     validity as a conversion of (void*)0 to the integral type.  */
-  if (CP_INTEGRAL_TYPE_P (type)
-      && (TYPE_PTR_P (intype) || NULLPTR_TYPE_P (intype)))
+     hold it.  */
+  if (CP_INTEGRAL_TYPE_P (type) && TYPE_PTR_P (intype))
     {
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
@@ -6063,8 +5995,6 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
           else
             return error_mark_node;
         }
-      if (NULLPTR_TYPE_P (intype))
-        return build_int_cst (type, 0);
     }
   /* [expr.reinterpret.cast]
      A value of integral or enumeration type can be explicitly
@@ -6659,12 +6589,6 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
       if (BRACE_ENCLOSED_INITIALIZER_P (newrhs))
        {
-         if (modifycode != INIT_EXPR)
-           {
-             if (complain & tf_error)
-               error ("assigning to an array from an initializer list");
-             return error_mark_node;
-           }
          if (check_array_initializer (lhs, lhstype, newrhs))
            return error_mark_node;
          newrhs = digest_init (lhstype, newrhs);
@@ -7645,7 +7569,7 @@ check_return_expr (tree retval, bool *no_warning)
       if ((cxx_dialect != cxx98) 
           && named_return_value_okay_p
           /* The variable must not have the `volatile' qualifier.  */
-         && !CP_TYPE_VOLATILE_P (TREE_TYPE (retval))
+         && !(cp_type_quals (TREE_TYPE (retval)) & TYPE_QUAL_VOLATILE)
          /* The return type must be a class type.  */
          && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
        flags = flags | LOOKUP_PREFER_RVALUE;
@@ -7859,50 +7783,24 @@ comp_ptr_ttypes_const (tree to, tree from)
 int
 cp_type_quals (const_tree type)
 {
-  int quals;
   /* This CONST_CAST is okay because strip_array_types returns its
      argument unmodified and we assign it to a const_tree.  */
-  type = strip_array_types (CONST_CAST_TREE (type));
-  if (type == error_mark_node
-      /* Quals on a FUNCTION_TYPE are memfn quals.  */
-      || TREE_CODE (type) == FUNCTION_TYPE)
+  type = strip_array_types (CONST_CAST_TREE(type));
+  if (type == error_mark_node)
     return TYPE_UNQUALIFIED;
-  quals = TYPE_QUALS (type);
-  /* METHOD and REFERENCE_TYPEs should never have quals.  */
-  gcc_assert ((TREE_CODE (type) != METHOD_TYPE
-              && TREE_CODE (type) != REFERENCE_TYPE)
-             || ((quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE))
-                 == TYPE_UNQUALIFIED));
-  return quals;
+  return TYPE_QUALS (type);
 }
 
-/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
-   METHOD_TYPE.  */
+/* Returns nonzero if the TYPE is const from a C++ perspective: look inside
+   arrays.  */
 
-int
-type_memfn_quals (const_tree type)
-{
-  if (TREE_CODE (type) == FUNCTION_TYPE)
-    return TYPE_QUALS (type);
-  else if (TREE_CODE (type) == METHOD_TYPE)
-    return cp_type_quals (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))));
-  else
-    gcc_unreachable ();
-}
-
-/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
-   MEMFN_QUALS.  */
-
-tree
-apply_memfn_quals (tree type, cp_cv_quals memfn_quals)
+bool
+cp_type_readonly (const_tree type)
 {
-  /* Could handle METHOD_TYPE here if necessary.  */
-  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
-  if (TYPE_QUALS (type) == memfn_quals)
-    return type;
-  /* This should really have a different TYPE_MAIN_VARIANT, but that gets
-     complex.  */
-  return build_qualified_type (type, memfn_quals);
+  /* This CONST_CAST is okay because strip_array_types returns its
+     argument unmodified and we assign it to a const_tree.  */
+  type = strip_array_types (CONST_CAST_TREE(type));
+  return TYPE_READONLY (type);
 }
 
 /* Returns nonzero if TYPE is const or volatile.  */
@@ -7949,8 +7847,23 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
   if (TREE_CODE (decl) == TYPE_DECL)
     return;
 
-  gcc_assert (!(TREE_CODE (type) == FUNCTION_TYPE
-               && type_quals != TYPE_UNQUALIFIED));
+  if (TREE_CODE (type) == FUNCTION_TYPE
+      && type_quals != TYPE_UNQUALIFIED)
+    {
+      /* This was an error in C++98 (cv-qualifiers cannot be added to
+        a function type), but DR 295 makes the code well-formed by
+        dropping the extra qualifiers. */
+      if (pedantic)
+       {
+         tree bad_type = build_qualified_type (type, type_quals);
+         pedwarn (input_location, OPT_pedantic, 
+                  "ignoring %qV qualifiers added to function type %qT",
+                  bad_type, type);
+       }
+
+      TREE_TYPE (decl) = TYPE_MAIN_VARIANT (type);
+      return;
+    }
 
   /* Avoid setting TREE_READONLY incorrectly.  */
   if (/* If the object has a constructor, the constructor may modify
@@ -8107,4 +8020,3 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
 
   return win;
 }
-