summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog49
-rw-r--r--gcc/cp/call.c9
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/cvt.c21
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/except.c3
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/pt.c44
-rw-r--r--gcc/cp/rtti.c48
-rw-r--r--gcc/cp/semantics.c37
-rw-r--r--gcc/cp/typeck.c26
-rw-r--r--gcc/cp/typeck2.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/operator5.C14
17 files changed, 174 insertions, 119 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f129e110c0f..c0da0a102c7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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'
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f8af887a323..ab31c99a51e 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 8a0da05899e..886d301f160 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 318b3b30a25..668aa685754 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 f1968fd3a90..7039bfe6fd0 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 bf7b80fbd84..22fcc7cda93 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 88fba4f55e8..c7d28e502ae 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 95da1614d58..649fab79105 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 7dd15d2e1df..95b57b2e8ef 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 46b9385d176..dae68f36578 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 9bf396bf465..6e34ba6926c 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 cf66904b9b6..c113e1c349d 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 <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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7f399b48e3a..956bf04c163 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 1bd12e71a3b..a06101c42f0 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 ab95bc3e1b8..8d97e451c6d 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 d67d208e1c4..eac55dfa82d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..1c0c2923191
--- /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 <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();
+}
OpenPOWER on IntegriCloud