cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2004 08:36:09 +0000 (08:36 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Dec 2004 08:36:09 +0000 (08:36 +0000)
PR c++/18803
* cp-tree.h (REFERENCE_REF_P): New.
(CPTI_TYPE_INFO_TYPE): Rename to ...
(CPTI_CONST_TYPE_INFO_TYPE): ... here.
(CPTI_TYPE_INFO_REF_TYPE): Remove.
(type_info_type_node): Rename to ...
(const_type_info_type_node): ... here.
(type_info_ref_type): Remove.
* call.c (build_user_type_conversion): Reformat.
(resolve_args): Do not convert_from_reference.
(build_object_call): Call convert_from_reference.
(prep_operand): Do not convert_from_reference.
(build_new_method_call): Likewise.
* class.c (build_vfield_ref): Likewise.
* cvt.c (convert_to_reference): Likewise.
(convert_from_reference): Build INDIRECT_REF here, not with
build_indirect_ref.
(convert_force): Do not convert_from_reference.
(build_expr_type_conversion): Likewise.
* decl.c (grok_reference_init): Likewise.
* decl2.c (delete_sanity): Likewise.
* except.c (initialize_handler_parm): Use POINTER_TYPE_P.
* init.c (build_dtor_call): Do not convert_from_reference.
* parser.c (cp_parser_template_argument): Unwrap indirected
reference. Allow TEMPLATE_PARM_INDEX as an object parm.
* pt.c (tsubst_copy_and_build) <case INDIRECT_REF>: Use
convert_from_reference, if indicated.
<case CALL_EXPR>: Do not convert_from_reference.
<case PARM_DECL, VAR_DECL>: Convert_from_reference if needed.
(tsubst_initializer_list): Do not convert_from_reference.
* rtti.c (init_rtti_processing): Adjust node creation.
(throw_bad_typeid): Use const_type_info_type_node.
Do not convert_from_reference.
(typeid_ok_p): Use const_type_info_type_node.
(build_typeid, get_typeid): Always return type_info typed node.
(build_dynamic_cast_1): Dont convert_from_reference. Refactor.
* semantics.c (finish_stmt_expr_expr): Do not
convert_from_reference.
(finish_id_expression): Convert_from_reference as appropriate.
* typeck.c (decay_conversion): Do not convert_from_reference.
(finish_class_member_access_expr): Likewise.
(build_indirect_ref): Use POINTER_TYPE_P.
(convert_arguments): Do not convert_from_reference.
(build_modify_expr): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (build_x_arrow): Likewise.
testsuite:
PR c++/18803
* g++.dg/template/operator5.C: New.

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

17 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/operator5.C [new file with mode: 0644]

index f129e11..c0da0a1 100644 (file)
@@ -1,3 +1,52 @@
+2004-12-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/18803
+       * cp-tree.h (REFERENCE_REF_P): New.
+       (CPTI_TYPE_INFO_TYPE): Rename to ...
+       (CPTI_CONST_TYPE_INFO_TYPE): ... here.
+       (CPTI_TYPE_INFO_REF_TYPE): Remove.
+       (type_info_type_node): Rename to ...
+       (const_type_info_type_node): ... here.
+       (type_info_ref_type): Remove.
+       * call.c (build_user_type_conversion): Reformat.
+       (resolve_args): Do not convert_from_reference.
+       (build_object_call): Call convert_from_reference.
+       (prep_operand): Do not convert_from_reference.
+       (build_new_method_call): Likewise.
+       * class.c (build_vfield_ref): Likewise.
+       * cvt.c (convert_to_reference): Likewise.
+       (convert_from_reference): Build INDIRECT_REF here, not with
+       build_indirect_ref.
+       (convert_force): Do not convert_from_reference.
+       (build_expr_type_conversion): Likewise.
+       * decl.c (grok_reference_init): Likewise.
+       * decl2.c (delete_sanity): Likewise.
+       * except.c (initialize_handler_parm): Use POINTER_TYPE_P.
+       * init.c (build_dtor_call): Do not convert_from_reference.
+       * parser.c (cp_parser_template_argument): Unwrap indirected
+       reference. Allow TEMPLATE_PARM_INDEX as an object parm.
+       * pt.c (tsubst_copy_and_build) <case INDIRECT_REF>: Use
+       convert_from_reference, if indicated.
+       <case CALL_EXPR>: Do not convert_from_reference.
+       <case PARM_DECL, VAR_DECL>: Convert_from_reference if needed.
+       (tsubst_initializer_list): Do not convert_from_reference.
+       * rtti.c (init_rtti_processing): Adjust node creation.
+       (throw_bad_typeid): Use const_type_info_type_node.
+       Do not convert_from_reference.
+       (typeid_ok_p): Use const_type_info_type_node.
+       (build_typeid, get_typeid): Always return type_info typed node.
+       (build_dynamic_cast_1): Dont convert_from_reference. Refactor.
+       * semantics.c (finish_stmt_expr_expr): Do not
+       convert_from_reference.
+       (finish_id_expression): Convert_from_reference as appropriate.
+       * typeck.c (decay_conversion): Do not convert_from_reference.
+       (finish_class_member_access_expr): Likewise.
+       (build_indirect_ref): Use POINTER_TYPE_P.
+       (convert_arguments): Do not convert_from_reference.
+       (build_modify_expr): Likewise.
+       (convert_for_initialization): Likewise.
+       * typeck2.c (build_x_arrow): Likewise.
+
 2004-12-07  Ziemowit Laski  <zlaski@apple.com>
 
        * cp-tree.h (struct lang_type_class): Rename 'objc_protocols'
index f8af887..ab31c99 100644 (file)
@@ -2650,7 +2650,8 @@ build_user_type_conversion (tree totype, tree expr, int flags)
     {
       if (cand->second_conv->kind == ck_ambig)
        return error_mark_node;
-      return convert_from_reference (convert_like (cand->second_conv, expr));
+      expr = convert_like (cand->second_conv, expr);
+      return convert_from_reference (expr);
     }
   return NULL_TREE;
 }
@@ -2672,8 +2673,6 @@ resolve_args (tree args)
          error ("invalid use of void expression");
          return error_mark_node;
        }
-      arg = convert_from_reference (arg);
-      TREE_VALUE (t) = arg;
     }
   return args;
 }
@@ -2979,6 +2978,7 @@ build_object_call (tree obj, tree args)
       else
        {
          obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1);
+         obj = convert_from_reference (obj);
          result = build_function_call (obj, args);
        }
     }
@@ -3475,7 +3475,6 @@ prep_operand (tree operand)
 {
   if (operand)
     {
-      operand = convert_from_reference (operand);
       if (CLASS_TYPE_P (TREE_TYPE (operand))
          && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
        /* Make sure the template type is instantiated now.  */
@@ -5198,8 +5197,6 @@ build_new_method_call (tree instance, tree fns, tree args,
   if (args == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
-    instance = convert_from_reference (instance);
   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
   instance_ptr = build_this (instance);
 
index 8a0da05..886d301 100644 (file)
@@ -492,9 +492,6 @@ build_vfield_ref (tree datum, tree type)
   if (datum == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
-    datum = convert_from_reference (datum);
-
   /* First, convert to the requested type.  */
   if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
     datum = convert_to_base (datum, type, /*check_access=*/false,
index 318b3b3..668aa68 100644 (file)
@@ -48,6 +48,7 @@ struct diagnostic_context;
       EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
       BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
       TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
+      REFERENCE_REF_P (in INDIRECT_EXPR)
    1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -483,9 +484,8 @@ enum cp_tree_index
     CPTI_VTBL_PTR_TYPE,
     CPTI_STD,
     CPTI_ABI,
-    CPTI_TYPE_INFO_TYPE,
+    CPTI_CONST_TYPE_INFO_TYPE,
     CPTI_TYPE_INFO_PTR_TYPE,
-    CPTI_TYPE_INFO_REF_TYPE,
     CPTI_ABORT_FNDECL,
     CPTI_GLOBAL_DELETE_FNDECL,
     CPTI_AGGR_TAG,
@@ -561,9 +561,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
 #define vtbl_ptr_type_node             cp_global_trees[CPTI_VTBL_PTR_TYPE]
 #define std_node                       cp_global_trees[CPTI_STD]
 #define abi_node                        cp_global_trees[CPTI_ABI]
-#define type_info_type_node            cp_global_trees[CPTI_TYPE_INFO_TYPE]
+#define const_type_info_type_node      cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
 #define type_info_ptr_type             cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
-#define type_info_ref_type              cp_global_trees[CPTI_TYPE_INFO_REF_TYPE]
 #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]
@@ -2224,6 +2223,10 @@ struct lang_decl GTY(())
   (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))     \
    ->u.f.u.saved_language_function)
 
+/* Indicates an indirect_expr is for converting a reference.  */
+#define REFERENCE_REF_P(NODE) \
+  TREE_LANG_FLAG_0 (INDIRECT_REF_CHECK (NODE))
+
 #define NEW_EXPR_USE_GLOBAL(NODE) \
   TREE_LANG_FLAG_0 (NEW_EXPR_CHECK (NODE))
 #define DELETE_EXPR_USE_GLOBAL(NODE) \
index f1968fd..7039bfe 100644 (file)
@@ -451,8 +451,6 @@ convert_to_reference (tree reftype, tree expr, int convtype,
     expr = instantiate_type (type, expr, 
                             (flags & LOOKUP_COMPLAIN)
                             ? tf_error | tf_warning : tf_none);
-  else
-    expr = convert_from_reference (expr);
 
   if (expr == error_mark_node)
     return error_mark_node;
@@ -553,7 +551,21 @@ tree
 convert_from_reference (tree val)
 {
   if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
-    return build_indirect_ref (val, NULL);
+    {
+      tree t = canonical_type_variant (TREE_TYPE (TREE_TYPE (val)));
+      tree ref = build1 (INDIRECT_REF, t, val);
+      
+       /* We *must* set TREE_READONLY when dereferencing a pointer to const,
+         so that we get the proper error message if the result is used
+         to assign to.  Also, &* is supposed to be a no-op.  */
+      TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
+      TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
+      TREE_SIDE_EFFECTS (ref)
+       = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (val));
+      REFERENCE_REF_P (ref) = 1;
+      val = ref;
+    }
+  
   return val;
 }
 
@@ -956,8 +968,6 @@ convert_force (tree type, tree expr, int convtype)
     return (fold_if_not_in_template 
            (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
                                   NULL_TREE)));
-  else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
-    e = convert_from_reference (e);
 
   if (code == POINTER_TYPE)
     return fold_if_not_in_template (convert_to_pointer_force (type, e));
@@ -1012,7 +1022,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
       && !(desires & WANT_NULL))
     warning ("converting NULL to non-pointer type");
     
-  expr = convert_from_reference (expr);
   basetype = TREE_TYPE (expr);
 
   if (basetype == error_mark_node)
index bf7b80f..22fcc7c 100644 (file)
@@ -3972,9 +3972,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
   if (TREE_CODE (init) == TREE_LIST)
     init = build_x_compound_expr_from_list (init, "initializer");
 
-  if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE)
-    init = convert_from_reference (init);
-
   if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
       && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
     /* Note: default conversion is only called in very special cases.  */
index 88fba4f..c7d28e5 100644 (file)
@@ -419,8 +419,6 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
       return t;
     }
 
-  exp = convert_from_reference (exp);
-
   /* An array can't have been allocated by new, so complain.  */
   if (TREE_CODE (exp) == VAR_DECL
       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
index 95da161..649fab7 100644 (file)
@@ -337,8 +337,7 @@ initialize_handler_parm (tree decl, tree exp)
      adjusted by value from __cxa_begin_catch.  Others are returned by 
      reference.  */
   init_type = TREE_TYPE (decl);
-  if (! TYPE_PTR_P (init_type)
-      && TREE_CODE (init_type) != REFERENCE_TYPE)
+  if (!POINTER_TYPE_P (init_type))
     init_type = build_reference_type (init_type);
 
   choose_personality_routine (decl_is_java_type (init_type, 0)
index 7dd15d2..95b57b2 100644 (file)
@@ -2675,8 +2675,6 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
     default:
       gcc_unreachable ();
     }
-
-  exp = convert_from_reference (exp);
   fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
   return build_new_method_call (exp, fn, 
                                /*args=*/NULL_TREE,
index 46b9385..dae68f3 100644 (file)
@@ -8813,6 +8813,7 @@ cp_parser_template_argument (cp_parser* parser)
       if (cp_parser_parse_definitely (parser))
        return argument;
     }
+
   /* If the next token is "&", the argument must be the address of an
      object or function with external linkage.  */
   address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
@@ -8835,6 +8836,12 @@ cp_parser_template_argument (cp_parser* parser)
        cp_parser_abort_tentative_parse (parser);
       else
        {
+         if (TREE_CODE (argument) == INDIRECT_REF)
+           {
+             gcc_assert (REFERENCE_REF_P (argument));
+             argument = TREE_OPERAND (argument, 0);
+           }
+         
          if (qualifying_class)
            argument = finish_qualified_id_expr (qualifying_class,
                                                 argument,
@@ -8858,6 +8865,8 @@ cp_parser_template_argument (cp_parser* parser)
                       || TREE_CODE (argument) == SCOPE_REF))
            /* A pointer-to-member.  */
            ;
+         else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
+           ;
          else
            cp_parser_simulate_error (parser);
 
@@ -8876,6 +8885,7 @@ cp_parser_template_argument (cp_parser* parser)
       cp_parser_error (parser, "invalid non-type template argument");
       return error_mark_node;
     }
+
   /* If the argument wasn't successfully parsed as a type-id followed
      by '>>', the argument can only be a constant expression now.
      Otherwise, we try parsing the constant-expression tentatively,
index 9bf396b..6e34ba6 100644 (file)
@@ -8390,7 +8390,18 @@ tsubst_copy_and_build (tree t,
       }
 
     case INDIRECT_REF:
-      return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *");
+      {
+       tree r = RECUR (TREE_OPERAND (t, 0));
+
+       if (REFERENCE_REF_P (t))
+         {
+           gcc_assert (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE);
+           r = convert_from_reference (r);
+         }
+       else
+         r = build_x_indirect_ref (r, "unary *");
+       return r;
+      }
 
     case NOP_EXPR:
       return build_nop
@@ -8626,8 +8637,6 @@ tsubst_copy_and_build (tree t,
        if (DECL_P (function))
          mark_used (function);
 
-       function = convert_from_reference (function);
-
        if (TREE_CODE (function) == OFFSET_REF)
          return build_offset_ref_call_from_tree (function, call_args);
        if (TREE_CODE (function) == COMPONENT_REF)
@@ -8815,13 +8824,21 @@ tsubst_copy_and_build (tree t,
        return build_typeid (operand_0);
       }
 
-    case PARM_DECL:
-      return convert_from_reference (tsubst_copy (t, args, complain, in_decl));
-
     case VAR_DECL:
-      if (args)
-       t = tsubst_copy (t, args, complain, in_decl);
-      return convert_from_reference (t);
+      if (!args)
+       return t;
+      /* Fall through */
+      
+    case PARM_DECL:
+      {
+       tree r = tsubst_copy (t, args, complain, in_decl);
+       
+       if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
+         /* If the original type was a reference, we'll be wrapped in
+            the appropriate INDIRECT_REF.  */
+         r = convert_from_reference (r);
+       return r;
+      }
 
     case VA_ARG_EXPR:
       return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)),
@@ -11560,7 +11577,6 @@ tsubst_initializer_list (tree t, tree argvec)
     {
       tree decl;
       tree init;
-      tree val;
 
       decl = tsubst_copy (TREE_PURPOSE (t), argvec, tf_error | tf_warning,
                          NULL_TREE);
@@ -11570,14 +11586,6 @@ tsubst_initializer_list (tree t, tree argvec)
       
       init = tsubst_expr (TREE_VALUE (t), argvec, tf_error | tf_warning,
                          NULL_TREE);
-      if (!init)
-       ;
-      else if (TREE_CODE (init) == TREE_LIST)
-       for (val = init; val; val = TREE_CHAIN (val))
-         TREE_VALUE (val) = convert_from_reference (TREE_VALUE (val));
-      else if (init != void_type_node)
-       init = convert_from_reference (init);
-
       in_base_initializer = 0;
 
       if (decl)
index cf66904..c113e1c 100644 (file)
@@ -108,17 +108,15 @@ static int doing_runtime = 0;
 void
 init_rtti_processing (void)
 {
-  tree const_type_info_type;
-
+  tree type_info_type;
+  
   push_namespace (std_identifier);
-  type_info_type_node 
-    = xref_tag (class_type, get_identifier ("type_info"),
-               /*tag_scope=*/ts_global, false);
+  type_info_type = xref_tag (class_type, get_identifier ("type_info"),
+                            /*tag_scope=*/ts_global, false);
   pop_namespace ();
-  const_type_info_type = build_qualified_type (type_info_type_node, 
-                                              TYPE_QUAL_CONST);
-  type_info_ptr_type = build_pointer_type (const_type_info_type);
-  type_info_ref_type = build_reference_type (const_type_info_type);
+  const_type_info_type_node
+    = build_qualified_type (type_info_type, TYPE_QUAL_CONST);
+  type_info_ptr_type = build_pointer_type (const_type_info_type_node);
 
   unemitted_tinfo_decls = VEC_alloc (tree, 124);
   
@@ -182,12 +180,14 @@ throw_bad_typeid (void)
   tree fn = get_identifier ("__cxa_bad_typeid");
   if (!get_global_value_if_present (fn, &fn))
     {
-      tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
-      t = build_function_type (build_reference_type (t), void_list_node);
+      tree t;
+
+      t = build_reference_type (const_type_info_type_node);
+      t = build_function_type (t, void_list_node);
       fn = push_throw_library_fn (fn, t);
     }
 
-  return convert_from_reference (build_cxx_call (fn, NULL_TREE));
+  return build_cxx_call (fn, NULL_TREE);
 }
 \f
 /* Return an lvalue expression whose type is "const std::type_info"
@@ -244,7 +244,7 @@ typeid_ok_p (void)
       return false;
     }
   
-  if (!COMPLETE_TYPE_P (type_info_type_node))
+  if (!COMPLETE_TYPE_P (const_type_info_type_node))
     {
       error ("must #include <typeinfo> before using typeid");
       return false;
@@ -266,7 +266,7 @@ build_typeid (tree exp)
     return error_mark_node;
 
   if (processing_template_decl)
-    return build_min (TYPEID_EXPR, type_info_ref_type, exp);
+    return build_min (TYPEID_EXPR, const_type_info_type_node, exp);
 
   if (TREE_CODE (exp) == INDIRECT_REF
       && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
@@ -390,7 +390,7 @@ get_typeid (tree type)
     return error_mark_node;
   
   if (processing_template_decl)
-    return build_min (TYPEID_EXPR, type_info_ref_type, type);
+    return build_min (TYPEID_EXPR, const_type_info_type_node, type);
 
   /* If the type of the type-id is a reference type, the result of the
      typeid expression refers to a type_info object representing the
@@ -441,6 +441,7 @@ build_dynamic_cast_1 (tree type, tree expr)
     case POINTER_TYPE:
       if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
        break;
+      /* Fall through.  */
     case REFERENCE_TYPE:
       if (! IS_AGGR_TYPE (TREE_TYPE (type)))
        {
@@ -460,18 +461,6 @@ build_dynamic_cast_1 (tree type, tree expr)
     }
 
   if (tc == POINTER_TYPE)
-    expr = convert_from_reference (expr);
-  else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
-    {
-      /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
-      exprtype = build_reference_type (exprtype);
-      expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
-                                  LOOKUP_NORMAL, NULL_TREE);
-    }
-
-  exprtype = TREE_TYPE (expr);
-
-  if (tc == POINTER_TYPE)
     {
       /* If T is a pointer type, v shall be an rvalue of a pointer to
         complete class type, and the result is an rvalue of type T.  */
@@ -494,6 +483,11 @@ build_dynamic_cast_1 (tree type, tree expr)
     }
   else
     {
+      /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
+      exprtype = build_reference_type (exprtype);
+      expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
+                                  LOOKUP_NORMAL, NULL_TREE);
+
       /* T is a reference type, v shall be an lvalue of a complete class
         type, and the result is an lvalue of the type referred to by T.  */
 
index 7f399b4..956bf04 100644 (file)
@@ -1505,7 +1505,6 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)
              || TREE_CODE (type) == FUNCTION_TYPE)
            expr = decay_conversion (expr);
 
-         expr = convert_from_reference (expr);
          expr = require_complete_type (expr);
 
          type = TREE_TYPE (expr);
@@ -2430,12 +2429,16 @@ finish_id_expression (tree id_expression,
   if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
       || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
     {
+      tree r;
+      
       *idk = CP_ID_KIND_NONE;
       if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
        decl = TEMPLATE_PARM_DECL (decl);
+      r = convert_from_reference (DECL_INITIAL (decl));
+      
       if (integral_constant_expression_p 
          && !dependent_type_p (TREE_TYPE (decl))
-         && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))) 
+         && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
        {
          if (!allow_non_integral_constant_expression_p)
            error ("template parameter %qD of type %qT is not allowed in "
@@ -2443,7 +2446,7 @@ finish_id_expression (tree id_expression,
                   "integral or enumeration type", decl, TREE_TYPE (decl));
          *non_integral_constant_expression_p = true;
        }
-      return DECL_INITIAL (decl);
+      return r;
     }
   /* Similarly, we resolve enumeration constants to their 
      underlying values.  */
@@ -2550,10 +2553,10 @@ finish_id_expression (tree id_expression,
              if (TYPE_P (scope) && dependent_type_p (scope))
                return build_nt (SCOPE_REF, scope, id_expression);
              else if (TYPE_P (scope) && DECL_P (decl))
-               return build2 (SCOPE_REF, TREE_TYPE (decl), scope,
-                              id_expression);
+               return convert_from_reference
+                 (build2 (SCOPE_REF, TREE_TYPE (decl), scope, id_expression));
              else
-               return decl;
+               return convert_from_reference (decl);
            }
          /* A TEMPLATE_ID already contains all the information we
             need.  */
@@ -2570,7 +2573,7 @@ finish_id_expression (tree id_expression,
             (or an instantiation thereof).  */
          if (TREE_CODE (decl) == VAR_DECL
              || TREE_CODE (decl) == PARM_DECL)
-           return decl;
+           return convert_from_reference (decl);
          /* The same is true for FIELD_DECL, but we also need to
             make sure that the syntax is correct.  */
          else if (TREE_CODE (decl) == FIELD_DECL)
@@ -2581,8 +2584,8 @@ finish_id_expression (tree id_expression,
        }
 
       /* Only certain kinds of names are allowed in constant
-       expression.  Enumerators and template parameters 
-       have already been handled above.  */
+         expression.  Enumerators and template parameters have already
+         been handled above.  */
       if (integral_constant_expression_p
          && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
        {
@@ -2630,10 +2633,15 @@ finish_id_expression (tree id_expression,
 
          if (TREE_CODE (decl) == FIELD_DECL || BASELINK_P (decl))
            *qualifying_class = scope;
-         else if (!processing_template_decl)
-           decl = convert_from_reference (decl);
-         else if (TYPE_P (scope))
-           decl = build2 (SCOPE_REF, TREE_TYPE (decl), scope, decl);
+         else
+           {
+             tree r = convert_from_reference (decl);
+             
+             if (processing_template_decl
+                 && TYPE_P (scope))
+               r = build2 (SCOPE_REF, TREE_TYPE (r), scope, decl);
+             decl = r;
+           }
        }
       else if (TREE_CODE (decl) == FIELD_DECL)
        decl = finish_non_static_data_member (decl, current_class_ref,
@@ -2686,8 +2694,7 @@ finish_id_expression (tree id_expression,
              perform_or_defer_access_check (TYPE_BINFO (path), decl);
            }
          
-         if (! processing_template_decl)
-           decl = convert_from_reference (decl);
+         decl = convert_from_reference (decl);
        }
       
       /* Resolve references to variables of anonymous unions
index 1bd12e7..a06101c 100644 (file)
@@ -1343,13 +1343,6 @@ decay_conversion (tree exp)
   type = TREE_TYPE (exp);
   code = TREE_CODE (type);
 
-  if (code == REFERENCE_TYPE)
-    {
-      exp = convert_from_reference (exp);
-      type = TREE_TYPE (exp);
-      code = TREE_CODE (type);
-    }
-
   if (type == error_mark_node)
     return error_mark_node;
 
@@ -1905,12 +1898,6 @@ finish_class_member_access_expr (tree object, tree name)
       object = build_non_dependent_expr (object);
     }
   
-  if (TREE_CODE (object_type) == REFERENCE_TYPE)
-    {
-      object = convert_from_reference (object);
-      object_type = TREE_TYPE (object);
-    }
-
   /* [expr.ref]
 
      The type of the first expression shall be "class object" (of a
@@ -2102,7 +2089,7 @@ build_indirect_ref (tree ptr, const char *errorstring)
             ? ptr : decay_conversion (ptr));
   type = TREE_TYPE (pointer);
 
-  if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
+  if (POINTER_TYPE_P (type))
     {
       /* [expr.unary.op]
         
@@ -2627,9 +2614,6 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
        }
       else
        {
-         if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
-           val = convert_from_reference (val);
-
          if (fndecl && DECL_BUILT_IN (fndecl)
              && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
            /* Don't do ellipsis conversion for __built_in_constant_p
@@ -5372,11 +5356,6 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
     }
   else
     {
-      if (TREE_CODE (lhstype) == REFERENCE_TYPE)
-       {
-         lhs = convert_from_reference (lhs);
-         olhstype = lhstype = TREE_TYPE (lhs);
-       }
       lhs = require_complete_type (lhs);
       if (lhs == error_mark_node)
        return error_mark_node;
@@ -6025,9 +6004,6 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
     return error_mark_node;
 
-  if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
-    rhs = convert_from_reference (rhs);
-
   if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
        && TREE_CODE (type) != ARRAY_TYPE
        && (TREE_CODE (type) != REFERENCE_TYPE
index ab95bc3..8d97e45 100644 (file)
@@ -1212,12 +1212,6 @@ build_x_arrow (tree expr)
       expr = build_non_dependent_expr (expr);
     }
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    {
-      expr = convert_from_reference (expr);
-      type = TREE_TYPE (expr);
-    }
-
   if (IS_AGGR_TYPE (type))
     {
       while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
index d67d208..eac55df 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/18803
+       * g++.dg/template/operator5.C: New.
+
 2004-12-08  Hans-Peter Nilsson  <hp@bitrange.com>
 
        PR c/18867
diff --git a/gcc/testsuite/g++.dg/template/operator5.C b/gcc/testsuite/g++.dg/template/operator5.C
new file mode 100644 (file)
index 0000000..1c0c292
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 7 Dec 2004 <nathan@codesourcery.com>
+
+// PR 18803: reject legal
+// Origin: Wolfgang Bangerth <bangerth@dealii.org>
+
+struct A { 
+  int operator() (); 
+}; 
+template <int> void foo () { 
+  A &a = *new A(); 
+  const int i = a(); 
+}