OSDN Git Service

Fix candidate for PR c++/43206
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 25 Mar 2010 22:08:33 +0000 (22:08 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 00:35:36 +0000 (09:35 +0900)
gcc/cp/ChangeLog:
PR c++/43206
* cp-tree.h (get_template_parms_at_level): Declare ...
* pt.c (get_template_parms_at_level): ... new function.
* typeck.c (get_template_parms_of_dependent_type): If a template
type parm's DECL_CONTEXT isn't yet set, get its siblings from
current_template_parms. Use get_template_parms_at_level. Remove
useless test.
(incompatible_dependent_types_p): If we get empty parms from just one
of the template type parms we are comparing then the template parms are
incompatible.

gcc/testsuite/ChangeLog:
PR c++/43206
* g++.dg/template/typedef30.C: New test case.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157730 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog

index 0aad33c..ff66a20 100644 (file)
@@ -1,3 +1,16 @@
+2010-03-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/43206
+       * cp-tree.h (get_template_parms_at_level): Declare ...
+       * pt.c (get_template_parms_at_level): ... new function.
+       * typeck.c (get_template_parms_of_dependent_type): If a template
+       type parm's DECL_CONTEXT isn't yet set, get its siblings from
+       current_template_parms. Use get_template_parms_at_level. Remove
+       useless test.
+       (incompatible_dependent_types_p): If we get empty parms from just one
+       of the template type parms we are comparing then the template parms are
+       incompatible.
+
 2010-03-24  Jason Merrill  <jason@redhat.com>
 
        PR c++/43502
index 3e1b310..5648827 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for C++ parsing and type checking.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hashtab.h"
 #include "splay-tree.h"
 #include "vec.h"
+#include "varray.h"
 #include "c-common.h"
 #include "name-lookup.h"
 
@@ -73,6 +74,7 @@ framework extensions, you must include this file before toplev.h, not after.
       BASELINK_QUALIFIED_P (in BASELINK)
       TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
       TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
+      TYPE_REF_IS_RVALUE (in REFERENCE_TYPE)
       ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
       CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
       LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
@@ -119,6 +121,7 @@ framework extensions, you must include this file before toplev.h, not after.
    3: TYPE_FOR_JAVA.
    4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR
    5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE)
+      SCOPED_ENUM_P (in ENUMERAL_TYPE)
    6: TYPE_DEPENDENT_P_VALID
 
    Usage of DECL_LANG_FLAG_?:
@@ -775,9 +778,6 @@ enum cp_tree_index
 
     CPTI_KEYED_CLASSES,
 
-    CPTI_NULLPTR,
-    CPTI_NULLPTR_TYPE,
-
     CPTI_MAX
 };
 
@@ -812,8 +812,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
 #define abort_fndecl                   cp_global_trees[CPTI_ABORT_FNDECL]
 #define global_delete_fndecl           cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
 #define current_aggr                   cp_global_trees[CPTI_AGGR_TAG]
-#define nullptr_node                   cp_global_trees[CPTI_NULLPTR]
-#define nullptr_type_node              cp_global_trees[CPTI_NULLPTR_TYPE]
 
 /* We cache these tree nodes so as to call get_identifier less
    frequently.  */
@@ -1741,12 +1739,6 @@ struct GTY(()) lang_type {
   (TYPE_RAISES_EXCEPTIONS (NODE) \
    && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE)
 
-/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept.  This is the
-   case for things declared noexcept(true) and, with -fnothrow-opt, for
-   throw() functions.  */
-#define TYPE_NOEXCEPT_P(NODE) \
-  (flag_nothrow_opt && TYPE_NOTHROW_P(NODE))
-
 /* The binding level associated with the namespace.  */
 #define NAMESPACE_LEVEL(NODE) \
   (LANG_DECL_NS_CHECK (NODE)->level)
@@ -1766,7 +1758,7 @@ struct GTY(()) lang_decl_base {
   unsigned threadprivate_or_deleted_p : 1; /* var or fn */
   unsigned anticipated_p : 1;             /* fn or type */
   unsigned friend_attr : 1;               /* fn or type */
-  unsigned template_conv_p : 1;                   /* var or template */
+  unsigned template_conv_p : 1;                   /* template only? */
   unsigned odr_used : 1;                  /* var or fn */
   unsigned u2sel : 1;
   /* 1 spare bit */
@@ -2096,15 +2088,6 @@ struct GTY(()) lang_decl {
 #define DECL_TEMPLATE_CONV_FN_P(NODE) \
   (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p)
 
-/* Nonzero if NODE, a static data member, was declared in its class as an
-   array of unknown bound.  */
-#define VAR_HAD_UNKNOWN_BOUND(NODE)                    \
-  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))          \
-   ? DECL_LANG_SPECIFIC (NODE)->u.base.template_conv_p \
-   : false)
-#define SET_VAR_HAD_UNKNOWN_BOUND(NODE) \
-  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.template_conv_p = true)
-
 /* Set the overloaded operator code for NODE to CODE.  */
 #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
   (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))
@@ -3010,16 +2993,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    || TREE_CODE (TYPE) == REAL_TYPE \
    || TREE_CODE (TYPE) == COMPLEX_TYPE)
 
-/* True iff TYPE is cv decltype(nullptr).  */
-#define NULLPTR_TYPE_P(TYPE)                           \
-  (TREE_CODE (TYPE) == LANG_TYPE                       \
-   && TYPE_MAIN_VARIANT (TYPE) == nullptr_type_node)
-
 /* [basic.types]
 
-   Arithmetic types, enumeration types, pointer types,
-   pointer-to-member types, and std::nullptr_t are collectively called
-   scalar types.
+   Arithmetic types, enumeration types, pointer types, and
+   pointer-to-member types, are collectively called scalar types.
    
    Keep these checks in ascending code order.  */
 #define SCALAR_TYPE_P(TYPE)                    \
@@ -3027,8 +3004,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    || TREE_CODE (TYPE) == ENUMERAL_TYPE                \
    || ARITHMETIC_TYPE_P (TYPE)                 \
    || TYPE_PTR_P (TYPE)                                \
-   || TYPE_PTRMEMFUNC_P (TYPE)                  \
-   || NULLPTR_TYPE_P (TYPE))
+   || TYPE_PTRMEMFUNC_P (TYPE))
 
 /* Determines whether this type is a C++0x scoped enumeration
    type. Scoped enumerations types are introduced via "enum class" or
@@ -3051,17 +3027,17 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
      - The underlying type of the enum is well-defined.  */
 #define SCOPED_ENUM_P(TYPE)                                             \
-  (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE))
+  (TREE_CODE (TYPE) == ENUMERAL_TYPE && TYPE_LANG_FLAG_5 (TYPE))
 
 /* Determine whether this is an unscoped enumeration type.  */
 #define UNSCOPED_ENUM_P(TYPE)                                           \
-  (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE))
+  (TREE_CODE (TYPE) == ENUMERAL_TYPE && !TYPE_LANG_FLAG_5 (TYPE))
 
 /* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped
    enumeration type (1) or a normal (unscoped) enumeration type
    (0).  */
 #define SET_SCOPED_ENUM_P(TYPE, VAL)                    \
-  (ENUM_IS_SCOPED (TYPE) = (VAL))
+  (TYPE_LANG_FLAG_5 (ENUMERAL_TYPE_CHECK (TYPE)) = (VAL))
 
 /* Returns the underlying type of the given enumeration type. The
    underlying type is determined in different ways, depending on the
@@ -3216,6 +3192,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define TYPE_REF_OBJ_P(NODE)                                   \
   (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE)))
 
+/* True if reference type NODE is an rvalue reference */
+#define TYPE_REF_IS_RVALUE(NODE) \
+  TREE_LANG_FLAG_0 (REFERENCE_TYPE_CHECK (NODE))
+
 /* Returns true if NODE is a pointer to an object, or a pointer to
    void.  Keep these checks in ascending tree code order.  */
 #define TYPE_PTROBV_P(NODE)                                    \
@@ -3357,6 +3337,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define ANON_UNION_TYPE_P(NODE) \
   (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE))
 
+#define UNKNOWN_TYPE LANG_TYPE
+
 /* Define fields and accessors for nodes representing declared names.  */
 
 #define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous)
@@ -4120,8 +4102,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
    have already generated a temporary, such as reference
    initialization and the catch parameter.  */
 #define DIRECT_BIND (1 << 4)
-/* We're performing a user-defined conversion, so more user-defined
-   conversions are not permitted (only built-in conversions).  */
+/* User-defined conversions are not permitted.  (Built-in conversions
+   are permitted.)  */
 #define LOOKUP_NO_CONVERSION (1 << 5)
 /* The user has explicitly called a destructor.  (Therefore, we do
    not need to check that the object is non-NULL before calling the
@@ -4148,8 +4130,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
 #define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1)
 /* This is the first parameter of a copy constructor.  */
 #define LOOKUP_COPY_PARM (LOOKUP_NO_COPY_CTOR_CONVERSION << 1)
-/* We only want to consider list constructors.  */
-#define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -4260,10 +4240,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
   (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE)))
 #define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \
   (TEMPLATE_PARM_PARAMETER_PACK (TEMPLATE_TYPE_PARM_INDEX (NODE)))
-/* The list of template parms that a given template parameter of type
-   TEMPLATE_TYPE_PARM belongs to.*/
-#define TEMPLATE_TYPE_PARM_SIBLING_PARMS(NODE) \
-  (TREE_CHECK ((NODE), TEMPLATE_TYPE_PARM))->type.maxval
 
 /* These constants can used as bit flags in the process of tree formatting.
 
@@ -4586,8 +4562,7 @@ extern void validate_conversion_obstack           (void);
 extern tree build_vfield_ref                   (tree, tree);
 extern tree build_base_path                    (enum tree_code, tree,
                                                 tree, int);
-extern tree convert_to_base                    (tree, tree, bool, bool,
-                                                tsubst_flags_t);
+extern tree convert_to_base                    (tree, tree, bool, bool);
 extern tree convert_to_base_statically         (tree, tree);
 extern tree build_vtbl_ref                     (tree, tree);
 extern tree build_vfn_ref                      (tree, tree);
@@ -4597,7 +4572,6 @@ extern void resort_type_method_vec                (void *, void *,
 extern bool add_method                         (tree, tree, tree);
 extern bool currently_open_class               (tree);
 extern tree currently_open_derived_class       (tree);
-extern tree current_nonlambda_class_type       (void);
 extern tree finish_struct                      (tree, tree);
 extern void finish_struct_1                    (tree);
 extern int resolves_to_fixed_type_p            (tree, int *);
@@ -4630,7 +4604,6 @@ extern void check_for_override                    (tree, tree);
 extern void push_class_stack                   (void);
 extern void pop_class_stack                    (void);
 extern bool type_has_user_nondefault_constructor (tree);
-extern tree in_class_defaulted_default_constructor (tree);
 extern bool user_provided_p                    (tree);
 extern bool type_has_user_provided_constructor  (tree);
 extern bool type_has_user_provided_default_constructor (tree);
@@ -4667,7 +4640,6 @@ extern tree pushdecl_top_level_and_finish (tree, tree);
 extern tree check_for_out_of_scope_variable    (tree);
 extern void print_other_binding_stack          (struct cp_binding_level *);
 extern tree maybe_push_decl                    (tree);
-extern tree current_decl_namespace             (void);
 
 /* decl.c */
 extern tree poplevel                           (int, int, int);
@@ -4751,7 +4723,6 @@ extern bool cp_missing_noreturn_ok_p              (tree);
 extern void initialize_artificial_var          (tree, tree);
 extern tree check_var_type                     (tree, tree);
 extern tree reshape_init (tree, tree);
-extern tree next_initializable_field (tree);
 
 extern bool defer_mark_used_calls;
 extern GTY(()) VEC(tree, gc) *deferred_mark_used_calls;
@@ -4833,10 +4804,6 @@ extern tree build_eh_type_type                   (tree);
 
 /* in expr.c */
 extern tree cplus_expand_constant              (tree);
-extern tree mark_rvalue_use                    (tree);
-extern tree mark_lvalue_use                    (tree);
-extern tree mark_type_use                      (tree);
-extern void mark_exp_read                      (tree);
 
 /* friend.c */
 extern int is_friend                           (tree, tree);
@@ -4870,7 +4837,6 @@ extern tree create_temporary_var          (tree);
 extern void initialize_vtbl_ptrs               (tree);
 extern tree build_java_class_ref               (tree);
 extern tree integral_constant_value            (tree);
-extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool);
 
 /* in lex.c */
 extern void cxx_dup_lang_specific_decl         (tree);
@@ -5004,11 +4970,10 @@ extern void pop_tinst_level                     (void);
 extern struct tinst_level *outermost_tinst_level(void);
 extern bool parameter_of_template_p            (tree, tree);
 extern void init_template_processing           (void);
-extern void print_template_statistics          (void);
 bool template_template_parameter_p             (const_tree);
 extern bool primary_template_instantiation_p    (const_tree);
 extern tree get_primary_template_innermost_parameters  (const_tree);
-extern tree get_template_parms_at_level (tree, int);
+extern tree get_template_parms_at_level (tree, unsigned);
 extern tree get_template_innermost_arguments   (const_tree);
 extern tree get_template_argument_pack_elems   (const_tree);
 extern tree get_function_template_decl         (const_tree);
@@ -5234,7 +5199,6 @@ extern tree add_capture                         (tree, tree, tree, bool, bool);
 extern tree add_default_capture                 (tree, tree, tree);
 extern void register_capture_members           (tree);
 extern tree lambda_expr_this_capture            (tree);
-extern tree nonlambda_method_basetype          (void);
 extern void maybe_add_lambda_conv_op            (tree);
 
 /* in tree.c */
@@ -5280,7 +5244,6 @@ extern tree hash_tree_cons                        (tree, tree, tree);
 extern tree hash_tree_chain                    (tree, tree);
 extern tree build_qualified_name               (tree, tree, tree, bool);
 extern int is_overloaded_fn                    (tree);
-extern tree get_fns                            (tree);
 extern tree get_first_fn                       (tree);
 extern tree ovl_cons                           (tree, tree);
 extern tree build_overload                     (tree, tree);
@@ -5372,8 +5335,6 @@ extern tree build_x_indirect_ref          (tree, ref_operator,
 extern tree cp_build_indirect_ref              (tree, ref_operator,
                                                  tsubst_flags_t);
 extern tree build_array_ref                    (location_t, tree, tree);
-extern tree cp_build_array_ref                 (location_t, tree, tree,
-                                                tsubst_flags_t);
 extern tree get_member_function_from_ptrfunc   (tree *, tree);
 extern tree cp_build_function_call              (tree, tree, tsubst_flags_t);
 extern tree cp_build_function_call_vec         (tree, VEC(tree,gc) **,
@@ -5413,8 +5374,7 @@ extern bool error_type_p                  (const_tree);
 extern int ptr_reasonably_similar              (const_tree, const_tree);
 extern tree build_ptrmemfunc                   (tree, tree, int, bool);
 extern int cp_type_quals                       (const_tree);
-extern int type_memfn_quals                    (const_tree);
-extern tree apply_memfn_quals                  (tree, cp_cv_quals);
+extern bool cp_type_readonly                   (const_tree);
 extern bool cp_has_mutable_p                   (const_tree);
 extern bool at_least_as_qualified_p            (const_tree, const_tree);
 extern void cp_apply_type_quals_to_decl                (int, tree);
@@ -5426,7 +5386,6 @@ extern tree composite_pointer_type                (tree, tree, tree, tree,
                                                 composite_pointer_operation, 
                                                 tsubst_flags_t);
 extern tree merge_types                                (tree, tree);
-extern tree strip_array_domain                 (tree);
 extern tree check_return_expr                  (tree, bool *);
 extern tree cp_build_binary_op                  (location_t,
                                                 enum tree_code, tree, tree,
index 85bf1fd..59fdc44 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
@@ -493,9 +493,6 @@ add_to_template_args (tree args, tree extra_args)
   int i;
   int j;
 
-  if (args == NULL_TREE)
-    return extra_args;
-
   extra_depth = TMPL_ARGS_DEPTH (extra_args);
   new_args = make_tree_vec (TMPL_ARGS_DEPTH (args) + extra_depth);
 
@@ -1563,12 +1560,6 @@ iterative_hash_template_arg (tree arg, hashval_t val)
       val = iterative_hash_template_arg (TREE_TYPE (arg), val);
       return iterative_hash_template_arg (TYPE_DOMAIN (arg), val);
 
-    case LAMBDA_EXPR:
-      /* A lambda can't appear in a template arg, but don't crash on
-        erroneous input.  */
-      gcc_assert (errorcount > 0);
-      return val;
-
     default:
       switch (tclass)
        {
@@ -2852,7 +2843,7 @@ get_primary_template_innermost_parameters (const_tree t)
    of template parameters PARMS.  */
 
 tree
-get_template_parms_at_level (tree parms, int level)
+get_template_parms_at_level (tree parms, unsigned level)
 {
   tree p;
   if (!parms
@@ -3577,9 +3568,6 @@ end_template_parm_list (tree parms)
       next = TREE_CHAIN (parm);
       TREE_VEC_ELT (saved_parmlist, nparms) = parm;
       TREE_CHAIN (parm) = NULL_TREE;
-      if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
-       TEMPLATE_TYPE_PARM_SIBLING_PARMS (TREE_TYPE (TREE_VALUE (parm))) =
-             current_template_parms;
     }
 
   --processing_template_parmlist;
@@ -3726,17 +3714,15 @@ maybe_update_decl_type (tree orig_type, tree scope)
         TYPENAME_TYPEs and SCOPE_REFs that were previously dependent.  */
       tree args = current_template_args ();
       tree auto_node = type_uses_auto (type);
-      tree pushed;
       if (auto_node)
        {
          tree auto_vec = make_tree_vec (1);
          TREE_VEC_ELT (auto_vec, 0) = auto_node;
          args = add_to_template_args (args, auto_vec);
        }
-      pushed = push_scope (scope);
+      push_scope (scope);
       type = tsubst (type, args, tf_warning_or_error, NULL_TREE);
-      if (pushed)
-       pop_scope (scope);
+      pop_scope (scope);
     }
 
   if (type == error_mark_node)
@@ -3837,7 +3823,7 @@ process_partial_specialization (tree decl)
   int nargs = TREE_VEC_LENGTH (inner_args);
   int ntparms;
   int  i;
-  bool did_error_intro = false;
+  int did_error_intro = 0;
   struct template_parm_data tpd;
   struct template_parm_data tpd2;
 
@@ -3899,15 +3885,12 @@ process_partial_specialization (tree decl)
        if (!did_error_intro)
          {
            error ("template parameters not used in partial specialization:");
-           did_error_intro = true;
+           did_error_intro = 1;
          }
 
        error ("        %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i)));
       }
 
-  if (did_error_intro)
-    return error_mark_node;
-
   /* [temp.class.spec]
 
      The argument list of the specialization shall not be identical to
@@ -4562,9 +4545,6 @@ push_template_decl_real (tree decl, bool is_friend)
 
            if (current == decl)
              current = ctx;
-           else if (current == NULL_TREE)
-             /* Can happen in erroneous input.  */
-             break;
            else
              current = (TYPE_P (current)
                         ? TYPE_CONTEXT (current)
@@ -4636,6 +4616,9 @@ template arguments to %qD do not match original template %qD",
          tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
          if (TREE_CODE (parm) == TEMPLATE_DECL)
            DECL_CONTEXT (parm) = tmpl;
+
+         if (TREE_CODE (TREE_TYPE (parm)) == TEMPLATE_TYPE_PARM)
+           DECL_CONTEXT (TYPE_NAME (TREE_TYPE (parm))) = tmpl;
        }
     }
 
@@ -4933,7 +4916,6 @@ convert_nontype_argument (tree type, tree expr)
   if (error_operand_p (expr))
     return error_mark_node;
   expr_type = TREE_TYPE (expr);
-  expr = mark_rvalue_use (expr);
 
   /* HACK: Due to double coercion, we can get a
      NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
@@ -7340,18 +7322,11 @@ tsubst_friend_function (tree decl, tree args)
              DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
 
              if (TREE_CODE (old_decl) != TEMPLATE_DECL)
-               {
-                 /* We should have called reregister_specialization in
-                    duplicate_decls.  */
-                 gcc_assert (retrieve_specialization (new_template,
-                                                      new_args, 0)
-                             == old_decl);
-
-                 /* Instantiate it if the global has already been used.  */
-                 if (DECL_ODR_USED (old_decl))
-                   instantiate_decl (old_decl, /*defer_ok=*/true,
-                                     /*expl_inst_class_mem_p=*/false);
-               }
+               /* We should have called reregister_specialization in
+                  duplicate_decls.  */
+               gcc_assert (retrieve_specialization (new_template,
+                                                    new_args, 0)
+                           == old_decl);
              else
                {
                  tree t;
@@ -8760,7 +8735,7 @@ tsubst_aggr_type (tree t,
            {
              r = lookup_template_class (t, argvec, in_decl, context,
                                         entering_scope, complain);
-             r = cp_build_qualified_type_real (r, cp_type_quals (t), complain);
+             r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
            }
 
          cp_unevaluated_operand = saved_unevaluated_operand;
@@ -9037,8 +9012,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
               specialize R.  */
            gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
            argvec = tsubst_template_args (DECL_TI_ARGS
-                                          (DECL_TEMPLATE_RESULT
-                                                 (DECL_TI_TEMPLATE (t))),
+                                          (DECL_TEMPLATE_RESULT (gen_tmpl)),
                                           args, complain, in_decl);
 
            /* Check to see if we already have this specialization.  */
@@ -9506,8 +9480,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              type = DECL_ORIGINAL_TYPE (t);
            else
              type = TREE_TYPE (t);
-           if (TREE_CODE (t) == VAR_DECL && VAR_HAD_UNKNOWN_BOUND (t))
-             type = strip_array_domain (type);
            type = tsubst (type, args, complain, in_decl);
          }
        if (TREE_CODE (r) == VAR_DECL)
@@ -9791,10 +9763,7 @@ tsubst_function_type (tree t,
 
   /* Construct a new type node and return it.  */
   if (TREE_CODE (t) == FUNCTION_TYPE)
-    {
-      fntype = build_function_type (return_type, arg_types);
-      fntype = apply_memfn_quals (fntype, type_memfn_quals (t));
-    }
+    fntype = build_function_type (return_type, arg_types);
   else
     {
       tree r = TREE_TYPE (TREE_VALUE (arg_types));
@@ -9816,6 +9785,7 @@ tsubst_function_type (tree t,
       fntype = build_method_type_directly (r, return_type,
                                           TREE_CHAIN (arg_types));
     }
+  fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
   fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
 
   return fntype;
@@ -10113,7 +10083,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                int quals;
                gcc_assert (TYPE_P (arg));
 
-               quals = cp_type_quals (arg) | cp_type_quals (t);
+               /* cv-quals from the template are discarded when
+                  substituting in a function or reference type.  */
+               if (TREE_CODE (arg) == FUNCTION_TYPE
+                   || TREE_CODE (arg) == METHOD_TYPE
+                   || TREE_CODE (arg) == REFERENCE_TYPE)
+                 quals = cp_type_quals (arg);
+               else
+                 quals = cp_type_quals (arg) | cp_type_quals (t);
                  
                return cp_build_qualified_type_real
                  (arg, quals, complain | tf_ignore_bad_quals);
@@ -10141,11 +10118,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                                            /*entering_scope=*/0,
                                           complain);
                return cp_build_qualified_type_real
-                 (r, cp_type_quals (t), complain);
+                 (r, TYPE_QUALS (t), complain);
              }
            else
              /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
-             return unshare_expr (arg);
+             return arg;
          }
 
        if (level == 1)
@@ -10331,7 +10308,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
               TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
        else
          r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
-       r = cp_build_qualified_type_real (r, cp_type_quals (t), complain);
+       r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
 
        if (r != error_mark_node)
          /* Will this ever be needed for TYPE_..._TO values?  */
@@ -10373,14 +10350,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
            /* The type of the implicit object parameter gets its
               cv-qualifiers from the FUNCTION_TYPE. */
            tree memptr;
-           tree method_type = build_memfn_type (type, r, type_memfn_quals (type));
+           tree method_type = build_memfn_type (type, r, cp_type_quals (type));
            memptr = build_ptrmemfunc_type (build_pointer_type (method_type));
            return cp_build_qualified_type_real (memptr, cp_type_quals (t),
                                                 complain);
          }
        else
          return cp_build_qualified_type_real (build_ptrmem_type (r, type),
-                                              cp_type_quals (t),
+                                              TYPE_QUALS (t),
                                               complain);
       }
     case FUNCTION_TYPE:
@@ -14099,9 +14076,9 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
     {
       /*  Although a CVR qualifier is ignored when being applied to a
          substituted template parameter ([8.3.2]/1 for example), that
-         does not allow us to unify "const T" with "int&" because both
-         types are not of the form "cv-list T" [14.8.2.5 temp.deduct.type].
-         It is ok when we're allowing additional CV qualifiers
+         does not apply during deduction [14.8.2.4]/1, (even though
+         that is not explicitly mentioned, [14.8.2.4]/9 indicates
+         this).  Except when we're allowing additional CV qualifiers
          at the outer level [14.8.2.1]/3,1st bullet.  */
       if ((TREE_CODE (arg) == REFERENCE_TYPE
           || TREE_CODE (arg) == FUNCTION_TYPE
@@ -14467,10 +14444,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
        {
          int elt_strict = strict;
-
-         if (elt == error_mark_node)
-           return 1;
-
          if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
            {
              tree type = TREE_TYPE (elt);
@@ -15037,6 +15010,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
        {
          tree method_type;
          tree fntype;
+         cp_cv_quals cv_quals;
 
          /* Check top-level cv qualifiers */
          if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
@@ -15055,7 +15029,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
          /* Extract the cv-qualifiers of the member function from the
             implicit object parameter and place them on the function
             type to be restored later. */
-         fntype = apply_memfn_quals (fntype, type_memfn_quals (method_type));
+         cv_quals =
+           cp_type_quals(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (method_type))));
+         fntype = build_qualified_type (fntype, cv_quals);
          return unify (tparms, targs, TREE_TYPE (parm), fntype, strict);
        }
 
@@ -15079,13 +15055,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
       /* Matched cases are handled by the ARG == PARM test above.  */
       return 1;
 
-    case VAR_DECL:
-      /* A non-type template parameter that is a variable should be a
-        an integral constant, in which case, it whould have been
-        folded into its (constant) value. So we should not be getting
-        a variable here.  */
-      gcc_unreachable ();
-
     case TYPE_ARGUMENT_PACK:
     case NONTYPE_ARGUMENT_PACK:
       {
@@ -15495,10 +15464,13 @@ more_specialized_fn (tree pat1, tree pat2, int len)
         than the type from the parameter template (as described above)
         that type is considered to be more specialized than the other. If
         neither type is more cv-qualified than the other then neither type
-        is more specialized than the other."  */
+        is more specialized than the other."
 
+         We check same_type_p explicitly because deduction can also succeed
+         in both directions when there is a nondeduced context.  */
       if (deduce1 && deduce2
-         && quals1 != quals2 && quals1 >= 0 && quals2 >= 0)
+         && quals1 != quals2 && quals1 >= 0 && quals2 >= 0
+         && same_type_p (arg1, arg2))
        {
          if ((quals1 & quals2) == quals2)
            lose2 = true;
@@ -15941,13 +15913,12 @@ most_specialized_class (tree type, tree tmpl)
       tree parms = TREE_VALUE (t);
 
       partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
-
-      ++processing_template_decl;
-
       if (outer_args)
        {
          int i;
 
+         ++processing_template_decl;
+
          /* Discard the outer levels of args, and then substitute in the
             template args from the enclosing class.  */
          partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
@@ -15964,21 +15935,8 @@ most_specialized_class (tree type, tree tmpl)
            TREE_VEC_ELT (parms, i) =
              tsubst (TREE_VEC_ELT (parms, i), outer_args, tf_none, NULL_TREE);
 
+         --processing_template_decl;
        }
-
-      partial_spec_args =
-         coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
-                                add_to_template_args (outer_args,
-                                                      partial_spec_args),
-                                tmpl, tf_none,
-                                /*require_all_args=*/true,
-                                /*use_default_args=*/true);
-
-      --processing_template_decl;
-
-      if (partial_spec_args == error_mark_node)
-       return error_mark_node;
-
       spec_args = get_class_bindings (parms,
                                      partial_spec_args,
                                      args);
@@ -16466,15 +16424,10 @@ regenerate_decl_from_template (tree decl, tree tmpl)
        DECL_DECLARED_INLINE_P (decl) = 1;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
-    {
-      DECL_INITIAL (decl) =
-       tsubst_expr (DECL_INITIAL (code_pattern), args,
-                    tf_error, DECL_TI_TEMPLATE (decl),
-                    /*integral_constant_expression_p=*/false);
-      if (VAR_HAD_UNKNOWN_BOUND (decl))
-       TREE_TYPE (decl) = tsubst (TREE_TYPE (code_pattern), args,
-                                  tf_error, DECL_TI_TEMPLATE (decl));
-    }
+    DECL_INITIAL (decl) =
+      tsubst_expr (DECL_INITIAL (code_pattern), args,
+                  tf_error, DECL_TI_TEMPLATE (decl),
+                  /*integral_constant_expression_p=*/false);
   else
     gcc_unreachable ();
 
@@ -17745,15 +17698,6 @@ type_dependent_expression_p (tree expression)
       return false;
     }
 
-  /* A static data member of the current instantiation with incomplete
-     array type is type-dependent, as the definition and specializations
-     can have different bounds.  */
-  if (TREE_CODE (expression) == VAR_DECL
-      && DECL_CLASS_SCOPE_P (expression)
-      && dependent_type_p (DECL_CONTEXT (expression))
-      && VAR_HAD_UNKNOWN_BOUND (expression))
-    return true;
-
   if (TREE_TYPE (expression) == unknown_type_node)
     {
       if (TREE_CODE (expression) == ADDR_EXPR)
@@ -18585,19 +18529,4 @@ init_template_processing (void)
                                          ggc_free);
 }
 
-/* Print stats about the template hash tables for -fstats.  */
-
-void
-print_template_statistics (void)
-{
-  fprintf (stderr, "decl_specializations: size %ld, %ld elements, "
-          "%f collisions\n", (long) htab_size (decl_specializations),
-          (long) htab_elements (decl_specializations),
-          htab_collisions (decl_specializations));
-  fprintf (stderr, "type_specializations: size %ld, %ld elements, "
-          "%f collisions\n", (long) htab_size (type_specializations),
-          (long) htab_elements (type_specializations),
-          htab_collisions (type_specializations));
-}
-
 #include "gt-cp-pt.h"
index 54ccbfe..a4c64ea 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;
       }
@@ -884,19 +878,6 @@ merge_types (tree t1, tree t2)
     return cp_build_type_attribute_variant (t1, attributes);
 }
 
-/* Return the ARRAY_TYPE type without its domain.  */
-
-tree
-strip_array_domain (tree type)
-{
-  tree t2;
-  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
-  if (TYPE_DOMAIN (type) == NULL_TREE)
-    return type;
-  t2 = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
-  return cp_build_type_attribute_variant (t2, TYPE_ATTRIBUTES (type));
-}
-
 /* Wrapper around cp_common_type that is used by c-common.c and other
    front end optimizations that remove promotions.  
 
@@ -1129,22 +1110,36 @@ get_template_parms_of_dependent_type (tree t)
      template info from T itself.  */
   if ((tinfo = get_template_info (t)))
     ;
-  else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-    return TEMPLATE_TYPE_PARM_SIBLING_PARMS (t);
+  /* If T1 is a typedef or whatever has a template info associated
+     to its context, get the template parameters from that context.  */
   else if (typedef_variant_p (t)
           && !NAMESPACE_SCOPE_P (TYPE_NAME (t)))
     tinfo = get_template_info (DECL_CONTEXT (TYPE_NAME (t)));
-  /* If T is a TYPENAME_TYPE which context is a template type
-     parameter, get the template parameters from that context.  */
-  else if (TYPE_CONTEXT (t)
-          && TREE_CODE (TYPE_CONTEXT (t)) == TEMPLATE_TYPE_PARM)
-   return TEMPLATE_TYPE_PARM_SIBLING_PARMS (TYPE_CONTEXT (t));
+  else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
+          && DECL_CONTEXT (TYPE_NAME (t)) == NULL_TREE)
+    /* We have not yet created the DECL_TEMPLATE this
+       template type parm belongs to. It probably means
+       that we are in the middle of parsing the template parameters
+       of a template, and T is one of the parameters we have parsed.
+       Let's return the list of template parms we have parsed so far.  */
+    return get_template_parms_at_level (current_template_parms,
+                                       TEMPLATE_TYPE_LEVEL (t));
   else if (TYPE_CONTEXT (t)
           && !NAMESPACE_SCOPE_P (t))
     tinfo = get_template_info (TYPE_CONTEXT (t));
 
   if (tinfo)
     tparms = DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo));
+  /* If T is a template type parameter, get the template parameter
+     set it is part of.  */
+  else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
+          && DECL_CONTEXT (TYPE_NAME (t)))
+    tparms = DECL_TEMPLATE_PARMS (DECL_CONTEXT (TYPE_NAME (t)));
+  /* If T is a TYPENAME_TYPE which context is a template type
+     parameter, get the template parameters from that context.  */
+  else if (TYPE_CONTEXT (t)
+          && TREE_CODE (TYPE_CONTEXT (t)) == TEMPLATE_TYPE_PARM)
+    tparms = get_template_parms_of_dependent_type (TYPE_CONTEXT (t));
 
   return tparms;
 }
@@ -1161,7 +1156,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 +1168,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 +1232,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 +1245,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))
@@ -1632,15 +1610,6 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
       return e;
     }
 
-  /* To get the size of a static data member declared as an array of
-     unknown bound, we need to instantiate it.  */
-  if (TREE_CODE (e) == VAR_DECL
-      && VAR_HAD_UNKNOWN_BOUND (e)
-      && 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 +1665,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 +1814,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 +1831,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 +1955,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 +1996,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 +2829,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 +2849,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 +2859,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 +2877,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 +2913,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 +2925,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 +2962,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 +2975,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 +3266,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 +3287,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 +3321,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 +3434,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 +3957,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 +4148,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 +4779,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 +4912,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 +5978,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 +5989,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
@@ -6359,15 +6283,6 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
       return error_mark_node;
     }
 
-  if (TREE_CODE (type) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-      /* Casting to an integer of smaller size is an error detected elsewhere.  */
-      && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
-      /* Don't warn about converting any constant.  */
-      && !TREE_CONSTANT (value))
-    warning_at (input_location, OPT_Wint_to_pointer_cast, 
-               "cast to pointer from integer of different size");
-
   /* A C-style cast can be a const_cast.  */
   result = build_const_cast_1 (type, value, /*complain=*/false,
                               &valid_p);
@@ -6659,12 +6574,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 +7554,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 +7768,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;
-}
-
-/* Returns the function-cv-quals for TYPE, which must be a FUNCTION_TYPE or
-   METHOD_TYPE.  */
-
-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 ();
+  return TYPE_QUALS (type);
 }
 
-/* Returns the FUNCTION_TYPE TYPE with its function-cv-quals changed to
-   MEMFN_QUALS.  */
+/* Returns nonzero if the TYPE is const from a C++ perspective: look inside
+   arrays.  */
 
-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 +7832,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 +8005,3 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsubst_flags_t complain)
 
   return win;
 }
-
index 93083bf..8c7bc15 100644 (file)
@@ -1,3 +1,8 @@
+2010-03-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/43206
+       * g++.dg/template/typedef30.C: New test case.
+
 2010-03-25  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/43385