From: nathan Date: Wed, 8 Dec 2004 08:36:09 +0000 (+0000) Subject: cp: X-Git-Tag: upstream/4.9.2~65247 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=729f89ff588de32a6f6c4c928cb1d4115ae2fb2e;p=platform%2Fupstream%2Flinaro-gcc.git cp: 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) : Use convert_from_reference, if indicated. : Do not convert_from_reference. : 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f129e11..c0da0a1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,52 @@ +2004-12-08 Nathan Sidwell + + 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) : Use + convert_from_reference, if indicated. + : Do not convert_from_reference. + : 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 * cp-tree.h (struct lang_type_class): Rename 'objc_protocols' diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f8af887..ab31c99 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 8a0da05..886d301 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 318b3b3..668aa68 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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) \ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index f1968fd..7039bfe 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index bf7b80f..22fcc7c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 88fba4f..c7d28e5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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) diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 95da161..649fab7 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -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) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 7dd15d2..95b57b2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 46b9385..dae68f3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9bf396b..6e34ba6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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) diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index cf66904..c113e1c 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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); } /* 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 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. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7f399b4..956bf04 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1bd12e7..a06101c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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 diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index ab95bc3..8d97e45 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d67d208..eac55df 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-08 Nathan Sidwell + + PR c++/18803 + * g++.dg/template/operator5.C: New. + 2004-12-08 Hans-Peter Nilsson 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 index 0000000..1c0c292 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/operator5.C @@ -0,0 +1,14 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Dec 2004 + +// PR 18803: reject legal +// Origin: Wolfgang Bangerth + +struct A { + int operator() (); +}; + +template void foo () { + A &a = *new A(); + const int i = a(); +}