mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 21:01:29 +08:00
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:
parent
89b1749804
commit
db24eb1f4f
@ -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'
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) \
|
||||
|
21
gcc/cp/cvt.c
21
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)
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
44
gcc/cp/pt.c
44
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)
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
14
gcc/testsuite/g++.dg/template/operator5.C
Normal file
14
gcc/testsuite/g++.dg/template/operator5.C
Normal 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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user