re PR c++/18803 (rejects access to operator() in template)

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) <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.

From-SVN: r91863
This commit is contained in:
Nathan Sidwell 2004-12-08 08:36:09 +00:00 committed by Nathan Sidwell
parent 89b1749804
commit db24eb1f4f
17 changed files with 174 additions and 119 deletions

View 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'

View 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);

View 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,

View 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) \

View 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)

View 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. */

View 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)

View 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)

View 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,

View 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,

View 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)

View 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);
}
/* 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)))
{
@ -459,18 +460,6 @@ build_dynamic_cast_1 (tree type, tree expr)
goto fail;
}
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
@ -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. */

View 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

View 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

View 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,

View 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

View File

@ -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();
}