call.c (build_field_call): Do not look up the field by name.
* call.c (build_field_call): Do not look up the field by name. (build_method_call): Simplify. (struct z_candidate): Add access_path and conversion_path. Remove basetype_path. (convert_class_to_reference): Adjust use of add_function_candidate. (add_candidate): Add conversion_path argument. (add_function_candidate): Use it. (add_conv_dndidate): Likewise. (build_builtin_candidate): Likewise. (add_template_candidate_real): Add conversion_path argument. (add_template_conv_candidate): Likewise. (add_template_candidate): Likewise. (build_user_type_conversion_1): Use it. (build_new_function_call): Remove name lookup code. Adjust use of add_template_candidate and add_function_candidate. (build_new_op): Likewise. (convert_like_real): Use build_special_member_call. (build_over_call): Use cand->conversion_path. (build_special_member_call): New method. (build_new_method_call): Remove name lookup code. * cp-tree.def (OFFSET_REF): Update documentation. (TEMPLATE_ID_EXPR): Likewise. * cp-tree.h (BASELINK_ACCESS_BINFO): New macro. (BASELINK_OPTYPE): Likewise. (build_new_method_call): Adjust prototype. (build_special_member_call): New method. (build_baselink): New method. (build_offset_ref_call_from_tree): Likewise. (build_call_from_tree): Likewise. (finish_qualified_call_expr): Remove. (finish_call_expr): Adjust prototype. (build_x_function_call): Remove. * cvt.c (ocp_convert): Use build_special_member_call. * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr. (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and CALL_EXPR. (build_offset_ref_call_from_tree): New function. (build_call_from_tree): Likewise. * init.c (expand_cleanup): Use build_special_member_call. (expand_default_init): Likewise. (build_member_call): Use finish_call_expr. (build_new_1): Use build_special_member_call. (push_base_cleanups): Likewise. * method.c (do_build_assign_ref): Likewise. * parse.y (template_id): Do not pass a COMPONENT_REF to lookup_template_function. (primary): Use parse_finish_call_epxr, not finish_call_expr. (parse_finish_call_expr): New function. * pt.c (lookup_template_function): Add assertions. * search.c (lookup_base): Allow T to be a binfo. (build_baselink): New function. (lookup_member): Use it. * semantics.c (finish_call_expr): Do not do name lookup. (finish_object_call_expr): Remove #if 0'd code. (finish_qualified_call_expr): Remove. * typeck.c (build_x_function_call): Remove. (build_static_case): Use build_special_member_call. * typeck2.c (build_functional_cast): Likewise. * g++.dg/inherit/operator1.C: New test. * g++.dg/lookup/disamb1.C: Fix typo in comment. * g++.dg/other/error1.C: Change expected error message. * g++.dg/template/conv4.C: Likewise. From-SVN: r55920
This commit is contained in:
parent
692f56114c
commit
4ba126e468
@ -1,3 +1,65 @@
|
||||
2002-07-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* call.c (build_field_call): Do not look up the field by name.
|
||||
(build_method_call): Simplify.
|
||||
(struct z_candidate): Add access_path and conversion_path. Remove
|
||||
basetype_path.
|
||||
(convert_class_to_reference): Adjust use of
|
||||
add_function_candidate.
|
||||
(add_candidate): Add conversion_path argument.
|
||||
(add_function_candidate): Use it.
|
||||
(add_conv_dndidate): Likewise.
|
||||
(build_builtin_candidate): Likewise.
|
||||
(add_template_candidate_real): Add conversion_path argument.
|
||||
(add_template_conv_candidate): Likewise.
|
||||
(add_template_candidate): Likewise.
|
||||
(build_user_type_conversion_1): Use it.
|
||||
(build_new_function_call): Remove name lookup code. Adjust use of
|
||||
add_template_candidate and add_function_candidate.
|
||||
(build_new_op): Likewise.
|
||||
(convert_like_real): Use build_special_member_call.
|
||||
(build_over_call): Use cand->conversion_path.
|
||||
(build_special_member_call): New method.
|
||||
(build_new_method_call): Remove name lookup code.
|
||||
* cp-tree.def (OFFSET_REF): Update documentation.
|
||||
(TEMPLATE_ID_EXPR): Likewise.
|
||||
* cp-tree.h (BASELINK_ACCESS_BINFO): New macro.
|
||||
(BASELINK_OPTYPE): Likewise.
|
||||
(build_new_method_call): Adjust prototype.
|
||||
(build_special_member_call): New method.
|
||||
(build_baselink): New method.
|
||||
(build_offset_ref_call_from_tree): Likewise.
|
||||
(build_call_from_tree): Likewise.
|
||||
(finish_qualified_call_expr): Remove.
|
||||
(finish_call_expr): Adjust prototype.
|
||||
(build_x_function_call): Remove.
|
||||
* cvt.c (ocp_convert): Use build_special_member_call.
|
||||
* decl2.c (reparse_absdcl_as_expr): Use finish_call_expr.
|
||||
(build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and
|
||||
CALL_EXPR.
|
||||
(build_offset_ref_call_from_tree): New function.
|
||||
(build_call_from_tree): Likewise.
|
||||
* init.c (expand_cleanup): Use build_special_member_call.
|
||||
(expand_default_init): Likewise.
|
||||
(build_member_call): Use finish_call_expr.
|
||||
(build_new_1): Use build_special_member_call.
|
||||
(push_base_cleanups): Likewise.
|
||||
* method.c (do_build_assign_ref): Likewise.
|
||||
* parse.y (template_id): Do not pass a COMPONENT_REF to
|
||||
lookup_template_function.
|
||||
(primary): Use parse_finish_call_epxr, not finish_call_expr.
|
||||
(parse_finish_call_expr): New function.
|
||||
* pt.c (lookup_template_function): Add assertions.
|
||||
* search.c (lookup_base): Allow T to be a binfo.
|
||||
(build_baselink): New function.
|
||||
(lookup_member): Use it.
|
||||
* semantics.c (finish_call_expr): Do not do name lookup.
|
||||
(finish_object_call_expr): Remove #if 0'd code.
|
||||
(finish_qualified_call_expr): Remove.
|
||||
* typeck.c (build_x_function_call): Remove.
|
||||
(build_static_case): Use build_special_member_call.
|
||||
* typeck2.c (build_functional_cast): Likewise.
|
||||
|
||||
2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
|
||||
|
633
gcc/cp/call.c
633
gcc/cp/call.c
File diff suppressed because it is too large
Load Diff
@ -23,11 +23,25 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
|
||||
/* Reference to the contents of an offset
|
||||
(a value whose type is an OFFSET_TYPE).
|
||||
Operand 0 is the object within which the offset is taken.
|
||||
Operand 1 is the offset. The language independent OFFSET_REF
|
||||
just won't work for us. */
|
||||
/* An OFFSET_REF is used in two situations:
|
||||
|
||||
1. An expression of the form `A::m' where `A' is a class and `m' is
|
||||
a non-static data member. In this case, operand 0 will be a
|
||||
TYPE (corresponding to `A') and operand 1 will be a FIELD_DECL
|
||||
(corresponding to `m'.
|
||||
|
||||
The expression is a pointer-to-member if its address is taken,
|
||||
but simply denotes a member of the object if its address isnot
|
||||
taken. In the latter case, resolve_offset_ref is used to
|
||||
convert it to a representation of the member referred to by the
|
||||
OFFSET_REF.
|
||||
|
||||
2. An expression of the form `x.*p'. In this case, operand 0 will
|
||||
be an expression corresponding to `x' and operand 1 will be an
|
||||
expression with pointer-to-member type.
|
||||
|
||||
OFFSET_REFs are only used during the parsing phase; once semantic
|
||||
analysis has taken place they are eliminated. */
|
||||
DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2)
|
||||
|
||||
/* A pointer-to-member constant. For a pointer-to-member constant
|
||||
@ -186,7 +200,8 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 2)
|
||||
The second is the TREE_LIST or TREE_VEC of explicitly specified
|
||||
arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or
|
||||
an OVERLOAD. If the template-id refers to a member template, the
|
||||
template may be an IDENTIFIER_NODE. */
|
||||
template may be an IDENTIFIER_NODE. In an uninstantiated template,
|
||||
the template may be a LOOKUP_EXPR. */
|
||||
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
|
||||
|
||||
/* An association between name and entity. Parameters are the scope
|
||||
|
@ -385,10 +385,25 @@ struct tree_overload GTY(())
|
||||
(TREE_CODE (NODE) == TREE_LIST && TREE_LANG_FLAG_1 (NODE))
|
||||
#define SET_BASELINK_P(NODE) \
|
||||
(TREE_LANG_FLAG_1 (NODE) = 1)
|
||||
/* The BINFO indicated the base from which the BASELINK_FUNCTIONS came. */
|
||||
#define BASELINK_BINFO(NODE) \
|
||||
(TREE_PURPOSE (NODE))
|
||||
/* The functions referred to by the BASELINK; either a FUNCTION_DECL
|
||||
or an OVERLOAD. */
|
||||
#define BASELINK_FUNCTIONS(NODE) \
|
||||
(TREE_VALUE (NODE))
|
||||
/* The BINFO in which the search for the functions indicated by this baselink
|
||||
began. This base is used to determine the accessibility of functions
|
||||
selected by overload resolution. */
|
||||
#define BASELINK_ACCESS_BINFO(NODE) \
|
||||
(TREE_TYPE (NODE))
|
||||
/* For a type-conversion operator, the BASELINK_OPTYPE indicates the type
|
||||
to which the conversion should occur. This value is important if
|
||||
the BASELINK_FUNCTIONS include a template conversion operator --
|
||||
the BASELINK_OPTYPE can be used to determine what type the user
|
||||
requested. */
|
||||
#define BASELINK_OPTYPE(NODE) \
|
||||
(TREE_CHAIN (NODE))
|
||||
|
||||
#define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)
|
||||
|
||||
@ -3676,6 +3691,8 @@ extern int sufficient_parms_p PARAMS ((tree));
|
||||
extern tree type_decays_to PARAMS ((tree));
|
||||
extern tree build_user_type_conversion PARAMS ((tree, tree, int));
|
||||
extern tree build_new_function_call PARAMS ((tree, tree));
|
||||
extern tree build_new_method_call (tree, tree, tree, tree, int);
|
||||
extern tree build_special_member_call (tree, tree, tree, tree, int);
|
||||
extern tree build_new_op PARAMS ((enum tree_code, int, tree, tree, tree));
|
||||
extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree));
|
||||
extern int can_convert PARAMS ((tree, tree));
|
||||
@ -3950,6 +3967,8 @@ extern void finish_file PARAMS ((void));
|
||||
extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
|
||||
extern tree reparse_absdcl_as_casts PARAMS ((tree, tree));
|
||||
extern tree build_expr_from_tree PARAMS ((tree));
|
||||
extern tree build_offset_ref_call_from_tree (tree, tree);
|
||||
extern tree build_call_from_tree (tree, tree, bool);
|
||||
extern tree reparse_decl_as_expr PARAMS ((tree, tree));
|
||||
extern tree finish_decl_parsing PARAMS ((tree));
|
||||
extern void set_decl_namespace PARAMS ((tree, tree, int));
|
||||
@ -4229,6 +4248,7 @@ extern tree unmarked_vtable_pathp PARAMS ((tree, void *));
|
||||
extern tree find_vbase_instance PARAMS ((tree, tree));
|
||||
extern tree binfo_for_vbase PARAMS ((tree, tree));
|
||||
extern tree binfo_via_virtual PARAMS ((tree, tree));
|
||||
extern tree build_baselink (tree, tree, tree, tree);
|
||||
|
||||
/* in semantics.c */
|
||||
extern void init_cp_semantics PARAMS ((void));
|
||||
@ -4281,13 +4301,12 @@ extern void finish_subobject PARAMS ((tree));
|
||||
extern tree finish_parenthesized_expr PARAMS ((tree));
|
||||
extern tree begin_stmt_expr PARAMS ((void));
|
||||
extern tree finish_stmt_expr PARAMS ((tree));
|
||||
extern tree finish_call_expr PARAMS ((tree, tree, int));
|
||||
extern tree finish_call_expr (tree, tree, bool);
|
||||
extern tree finish_increment_expr PARAMS ((tree, enum tree_code));
|
||||
extern tree finish_this_expr PARAMS ((void));
|
||||
extern tree finish_object_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_qualified_call_expr PARAMS ((tree, tree));
|
||||
extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
|
||||
extern tree finish_id_expr PARAMS ((tree));
|
||||
extern tree finish_fname (tree);
|
||||
@ -4454,7 +4473,6 @@ extern tree build_x_component_ref PARAMS ((tree, tree, tree));
|
||||
extern tree build_x_indirect_ref PARAMS ((tree, const char *));
|
||||
extern tree build_indirect_ref PARAMS ((tree, const char *));
|
||||
extern tree build_array_ref PARAMS ((tree, tree));
|
||||
extern tree build_x_function_call PARAMS ((tree, tree, tree));
|
||||
extern tree get_member_function_from_ptrfunc PARAMS ((tree *, tree));
|
||||
extern tree build_function_call_real PARAMS ((tree, tree, int, int));
|
||||
extern tree build_function_call_maybe PARAMS ((tree, tree));
|
||||
|
@ -771,10 +771,10 @@ ocp_convert (type, expr, convtype, flags)
|
||||
the target with the temp (see [dcl.init]). */
|
||||
ctor = build_user_type_conversion (type, ctor, flags);
|
||||
else
|
||||
ctor = build_method_call (NULL_TREE,
|
||||
complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, ctor),
|
||||
TYPE_BINFO (type), flags);
|
||||
ctor = build_special_member_call (NULL_TREE,
|
||||
complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, ctor),
|
||||
TYPE_BINFO (type), flags);
|
||||
if (ctor)
|
||||
return build_cplus_new (type, ctor);
|
||||
}
|
||||
|
150
gcc/cp/decl2.c
150
gcc/cp/decl2.c
@ -3587,14 +3587,7 @@ reparse_absdcl_as_expr (type, decl)
|
||||
/* recurse */
|
||||
decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0));
|
||||
|
||||
decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
|
||||
|
||||
if (TREE_CODE (decl) == CALL_EXPR
|
||||
&& (! TREE_TYPE (decl)
|
||||
|| TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE))
|
||||
decl = require_complete_type (decl);
|
||||
|
||||
return decl;
|
||||
return finish_call_expr (decl, NULL_TREE, /*disallow_virtual=*/false);
|
||||
}
|
||||
|
||||
/* This is something of the form `int ((int)(int)(int)1)' that has turned
|
||||
@ -3647,7 +3640,8 @@ reparse_absdcl_as_casts (decl, expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Given plain tree nodes for an expression, build up the full semantics. */
|
||||
/* T is the parse tree for an expression. Return the expression after
|
||||
performing semantic analysis. */
|
||||
|
||||
tree
|
||||
build_expr_from_tree (t)
|
||||
@ -3671,9 +3665,29 @@ build_expr_from_tree (t)
|
||||
return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
|
||||
|
||||
case TEMPLATE_ID_EXPR:
|
||||
return (lookup_template_function
|
||||
(build_expr_from_tree (TREE_OPERAND (t, 0)),
|
||||
build_expr_from_tree (TREE_OPERAND (t, 1))));
|
||||
{
|
||||
tree template;
|
||||
tree args;
|
||||
tree object;
|
||||
|
||||
template = build_expr_from_tree (TREE_OPERAND (t, 0));
|
||||
args = build_expr_from_tree (TREE_OPERAND (t, 1));
|
||||
|
||||
if (TREE_CODE (template) == COMPONENT_REF)
|
||||
{
|
||||
object = TREE_OPERAND (template, 0);
|
||||
template = TREE_OPERAND (template, 1);
|
||||
}
|
||||
else
|
||||
object = NULL_TREE;
|
||||
|
||||
template = lookup_template_function (template, args);
|
||||
if (object)
|
||||
return build (COMPONENT_REF, TREE_TYPE (template),
|
||||
object, template);
|
||||
else
|
||||
return template;
|
||||
}
|
||||
|
||||
case INDIRECT_REF:
|
||||
return build_x_indirect_ref
|
||||
@ -3881,9 +3895,18 @@ build_expr_from_tree (t)
|
||||
name = do_identifier (id, 0, args);
|
||||
}
|
||||
else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
|
||||
|| ! really_overloaded_fn (name))
|
||||
|| ! really_overloaded_fn (name))
|
||||
name = build_expr_from_tree (name);
|
||||
return build_x_function_call (name, args, current_class_ref);
|
||||
|
||||
if (TREE_CODE (name) == OFFSET_REF)
|
||||
return build_offset_ref_call_from_tree (name, args);
|
||||
if (TREE_CODE (name) == COMPONENT_REF)
|
||||
return finish_object_call_expr (TREE_OPERAND (name, 1),
|
||||
TREE_OPERAND (name, 0),
|
||||
args);
|
||||
name = convert_from_reference (name);
|
||||
return build_call_from_tree (name, args,
|
||||
/*disallow_virtual=*/false);
|
||||
}
|
||||
|
||||
case COND_EXPR:
|
||||
@ -3988,6 +4011,105 @@ build_expr_from_tree (t)
|
||||
}
|
||||
}
|
||||
|
||||
/* FN is an OFFSET_REF indicating the function to call in parse-tree
|
||||
form; it has not yet been semantically analyzed. ARGS are the
|
||||
arguments to the function. They have already been semantically
|
||||
analzyed. */
|
||||
|
||||
tree
|
||||
build_offset_ref_call_from_tree (tree fn, tree args)
|
||||
{
|
||||
tree object_addr;
|
||||
|
||||
my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725);
|
||||
|
||||
/* A qualified name corresponding to a non-static member
|
||||
function or a pointer-to-member is represented as an
|
||||
OFFSET_REF.
|
||||
|
||||
For both of these function calls, FN will be an OFFSET_REF.
|
||||
|
||||
struct A { void f(); };
|
||||
void A::f() { (A::f) (); }
|
||||
|
||||
struct B { void g(); };
|
||||
void (B::*p)();
|
||||
void B::g() { (this->*p)(); } */
|
||||
|
||||
/* This code is not really correct (for example, it does not
|
||||
handle the case that `A::f' is overloaded), but it is
|
||||
historically how we have handled this situation. */
|
||||
object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0);
|
||||
if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL)
|
||||
fn = resolve_offset_ref (fn);
|
||||
else
|
||||
{
|
||||
fn = TREE_OPERAND (fn, 1);
|
||||
fn = get_member_function_from_ptrfunc (&object_addr, fn);
|
||||
}
|
||||
args = tree_cons (NULL_TREE, object_addr, args);
|
||||
return build_function_call (fn, args);
|
||||
}
|
||||
|
||||
/* FN indicates the function to call. Name resolution has been
|
||||
performed on FN. ARGS are the arguments to the function. They
|
||||
have already been semantically analyzed. DISALLOW_VIRTUAL is true
|
||||
if the function call should be determined at compile time, even if
|
||||
FN is virtual. */
|
||||
|
||||
tree
|
||||
build_call_from_tree (tree fn, tree args, bool disallow_virtual)
|
||||
{
|
||||
tree template_args;
|
||||
tree template_id;
|
||||
tree f;
|
||||
|
||||
/* Check to see that name lookup has already been performed. */
|
||||
my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725);
|
||||
my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725);
|
||||
|
||||
/* In the future all of this should be eliminated. Instead,
|
||||
name-lookup for a member function should simply return a
|
||||
baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or
|
||||
TEMPLATE_ID_EXPR. */
|
||||
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
template_id = fn;
|
||||
template_args = TREE_OPERAND (fn, 1);
|
||||
fn = TREE_OPERAND (fn, 0);
|
||||
}
|
||||
else
|
||||
template_id = NULL_TREE;
|
||||
|
||||
f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn;
|
||||
/* Make sure we have a baselink (rather than simply a
|
||||
FUNCTION_DECL) for a member function. */
|
||||
if (current_class_type
|
||||
&& ((TREE_CODE (f) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_MEMBER_P (f))
|
||||
|| (DECL_FUNCTION_TEMPLATE_P (f)
|
||||
&& DECL_FUNCTION_MEMBER_P (f))))
|
||||
{
|
||||
f = lookup_member (current_class_type, DECL_NAME (f),
|
||||
/*protect=*/1, /*want_type=*/0);
|
||||
if (f)
|
||||
fn = f;
|
||||
}
|
||||
|
||||
if (template_id)
|
||||
{
|
||||
if (BASELINK_P (fn))
|
||||
BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
|
||||
BASELINK_FUNCTIONS (fn),
|
||||
template_args);
|
||||
else
|
||||
fn = template_id;
|
||||
}
|
||||
|
||||
return finish_call_expr (fn, args, disallow_virtual);
|
||||
}
|
||||
|
||||
/* This is something of the form `int (*a)++' that has turned out to be an
|
||||
expr. It was only converted into parse nodes, so we need to go through
|
||||
and build up the semantics. Most of the work is done by
|
||||
|
@ -852,8 +852,11 @@ expand_cleanup_for_base (binfo, flag)
|
||||
return;
|
||||
|
||||
/* Call the destructor. */
|
||||
expr = (build_scoped_method_call
|
||||
(current_class_ref, binfo, base_dtor_identifier, NULL_TREE));
|
||||
expr = build_special_member_call (current_class_ref,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE,
|
||||
binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
|
||||
if (flag)
|
||||
expr = fold (build (COND_EXPR, void_type_node,
|
||||
c_common_truthvalue_conversion (flag),
|
||||
@ -1282,7 +1285,7 @@ expand_default_init (binfo, true_exp, exp, init, flags)
|
||||
else
|
||||
ctor_name = base_ctor_identifier;
|
||||
|
||||
rval = build_method_call (exp, ctor_name, parms, binfo, flags);
|
||||
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
|
||||
if (TREE_SIDE_EFFECTS (rval))
|
||||
{
|
||||
if (building_stmt_tree ())
|
||||
@ -1451,15 +1454,16 @@ build_member_call (type, name, parmlist)
|
||||
TREE_OPERAND (name, 0) = method_name;
|
||||
}
|
||||
my_friendly_assert (is_overloaded_fn (method_name), 980519);
|
||||
return build_x_function_call (name, parmlist, current_class_ref);
|
||||
return finish_call_expr (name, parmlist, /*disallow_virtual=*/true);
|
||||
}
|
||||
|
||||
if (DECL_P (name))
|
||||
name = DECL_NAME (name);
|
||||
|
||||
if (TREE_CODE (type) == NAMESPACE_DECL)
|
||||
return build_x_function_call (lookup_namespace_name (type, name),
|
||||
parmlist, current_class_ref);
|
||||
return finish_call_expr (lookup_namespace_name (type, name),
|
||||
parmlist,
|
||||
/*disallow_virtual=*/true);
|
||||
|
||||
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
@ -1486,10 +1490,9 @@ build_member_call (type, name, parmlist)
|
||||
{
|
||||
tree ns = lookup_name (type, 0);
|
||||
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
|
||||
{
|
||||
return build_x_function_call (build_offset_ref (type, name),
|
||||
parmlist, current_class_ref);
|
||||
}
|
||||
return finish_call_expr (lookup_namespace_name (ns, name),
|
||||
parmlist,
|
||||
/*disallow_virtual=*/true);
|
||||
}
|
||||
|
||||
if (type == NULL_TREE || ! is_aggr_type (type, 1))
|
||||
@ -2326,7 +2329,8 @@ build_new_1 (exp)
|
||||
args));
|
||||
else
|
||||
alloc_call = build_method_call (build_dummy_object (true_type),
|
||||
fnname, args, NULL_TREE,
|
||||
fnname, args,
|
||||
TYPE_BINFO (true_type),
|
||||
LOOKUP_NORMAL);
|
||||
}
|
||||
|
||||
@ -2415,10 +2419,10 @@ build_new_1 (exp)
|
||||
if (has_array)
|
||||
init_expr = build_vec_init (init_expr, init, 0);
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
init_expr = build_method_call (init_expr,
|
||||
complete_ctor_identifier,
|
||||
init, TYPE_BINFO (true_type),
|
||||
LOOKUP_NORMAL);
|
||||
init_expr = build_special_member_call (init_expr,
|
||||
complete_ctor_identifier,
|
||||
init, TYPE_BINFO (true_type),
|
||||
LOOKUP_NORMAL);
|
||||
else
|
||||
{
|
||||
/* We are processing something like `new int (10)', which
|
||||
@ -3090,7 +3094,8 @@ build_dtor_call (exp, dtor_kind, flags)
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return build_method_call (exp, name, NULL_TREE, NULL_TREE, flags);
|
||||
return build_method_call (exp, name, NULL_TREE,
|
||||
TYPE_BINFO (TREE_TYPE (exp)), flags);
|
||||
}
|
||||
|
||||
/* Generate a call to a destructor. TYPE is the type to cast ADDR to.
|
||||
@ -3282,9 +3287,12 @@ push_base_cleanups ()
|
||||
|
||||
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
|
||||
{
|
||||
expr = build_scoped_method_call (current_class_ref, vbase,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE);
|
||||
expr = build_special_member_call (current_class_ref,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE,
|
||||
vbase,
|
||||
(LOOKUP_NORMAL
|
||||
| LOOKUP_NONVIRTUAL));
|
||||
expr = build (COND_EXPR, void_type_node, cond,
|
||||
expr, void_zero_node);
|
||||
finish_decl_cleanup (NULL_TREE, expr);
|
||||
@ -3303,10 +3311,10 @@ push_base_cleanups ()
|
||||
|| TREE_VIA_VIRTUAL (base_binfo))
|
||||
continue;
|
||||
|
||||
expr = build_scoped_method_call (current_class_ref, base_binfo,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE);
|
||||
|
||||
expr = build_special_member_call (current_class_ref,
|
||||
base_dtor_identifier,
|
||||
NULL_TREE, base_binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
|
||||
finish_decl_cleanup (NULL_TREE, expr);
|
||||
}
|
||||
|
||||
|
@ -623,28 +623,34 @@ do_build_assign_ref (fndecl)
|
||||
}
|
||||
else
|
||||
{
|
||||
tree fields = TYPE_FIELDS (current_class_type);
|
||||
int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
|
||||
tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
|
||||
tree fields;
|
||||
int cvquals = cp_type_quals (TREE_TYPE (parm));
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_bases; ++i)
|
||||
/* Assign to each of thedirect base classes. */
|
||||
for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i)
|
||||
{
|
||||
/* We must deal with the binfo's directly as a direct base
|
||||
might be inaccessible due to ambiguity. */
|
||||
tree binfo = TREE_VEC_ELT (binfos, i);
|
||||
tree src = build_base_path (PLUS_EXPR, parm, binfo, 1);
|
||||
tree dst = build_base_path (PLUS_EXPR, current_class_ref, binfo, 1);
|
||||
tree binfo;
|
||||
tree converted_parm;
|
||||
|
||||
tree expr = build_method_call (dst,
|
||||
ansi_assopname (NOP_EXPR),
|
||||
build_tree_list (NULL_TREE, src),
|
||||
binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
|
||||
finish_expr_stmt (expr);
|
||||
binfo = BINFO_BASETYPE (TYPE_BINFO (current_class_type), i);
|
||||
/* We must convert PARM directly to the base class
|
||||
explicitly since the base class may be ambiguous. */
|
||||
converted_parm = build_base_path (PLUS_EXPR, parm, binfo, 1);
|
||||
/* Call the base class assignment operator. */
|
||||
finish_expr_stmt
|
||||
(build_special_member_call (current_class_ref,
|
||||
ansi_assopname (NOP_EXPR),
|
||||
build_tree_list (NULL_TREE,
|
||||
converted_parm),
|
||||
binfo,
|
||||
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
|
||||
}
|
||||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
|
||||
/* Assign to each of the non-static data members. */
|
||||
for (fields = TYPE_FIELDS (current_class_type);
|
||||
fields;
|
||||
fields = TREE_CHAIN (fields))
|
||||
{
|
||||
tree comp, init, t;
|
||||
tree field = fields;
|
||||
|
169
gcc/cp/parse.y
169
gcc/cp/parse.y
@ -131,6 +131,7 @@ static tree parse_xref_tag (tree, tree, int);
|
||||
static tree parse_handle_class_head (tree, tree, tree, int, int *);
|
||||
static void parse_decl_instantiation (tree, tree, tree);
|
||||
static int parse_begin_function_definition (tree, tree);
|
||||
static tree parse_finish_call_expr (tree, tree, int);
|
||||
|
||||
/* Cons up an empty parameter list. */
|
||||
static inline tree
|
||||
@ -1534,9 +1535,19 @@ do_id:
|
||||
|
||||
template_id:
|
||||
PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
|
||||
{ $$ = lookup_template_function ($3, $4); }
|
||||
{
|
||||
tree template_name = $3;
|
||||
if (TREE_CODE (template_name) == COMPONENT_REF)
|
||||
template_name = TREE_OPERAND (template_name, 1);
|
||||
$$ = lookup_template_function (template_name, $4);
|
||||
}
|
||||
| operator_name '<' do_id template_arg_list_opt template_close_bracket
|
||||
{ $$ = lookup_template_function ($3, $4); }
|
||||
{
|
||||
tree template_name = $3;
|
||||
if (TREE_CODE (template_name) == COMPONENT_REF)
|
||||
template_name = TREE_OPERAND (template_name, 1);
|
||||
$$ = lookup_template_function (template_name, $4);
|
||||
}
|
||||
;
|
||||
|
||||
object_template_id:
|
||||
@ -1637,13 +1648,13 @@ primary:
|
||||
We could store lastiddecl in $1 to avoid another lookup,
|
||||
but that would result in many additional reduce/reduce conflicts. */
|
||||
| notype_unqualified_id '(' nonnull_exprlist ')'
|
||||
{ $$ = finish_call_expr ($1, $3, 1); }
|
||||
{ $$ = parse_finish_call_expr ($1, $3, 1); }
|
||||
| notype_unqualified_id LEFT_RIGHT
|
||||
{ $$ = finish_call_expr ($1, NULL_TREE, 1); }
|
||||
{ $$ = parse_finish_call_expr ($1, NULL_TREE, 1); }
|
||||
| primary '(' nonnull_exprlist ')'
|
||||
{ $$ = finish_call_expr ($1, $3, 0); }
|
||||
{ $$ = parse_finish_call_expr ($1, $3, 0); }
|
||||
| primary LEFT_RIGHT
|
||||
{ $$ = finish_call_expr ($1, NULL_TREE, 0); }
|
||||
{ $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
|
||||
| VA_ARG '(' expr_no_commas ',' type_id ')'
|
||||
{ $$ = build_x_va_arg ($3, groktypename ($5.t));
|
||||
check_for_new_type ("__builtin_va_arg", $5); }
|
||||
@ -1705,9 +1716,9 @@ primary:
|
||||
| overqualified_id %prec HYPERUNARY
|
||||
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
|
||||
| overqualified_id '(' nonnull_exprlist ')'
|
||||
{ $$ = finish_qualified_call_expr ($1, $3); }
|
||||
{ $$ = parse_finish_call_expr ($1, $3, 0); }
|
||||
| overqualified_id LEFT_RIGHT
|
||||
{ $$ = finish_qualified_call_expr ($1, NULL_TREE); }
|
||||
{ $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
|
||||
| object object_template_id %prec UNARY
|
||||
{
|
||||
$$ = build_x_component_ref ($$, $2, NULL_TREE);
|
||||
@ -4099,4 +4110,146 @@ parse_begin_function_definition (tree specs_attrs, tree declarator)
|
||||
return begin_function_definition (specs, attrs, declarator);
|
||||
}
|
||||
|
||||
/* Like finish_call_expr, but the name for FN has not yet been
|
||||
resolved. */
|
||||
|
||||
static tree
|
||||
parse_finish_call_expr (tree fn, tree args, int koenig)
|
||||
{
|
||||
bool disallow_virtual;
|
||||
tree template_args;
|
||||
tree template_id;
|
||||
tree f;
|
||||
|
||||
if (TREE_CODE (fn) == OFFSET_REF)
|
||||
return build_offset_ref_call_from_tree (fn, args);
|
||||
|
||||
if (TREE_CODE (fn) == SCOPE_REF)
|
||||
{
|
||||
tree scope;
|
||||
tree name;
|
||||
|
||||
scope = TREE_OPERAND (fn, 0);
|
||||
name = TREE_OPERAND (fn, 1);
|
||||
|
||||
if (scope == error_mark_node || name == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
if (TREE_CODE (scope) == NAMESPACE_DECL)
|
||||
fn = lookup_namespace_name (scope, name);
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
template_id = name;
|
||||
template_args = TREE_OPERAND (name, 1);
|
||||
name = TREE_OPERAND (name, 0);
|
||||
}
|
||||
else
|
||||
template_id = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (name) == OVERLOAD)
|
||||
name = DECL_NAME (get_first_fn (name));
|
||||
fn = lookup_member (scope, name, /*protect=*/1,
|
||||
/*prefer_type=*/0);
|
||||
if (BASELINK_P (fn) && template_id)
|
||||
BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
|
||||
BASELINK_FUNCTIONS (fn),
|
||||
template_args);
|
||||
if (BASELINK_P (fn)
|
||||
&& current_class_type
|
||||
&& DERIVED_FROM_P (scope, current_class_type))
|
||||
{
|
||||
scope = lookup_base (current_class_type, scope,
|
||||
ba_ignore | ba_quiet, NULL);
|
||||
if (scope)
|
||||
{
|
||||
BASELINK_ACCESS_BINFO (fn) = scope;
|
||||
BASELINK_BINFO (fn)
|
||||
= lookup_base (scope,
|
||||
BINFO_TYPE (BASELINK_BINFO (fn)),
|
||||
ba_ignore | ba_quiet,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
disallow_virtual = true;
|
||||
}
|
||||
else
|
||||
disallow_virtual = false;
|
||||
|
||||
if (koenig && TREE_CODE (fn) == IDENTIFIER_NODE)
|
||||
{
|
||||
/* Do the Koenig lookup. */
|
||||
fn = do_identifier (fn, 2, args);
|
||||
/* If name lookup didn't find any matching declarations, we've
|
||||
got an unbound identifier. */
|
||||
if (TREE_CODE (fn) == IDENTIFIER_NODE)
|
||||
{
|
||||
/* For some reason, do_identifier does not resolve
|
||||
conversion operator names if the only matches would be
|
||||
template conversion operators. So, we do it here. */
|
||||
if (IDENTIFIER_TYPENAME_P (fn) && current_class_type)
|
||||
{
|
||||
f = lookup_member (current_class_type, fn,
|
||||
/*protect=*/1, /*want_type=*/0);
|
||||
if (f)
|
||||
return finish_call_expr (f, args,
|
||||
/*disallow_virtual=*/false);
|
||||
}
|
||||
/* If the name still could not be resolved, then the program
|
||||
is ill-formed. */
|
||||
if (TREE_CODE (fn) == IDENTIFIER_NODE)
|
||||
{
|
||||
unqualified_name_lookup_error (fn);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (fn) == FUNCTION_DECL
|
||||
|| DECL_FUNCTION_TEMPLATE_P (fn)
|
||||
|| TREE_CODE (fn) == OVERLOAD)
|
||||
{
|
||||
tree scope = DECL_CONTEXT (get_first_fn (fn));
|
||||
if (scope && TYPE_P (scope))
|
||||
{
|
||||
tree access_scope;
|
||||
|
||||
if (DERIVED_FROM_P (scope, current_class_type)
|
||||
&& current_class_ref)
|
||||
return finish_object_call_expr (fn,
|
||||
current_class_ref,
|
||||
args);
|
||||
|
||||
access_scope = current_class_type;
|
||||
while (!DERIVED_FROM_P (scope, access_scope))
|
||||
{
|
||||
access_scope = TYPE_CONTEXT (access_scope);
|
||||
while (DECL_P (access_scope))
|
||||
access_scope = DECL_CONTEXT (access_scope);
|
||||
}
|
||||
|
||||
fn = build_baselink (NULL_TREE,
|
||||
TYPE_BINFO (access_scope),
|
||||
fn,
|
||||
/*optype=*/NULL_TREE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (fn) == COMPONENT_REF)
|
||||
/* If the parser sees `(x->y)(bar)' we get here because the
|
||||
parentheses confuse the parser. Treat this like
|
||||
`x->y(bar)'. */
|
||||
return finish_object_call_expr (TREE_OPERAND (fn, 1),
|
||||
TREE_OPERAND (fn, 0),
|
||||
args);
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_nt (CALL_EXPR, fn, args, NULL_TREE);
|
||||
|
||||
return build_call_from_tree (fn, args, disallow_virtual);
|
||||
}
|
||||
|
||||
#include "gt-cp-parse.h"
|
||||
|
25
gcc/cp/pt.c
25
gcc/cp/pt.c
@ -3814,9 +3814,9 @@ add_pending_template (d)
|
||||
}
|
||||
|
||||
|
||||
/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS (which
|
||||
may be either a _DECL or an overloaded function or an
|
||||
IDENTIFIER_NODE), and ARGLIST. */
|
||||
/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS and
|
||||
ARGLIST. Valid choices for FNS are given in the cp-tree.def
|
||||
documentation for TEMPLATE_ID_EXPR. */
|
||||
|
||||
tree
|
||||
lookup_template_function (fns, arglist)
|
||||
@ -3824,20 +3824,26 @@ lookup_template_function (fns, arglist)
|
||||
{
|
||||
tree type;
|
||||
|
||||
if (fns == error_mark_node || arglist == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (fns == NULL_TREE)
|
||||
{
|
||||
error ("non-template used as template");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
|
||||
|| TREE_CODE (fns) == OVERLOAD
|
||||
|| TREE_CODE (fns) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (fns) == LOOKUP_EXPR,
|
||||
20020730);
|
||||
|
||||
type = TREE_TYPE (fns);
|
||||
if (TREE_CODE (fns) == OVERLOAD || !type)
|
||||
type = unknown_type_node;
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);
|
||||
else
|
||||
return build (TEMPLATE_ID_EXPR, type, fns, arglist);
|
||||
|
||||
return build (TEMPLATE_ID_EXPR, type, fns, arglist);
|
||||
}
|
||||
|
||||
/* Within the scope of a template class S<T>, the name S gets bound
|
||||
@ -8012,8 +8018,7 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
|
||||
my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
|
||||
my_friendly_assert (xparms == NULL_TREE
|
||||
|| TREE_CODE (xparms) == TREE_LIST, 290);
|
||||
/* ARGS could be NULL (via a call from parse.y to
|
||||
build_x_function_call). */
|
||||
/* ARGS could be NULL. */
|
||||
if (xargs)
|
||||
my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
|
||||
my_friendly_assert (ntparms > 0, 292);
|
||||
|
@ -310,6 +310,7 @@ lookup_base (t, base, access, kind_ptr)
|
||||
base_kind *kind_ptr;
|
||||
{
|
||||
tree binfo = NULL; /* The binfo we've found so far. */
|
||||
tree t_binfo = NULL;
|
||||
base_kind bk;
|
||||
|
||||
if (t == error_mark_node || base == error_mark_node)
|
||||
@ -318,13 +319,21 @@ lookup_base (t, base, access, kind_ptr)
|
||||
*kind_ptr = bk_not_base;
|
||||
return error_mark_node;
|
||||
}
|
||||
my_friendly_assert (TYPE_P (t) && TYPE_P (base), 20011127);
|
||||
my_friendly_assert (TYPE_P (base), 20011127);
|
||||
|
||||
if (!TYPE_P (t))
|
||||
{
|
||||
t_binfo = t;
|
||||
t = BINFO_TYPE (t);
|
||||
}
|
||||
else
|
||||
t_binfo = TYPE_BINFO (t);
|
||||
|
||||
/* Ensure that the types are instantiated. */
|
||||
t = complete_type (TYPE_MAIN_VARIANT (t));
|
||||
base = complete_type (TYPE_MAIN_VARIANT (base));
|
||||
|
||||
bk = lookup_base_r (TYPE_BINFO (t), base, access & ~ba_quiet,
|
||||
bk = lookup_base_r (t_binfo, base, access & ~ba_quiet,
|
||||
0, 0, 0, &binfo);
|
||||
|
||||
switch (bk)
|
||||
@ -1361,6 +1370,32 @@ lookup_field_r (binfo, data)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Return a "baselink" which BASELINK_BINFO, BASELINK_ACCESS_BINFO,
|
||||
BASELINK_FUNCTIONS, and BASELINK_OPTYPE set to BINFO, ACCESS_BINFO,
|
||||
FUNCTIONS, and OPTYPE respectively. */
|
||||
|
||||
tree
|
||||
build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
|
||||
{
|
||||
tree baselink;
|
||||
|
||||
my_friendly_assert (TREE_CODE (functions) == FUNCTION_DECL
|
||||
|| TREE_CODE (functions) == TEMPLATE_DECL
|
||||
|| TREE_CODE (functions) == TEMPLATE_ID_EXPR
|
||||
|| TREE_CODE (functions) == OVERLOAD,
|
||||
20020730);
|
||||
my_friendly_assert (!optype || TYPE_P (optype), 20020730);
|
||||
|
||||
baselink = build_tree_list (NULL_TREE, NULL_TREE);
|
||||
SET_BASELINK_P (baselink);
|
||||
BASELINK_BINFO (baselink) = binfo;
|
||||
BASELINK_ACCESS_BINFO (baselink) = access_binfo;
|
||||
BASELINK_FUNCTIONS (baselink) = functions;
|
||||
BASELINK_OPTYPE (baselink) = optype;
|
||||
|
||||
return baselink;
|
||||
}
|
||||
|
||||
/* Look for a member named NAME in an inheritance lattice dominated by
|
||||
XBASETYPE. If PROTECT is 0 or two, we do not check access. If it is
|
||||
1, we enforce accessibility. If PROTECT is zero, then, for an
|
||||
@ -1470,19 +1505,9 @@ lookup_member (xbasetype, name, protect, want_type)
|
||||
TREE_TYPE (rval)));
|
||||
|
||||
if (rval && is_overloaded_fn (rval))
|
||||
{
|
||||
/* Note that the binfo we put in the baselink is the binfo where
|
||||
we found the functions, which we need for overload
|
||||
resolution, but which should not be passed to enforce_access;
|
||||
rather, enforce_access wants a binfo which refers to the
|
||||
scope in which we started looking for the function. This
|
||||
will generally be the binfo passed into this function as
|
||||
xbasetype. */
|
||||
|
||||
rval = tree_cons (rval_binfo, rval, NULL_TREE);
|
||||
SET_BASELINK_P (rval);
|
||||
}
|
||||
|
||||
rval = build_baselink (rval_binfo, basetype_path, rval,
|
||||
(IDENTIFIER_TYPENAME_P (name)
|
||||
? TREE_TYPE (name): NULL_TREE));
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -1242,32 +1242,86 @@ finish_stmt_expr (rtl_expr)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Finish a call to FN with ARGS. Returns a representation of the
|
||||
call. */
|
||||
/* Generate an expression for `FN (ARGS)'.
|
||||
|
||||
If DISALLOW_VIRTUAL is true, the call to FN will be not generated
|
||||
as a virtual call, even if FN is virtual. (This flag is set when
|
||||
encountering an expression where the function name is explicitly
|
||||
qualified. For example a call to `X::f' never generates a virtual
|
||||
call.)
|
||||
|
||||
Returns code for the call. */
|
||||
|
||||
tree
|
||||
finish_call_expr (fn, args, koenig)
|
||||
tree fn;
|
||||
tree args;
|
||||
int koenig;
|
||||
finish_call_expr (tree fn, tree args, bool disallow_virtual)
|
||||
{
|
||||
tree result;
|
||||
if (fn == error_mark_node || args == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (koenig)
|
||||
if (processing_template_decl)
|
||||
return build_nt (CALL_EXPR, fn, args, NULL_TREE);
|
||||
|
||||
/* ARGS should be a list of arguments. */
|
||||
my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
|
||||
20020712);
|
||||
|
||||
if (BASELINK_P (fn))
|
||||
{
|
||||
if (TREE_CODE (fn) == BIT_NOT_EXPR)
|
||||
fn = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (fn, 0));
|
||||
else if (TREE_CODE (fn) != TEMPLATE_ID_EXPR)
|
||||
fn = do_identifier (fn, 2, args);
|
||||
tree object;
|
||||
|
||||
/* A call to a member function. From [over.call.func]:
|
||||
|
||||
If the keyword this is in scope and refers to the class of
|
||||
that member function, or a derived class thereof, then the
|
||||
function call is transformed into a qualified function call
|
||||
using (*this) as the postfix-expression to the left of the
|
||||
. operator.... [Otherwise] a contrived object of type T
|
||||
becomes the implied object argument.
|
||||
|
||||
This paragraph is unclear about this situation:
|
||||
|
||||
struct A { void f(); };
|
||||
struct B : public A {};
|
||||
struct C : public A { void g() { B::f(); }};
|
||||
|
||||
In particular, for `B::f', this paragraph does not make clear
|
||||
whether "the class of that member function" refers to `A' or
|
||||
to `B'. We believe it refers to `B'. */
|
||||
if (current_class_type
|
||||
&& DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
|
||||
current_class_type)
|
||||
&& current_class_ref)
|
||||
object = current_class_ref;
|
||||
else
|
||||
{
|
||||
tree representative_fn;
|
||||
|
||||
representative_fn = BASELINK_FUNCTIONS (fn);
|
||||
if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
|
||||
representative_fn = TREE_OPERAND (representative_fn, 0);
|
||||
representative_fn = get_first_fn (representative_fn);
|
||||
object = build_dummy_object (DECL_CONTEXT (representative_fn));
|
||||
}
|
||||
|
||||
return build_new_method_call (object, fn, args, NULL_TREE,
|
||||
(disallow_virtual
|
||||
? LOOKUP_NONVIRTUAL : 0));
|
||||
}
|
||||
else if (is_overloaded_fn (fn))
|
||||
/* A call to a namespace-scope function. */
|
||||
return build_new_function_call (fn, args);
|
||||
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
|
||||
{
|
||||
/* If the "function" is really an object of class type, it might
|
||||
have an overloaded `operator ()'. */
|
||||
tree result;
|
||||
result = build_opfncall (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
result = build_x_function_call (fn, args, current_class_ref);
|
||||
|
||||
if (TREE_CODE (result) == CALL_EXPR
|
||||
&& (! TREE_TYPE (result)
|
||||
|| TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
|
||||
result = require_complete_type (result);
|
||||
|
||||
return result;
|
||||
/* A call where the function is unknown. */
|
||||
return build_function_call (fn, args);
|
||||
}
|
||||
|
||||
/* Finish a call to a postfix increment or decrement or EXPR. (Which
|
||||
@ -1327,14 +1381,6 @@ finish_object_call_expr (fn, object, args)
|
||||
tree object;
|
||||
tree args;
|
||||
{
|
||||
#if 0
|
||||
/* This is a future direction of this code, but because
|
||||
build_x_function_call cannot always undo what is done in
|
||||
build_component_ref entirely yet, we cannot do this. */
|
||||
|
||||
tree real_fn = build_component_ref (object, fn, NULL_TREE, 1);
|
||||
return finish_call_expr (real_fn, args);
|
||||
#else
|
||||
if (DECL_DECLARES_TYPE_P (fn))
|
||||
{
|
||||
if (processing_template_decl)
|
||||
@ -1353,9 +1399,8 @@ finish_object_call_expr (fn, object, args)
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Finish a qualified member function call using OBJECT and ARGS as
|
||||
@ -1396,22 +1441,6 @@ finish_pseudo_destructor_call_expr (object, scope, destructor)
|
||||
return cp_convert (void_type_node, object);
|
||||
}
|
||||
|
||||
/* Finish a call to a globally qualified member function FN using
|
||||
ARGS. Returns an expression for the call. */
|
||||
|
||||
tree
|
||||
finish_qualified_call_expr (fn, args)
|
||||
tree fn;
|
||||
tree args;
|
||||
{
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
|
||||
else
|
||||
return build_member_call (TREE_OPERAND (fn, 0),
|
||||
TREE_OPERAND (fn, 1),
|
||||
args);
|
||||
}
|
||||
|
||||
/* Finish an expression of the form CODE EXPR. */
|
||||
|
||||
tree
|
||||
|
312
gcc/cp/typeck.c
312
gcc/cp/typeck.c
@ -2455,309 +2455,6 @@ build_array_ref (array, idx)
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a function call to function FUNCTION with parameters PARAMS.
|
||||
PARAMS is a list--a chain of TREE_LIST nodes--in which the
|
||||
TREE_VALUE of each node is a parameter-expression. The PARAMS do
|
||||
not include any object pointer that may be required. FUNCTION's
|
||||
data type may be a function type or a pointer-to-function.
|
||||
|
||||
For C++: If FUNCTION's data type is a TREE_LIST, then the tree list
|
||||
is the list of possible methods that FUNCTION could conceivably
|
||||
be. If the list of methods comes from a class, then it will be
|
||||
a list of lists (where each element is associated with the class
|
||||
that produced it), otherwise it will be a simple list (for
|
||||
functions overloaded in global scope).
|
||||
|
||||
In the first case, TREE_VALUE (function) is the head of one of those
|
||||
lists, and TREE_PURPOSE is the name of the function.
|
||||
|
||||
In the second case, TREE_PURPOSE (function) is the function's
|
||||
name directly.
|
||||
|
||||
DECL is the class instance variable, usually CURRENT_CLASS_REF.
|
||||
|
||||
When calling a TEMPLATE_DECL, we don't require a complete return
|
||||
type. */
|
||||
|
||||
tree
|
||||
build_x_function_call (function, params, decl)
|
||||
tree function, params, decl;
|
||||
{
|
||||
tree type;
|
||||
tree template_id = NULL_TREE;
|
||||
int is_method;
|
||||
|
||||
if (function == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (CALL_EXPR, function, params, NULL_TREE);
|
||||
|
||||
/* Save explicit template arguments if found */
|
||||
if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
template_id = function;
|
||||
function = TREE_OPERAND (function, 0);
|
||||
}
|
||||
|
||||
type = TREE_TYPE (function);
|
||||
|
||||
if (TREE_CODE (type) == OFFSET_TYPE
|
||||
&& TREE_TYPE (type) == unknown_type_node
|
||||
&& TREE_CODE (function) == TREE_LIST
|
||||
&& TREE_CHAIN (function) == NULL_TREE)
|
||||
{
|
||||
/* Undo (Foo:bar)()... */
|
||||
type = TYPE_OFFSET_BASETYPE (type);
|
||||
function = TREE_VALUE (function);
|
||||
my_friendly_assert (TREE_CODE (function) == TREE_LIST, 999);
|
||||
my_friendly_assert (TREE_CHAIN (function) == NULL_TREE, 999);
|
||||
function = TREE_VALUE (function);
|
||||
if (TREE_CODE (function) == OVERLOAD)
|
||||
function = OVL_FUNCTION (function);
|
||||
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999);
|
||||
function = DECL_NAME (function);
|
||||
return build_method_call (decl, function, params,
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||
}
|
||||
|
||||
if (TREE_CODE (function) == OFFSET_REF
|
||||
&& TREE_CODE (type) != METHOD_TYPE)
|
||||
function = resolve_offset_ref (function);
|
||||
|
||||
if ((TREE_CODE (function) == FUNCTION_DECL
|
||||
&& DECL_STATIC_FUNCTION_P (function))
|
||||
|| (DECL_FUNCTION_TEMPLATE_P (function)
|
||||
&& DECL_STATIC_FUNCTION_P (DECL_TEMPLATE_RESULT (function))))
|
||||
return build_member_call (DECL_CONTEXT (function),
|
||||
template_id
|
||||
? template_id : DECL_NAME (function),
|
||||
params);
|
||||
|
||||
is_method = ((TREE_CODE (function) == TREE_LIST
|
||||
&& current_class_type != NULL_TREE
|
||||
&& (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function))
|
||||
== function))
|
||||
|| (TREE_CODE (function) == OVERLOAD
|
||||
&& DECL_FUNCTION_MEMBER_P (OVL_CURRENT (function)))
|
||||
|| TREE_CODE (function) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (type) == METHOD_TYPE
|
||||
|| TYPE_PTRMEMFUNC_P (type));
|
||||
|
||||
/* A friend template. Make it look like a toplevel declaration. */
|
||||
if (! is_method && TREE_CODE (function) == TEMPLATE_DECL)
|
||||
function = ovl_cons (function, NULL_TREE);
|
||||
|
||||
/* Handle methods, friends, and overloaded functions, respectively. */
|
||||
if (is_method)
|
||||
{
|
||||
tree basetype = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (function) == OVERLOAD)
|
||||
function = OVL_CURRENT (function);
|
||||
|
||||
if (TREE_CODE (function) == FUNCTION_DECL
|
||||
|| DECL_FUNCTION_TEMPLATE_P (function))
|
||||
{
|
||||
basetype = DECL_CONTEXT (function);
|
||||
|
||||
if (DECL_NAME (function))
|
||||
function = DECL_NAME (function);
|
||||
else
|
||||
function = TYPE_IDENTIFIER (DECL_CONTEXT (function));
|
||||
}
|
||||
else if (TREE_CODE (function) == TREE_LIST)
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (TREE_VALUE (function))
|
||||
== FUNCTION_DECL, 312);
|
||||
basetype = DECL_CONTEXT (TREE_VALUE (function));
|
||||
function = TREE_PURPOSE (function);
|
||||
}
|
||||
else if (TREE_CODE (function) != IDENTIFIER_NODE)
|
||||
{
|
||||
if (TREE_CODE (function) == OFFSET_REF)
|
||||
{
|
||||
if (TREE_OPERAND (function, 0))
|
||||
decl = TREE_OPERAND (function, 0);
|
||||
}
|
||||
/* Call via a pointer to member function. */
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
error ("pointer to member function called, but not in class scope");
|
||||
return error_mark_node;
|
||||
}
|
||||
/* What other type of POINTER_TYPE could this be? */
|
||||
if (TREE_CODE (TREE_TYPE (function)) != POINTER_TYPE
|
||||
&& ! TYPE_PTRMEMFUNC_P (TREE_TYPE (function))
|
||||
&& TREE_CODE (function) != OFFSET_REF)
|
||||
function = build (OFFSET_REF, TREE_TYPE (type), NULL_TREE,
|
||||
function);
|
||||
goto do_x_function;
|
||||
}
|
||||
|
||||
/* this is an abbreviated method call.
|
||||
must go through here in case it is a virtual function.
|
||||
@@ Perhaps this could be optimized. */
|
||||
|
||||
if (basetype && (! current_class_type
|
||||
|| ! DERIVED_FROM_P (basetype, current_class_type)))
|
||||
return build_member_call (basetype, function, params);
|
||||
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
if (current_class_type == NULL_TREE)
|
||||
{
|
||||
error ("object missing in call to method `%D'", function);
|
||||
return error_mark_node;
|
||||
}
|
||||
/* Yow: call from a static member function. */
|
||||
decl = build_dummy_object (current_class_type);
|
||||
}
|
||||
|
||||
/* Put back explicit template arguments, if any. */
|
||||
if (template_id)
|
||||
function = template_id;
|
||||
return build_method_call (decl, function, params,
|
||||
NULL_TREE, LOOKUP_NORMAL);
|
||||
}
|
||||
else if (TREE_CODE (function) == COMPONENT_REF
|
||||
&& type == unknown_type_node)
|
||||
{
|
||||
/* Undo what we did in build_component_ref. */
|
||||
decl = TREE_OPERAND (function, 0);
|
||||
function = TREE_OPERAND (function, 1);
|
||||
|
||||
if (TREE_CODE (function) == OVERLOAD
|
||||
&& TREE_TYPE (function) != unknown_type_node)
|
||||
/* It was a conversion operator. We can't use DECL_NAME, as
|
||||
that might refer to a templated function. */
|
||||
function = mangle_conv_op_name_for_type (TREE_TYPE (function));
|
||||
else if (TREE_CODE (function) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
my_friendly_assert (!template_id, 20011228);
|
||||
|
||||
template_id = function;
|
||||
}
|
||||
else
|
||||
{
|
||||
function = DECL_NAME (OVL_CURRENT (function));
|
||||
|
||||
if (template_id)
|
||||
{
|
||||
TREE_OPERAND (template_id, 0) = function;
|
||||
function = template_id;
|
||||
}
|
||||
}
|
||||
|
||||
return build_method_call (decl, function, params,
|
||||
NULL_TREE, LOOKUP_NORMAL);
|
||||
}
|
||||
else if (really_overloaded_fn (function))
|
||||
{
|
||||
if (OVL_FUNCTION (function) == NULL_TREE)
|
||||
{
|
||||
error ("function `%D' declared overloaded, but no definitions appear with which to resolve it?!?",
|
||||
TREE_PURPOSE (function));
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Put back explicit template arguments, if any. */
|
||||
if (template_id)
|
||||
function = template_id;
|
||||
return build_new_function_call (function, params);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Remove a potential OVERLOAD around it */
|
||||
function = OVL_CURRENT (function);
|
||||
|
||||
do_x_function:
|
||||
if (TREE_CODE (function) == OFFSET_REF)
|
||||
{
|
||||
/* If the component is a data element (or a virtual function), we play
|
||||
games here to make things work. */
|
||||
tree decl_addr;
|
||||
|
||||
if (TREE_OPERAND (function, 0))
|
||||
decl = TREE_OPERAND (function, 0);
|
||||
else
|
||||
decl = current_class_ref;
|
||||
|
||||
decl_addr = build_unary_op (ADDR_EXPR, decl, 0);
|
||||
|
||||
/* Sigh. OFFSET_REFs are being used for too many things.
|
||||
They're being used both for -> and ->*, and we want to resolve
|
||||
the -> cases here, but leave the ->*. We could use
|
||||
resolve_offset_ref for those, too, but it would call
|
||||
get_member_function_from_ptrfunc and decl_addr wouldn't get
|
||||
updated properly. Nasty. */
|
||||
if (TREE_CODE (TREE_OPERAND (function, 1)) == FIELD_DECL)
|
||||
function = resolve_offset_ref (function);
|
||||
else
|
||||
function = TREE_OPERAND (function, 1);
|
||||
|
||||
function = get_member_function_from_ptrfunc (&decl_addr, function);
|
||||
params = tree_cons (NULL_TREE, decl_addr, params);
|
||||
return build_function_call (function, params);
|
||||
}
|
||||
|
||||
type = TREE_TYPE (function);
|
||||
if (type != error_mark_node)
|
||||
{
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
if (IS_AGGR_TYPE (type))
|
||||
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, function, params, NULL_TREE);
|
||||
}
|
||||
|
||||
if (is_method)
|
||||
{
|
||||
tree fntype = TREE_TYPE (function);
|
||||
tree ctypeptr = NULL_TREE;
|
||||
|
||||
/* Explicitly named method? */
|
||||
if (TREE_CODE (function) == FUNCTION_DECL)
|
||||
ctypeptr = build_pointer_type (DECL_CLASS_CONTEXT (function));
|
||||
/* Expression with ptr-to-method type? It could either be a plain
|
||||
usage, or it might be a case where the ptr-to-method is being
|
||||
passed in as an argument. */
|
||||
else if (TYPE_PTRMEMFUNC_P (fntype))
|
||||
{
|
||||
tree rec = TYPE_METHOD_BASETYPE (TREE_TYPE
|
||||
(TYPE_PTRMEMFUNC_FN_TYPE (fntype)));
|
||||
ctypeptr = build_pointer_type (rec);
|
||||
}
|
||||
/* Unexpected node type? */
|
||||
else
|
||||
abort ();
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
if (current_function_decl
|
||||
&& DECL_STATIC_FUNCTION_P (current_function_decl))
|
||||
error ("invalid call to member function needing `this' in static member function scope");
|
||||
else
|
||||
error ("pointer to member function called, but not in class scope");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
|
||||
&& ! TYPE_PTRMEMFUNC_P (TREE_TYPE (decl)))
|
||||
{
|
||||
tree binfo = lookup_base (TREE_TYPE (decl), TREE_TYPE (ctypeptr),
|
||||
ba_check, NULL);
|
||||
|
||||
decl = build_unary_op (ADDR_EXPR, decl, 0);
|
||||
decl = build_base_path (PLUS_EXPR, decl, binfo, 1);
|
||||
}
|
||||
else
|
||||
decl = build_c_cast (ctypeptr, decl);
|
||||
params = tree_cons (NULL_TREE, decl, params);
|
||||
}
|
||||
|
||||
return build_function_call (function, params);
|
||||
}
|
||||
|
||||
/* Resolve a pointer to member function. INSTANCE is the object
|
||||
instance to use, if the member points to a virtual member.
|
||||
|
||||
@ -4928,7 +4625,7 @@ build_static_cast (type, expr)
|
||||
LOOKUP_COMPLAIN, NULL_TREE)));
|
||||
|
||||
if (IS_AGGR_TYPE (type))
|
||||
return build_cplus_new (type, (build_method_call
|
||||
return build_cplus_new (type, (build_special_member_call
|
||||
(NULL_TREE, complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL)));
|
||||
@ -5431,9 +5128,10 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
/* Do the default thing */;
|
||||
else
|
||||
{
|
||||
result = build_method_call (lhs, complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, rhs),
|
||||
TYPE_BINFO (lhstype), LOOKUP_NORMAL);
|
||||
result = build_special_member_call (lhs, complete_ctor_identifier,
|
||||
build_tree_list (NULL_TREE, rhs),
|
||||
TYPE_BINFO (lhstype),
|
||||
LOOKUP_NORMAL);
|
||||
if (result == NULL_TREE)
|
||||
return error_mark_node;
|
||||
return result;
|
||||
|
@ -1309,8 +1309,8 @@ build_functional_cast (exp, parms)
|
||||
return get_target_expr (exp);
|
||||
}
|
||||
|
||||
exp = build_method_call (NULL_TREE, complete_ctor_identifier, parms,
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||
exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||
|
||||
if (exp == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
@ -1,4 +1,11 @@
|
||||
2002-07-26 Neil Booth <neil@daikokuya.co.uk>
|
||||
2002-07-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/inherit/operator1.C: New test.
|
||||
* g++.dg/lookup/disamb1.C: Fix typo in comment.
|
||||
* g++.dg/other/error1.C: Change expected error message.
|
||||
* g++.dg/template/conv4.C: Likewise.
|
||||
|
||||
2002-07-26 Neil Booth <neil@daikokuya.cop.uk>
|
||||
|
||||
* gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/Wunused.c: Add test
|
||||
for documented behaviour.
|
||||
|
@ -113,11 +113,12 @@ Here are some more advanced usage instructions:
|
||||
1. To run a particular set of tests (rather than all of the tests),
|
||||
use the make variable "QMTEST_GPP_TESTS". For example,
|
||||
|
||||
make QMTEST_GPP_TESTS="gpp.dg" qmtest-g++
|
||||
make QMTEST_GPP_TESTS="g++.dg" qmtest-g++
|
||||
|
||||
will run only the tests in the g++.dg subdirectory, and:
|
||||
|
||||
make QMTEST_GPP_TESTS="gpp.dg.special.conpr1 gpp.old-deja.other.access2"
|
||||
make QMTEST_GPP_TESTS="g++.dg/special/conpr1.C \
|
||||
g++.old-deja/g++.other/access2.C"
|
||||
qmtest-g++
|
||||
|
||||
will run only the two tests indicated.
|
||||
|
34
gcc/testsuite/g++.dg/inherit/operator1.C
Normal file
34
gcc/testsuite/g++.dg/inherit/operator1.C
Normal file
@ -0,0 +1,34 @@
|
||||
// Test that conversions to base classes happen when calling
|
||||
// operators.
|
||||
|
||||
// { dg-do run }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
struct B1;
|
||||
struct B2;
|
||||
|
||||
B2* p;
|
||||
B1* p2;
|
||||
|
||||
struct B1 {
|
||||
virtual void f () {}
|
||||
};
|
||||
|
||||
struct B2 {
|
||||
int i;
|
||||
bool operator!() { if (this != p) abort (); return true; }
|
||||
operator void*() { if (this != p) abort (); return this; }
|
||||
};
|
||||
|
||||
struct B3 : public B1, public B2 {
|
||||
};
|
||||
|
||||
int main () {
|
||||
B3 b;
|
||||
p = (B2*) &b;
|
||||
p2 = (B1*) &b;
|
||||
bool b1 = b;
|
||||
bool b2 = !b;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// PR c++/525
|
||||
// Bug: With -pedantic, we weren't converting this to D1* for the call.
|
||||
// Bug: With -pedantic, we weren't converting this to B1* for the call.
|
||||
|
||||
struct A
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 18 Dec 2001 <nathan@nathan@codesourcery.com>
|
||||
|
||||
// PR 90, stupid error message `(this + 160)'
|
||||
@ -10,6 +10,6 @@ class foo {
|
||||
int fudge[40];
|
||||
int bar [40];
|
||||
inline int access(int i) {
|
||||
return bar(i); // { dg-error "`this->foo::bar' cannot" "" }
|
||||
return bar(i); // { dg-error "call to non-function `foo::bar'" "" }
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 29 Dec 2001 <nathan@codesourcery.com>
|
||||
|
||||
// PR 4361. Template conversion operators were not overloaded.
|
||||
@ -21,7 +21,7 @@ struct D
|
||||
{
|
||||
int Foo ()
|
||||
{
|
||||
return operator int (); // { dg-error "no matching function" "" }
|
||||
return operator int (); // { dg-error "not defined" "" }
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user