aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/call.c19
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/init.c51
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/cp/tree.c6
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/cp/typeck2.c33
8 files changed, 59 insertions, 76 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6f2a6ab..524cbea 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,16 @@
2002-04-06 Jason Merrill <jason@redhat.com>
+ PR c++/525
+ * init.c (build_member_call): Use build_scoped_ref.
+ (resolve_offset_ref): Likewise.
+ * call.c (build_scoped_method_call): Likewise.
+ * tree.c (maybe_dummy_object): Kludge around current_class_type being
+ wrong.
+ * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm.
+ * cp-tree.h: Adjust.
+
+ * init.c (push_base_cleanups): Just use build_scoped_method_call.
+
PR c++/6179
* method.c (implicitly_declare_fn): Pass unqualified type to
synthesize_exception_spec.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 1a74f74..d341fb0 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -298,27 +298,10 @@ build_scoped_method_call (exp, basetype, name, parms)
return error_mark_node;
}
- if (! binfo)
- {
- binfo = lookup_base (type, basetype, ba_check, NULL);
- if (binfo == error_mark_node)
- return error_mark_node;
- if (! binfo)
- error_not_base_type (basetype, type);
- }
+ decl = build_scoped_ref (exp, basetype, &binfo);
if (binfo)
{
- if (TREE_CODE (exp) == INDIRECT_REF)
- {
- decl = build_base_path (PLUS_EXPR,
- build_unary_op (ADDR_EXPR, exp, 0),
- binfo, 1);
- decl = build_indirect_ref (decl, NULL);
- }
- else
- decl = build_scoped_ref (exp, basetype);
-
/* Call to a destructor. */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b65467b..8b3a256 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4387,7 +4387,7 @@ extern int abstract_virtuals_error PARAMS ((tree, tree));
extern tree store_init_value PARAMS ((tree, tree));
extern tree digest_init PARAMS ((tree, tree, tree *));
-extern tree build_scoped_ref PARAMS ((tree, tree));
+extern tree build_scoped_ref PARAMS ((tree, tree, tree *));
extern tree build_x_arrow PARAMS ((tree));
extern tree build_m_component_ref PARAMS ((tree, tree));
extern tree build_functional_cast PARAMS ((tree, tree));
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 57b3dba..5caa69c 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1496,20 +1496,13 @@ build_member_call (type, name, parmlist)
decl = maybe_dummy_object (type, &basetype_path);
/* Convert 'this' to the specified type to disambiguate conversion
- to the function's context. Apparently Standard C++ says that we
- shouldn't do this. */
- if (decl == current_class_ref
- && ! pedantic
- && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type))
- {
- tree olddecl = current_class_ptr;
- tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
- if (oldtype != type)
- {
- tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype));
- decl = convert_force (build_pointer_type (newtype), olddecl, 0);
- decl = build_indirect_ref (decl, NULL);
- }
+ to the function's context. */
+ if (decl == current_class_ref)
+ {
+ basetype_path = NULL_TREE;
+ decl = build_scoped_ref (decl, type, &basetype_path);
+ if (decl == error_mark_node)
+ return error_mark_node;
}
if (method_name == constructor_name (type)
@@ -1819,7 +1812,7 @@ resolve_offset_ref (exp)
if (TREE_CODE (member) == FIELD_DECL
&& (base == current_class_ref || is_dummy_object (base)))
{
- tree binfo = TYPE_BINFO (current_class_type);
+ tree binfo = NULL_TREE;
/* Try to get to basetype from 'this'; if that doesn't work,
nothing will. */
@@ -1827,13 +1820,7 @@ resolve_offset_ref (exp)
/* First convert to the intermediate base specified, if appropriate. */
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
- {
- binfo = binfo_or_else (TYPE_OFFSET_BASETYPE (type),
- current_class_type);
- if (!binfo)
- return error_mark_node;
- base = build_base_path (PLUS_EXPR, base, binfo, 1);
- }
+ base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo);
return build_component_ref (base, member, binfo, 1);
}
@@ -3225,7 +3212,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
/* At the beginning of a destructor, push cleanups that will call the
destructors for our base classes and members.
- Called from setup_vtbl_ptr. */
+ Called from begin_destructor_body. */
void
push_base_cleanups ()
@@ -3255,21 +3242,9 @@ push_base_cleanups ()
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type))
{
- tree base_ptr_type = build_pointer_type (base_type);
- expr = current_class_ptr;
-
- /* Convert to the basetype here, as we know the layout is
- fixed. What is more, if we let build_method_call do it,
- it will use the vtable, which may have been clobbered
- by the deletion of our primary base. */
-
- expr = build1 (NOP_EXPR, base_ptr_type, expr);
- expr = build (PLUS_EXPR, base_ptr_type, expr,
- BINFO_OFFSET (vbase));
- expr = build_indirect_ref (expr, NULL);
- expr = build_method_call (expr, base_dtor_identifier,
- NULL_TREE, vbase,
- LOOKUP_NORMAL);
+ expr = build_scoped_method_call (current_class_ref, vbase,
+ base_dtor_identifier,
+ NULL_TREE);
expr = build (COND_EXPR, void_type_node, cond,
expr, void_zero_node);
finish_decl_cleanup (NULL_TREE, expr);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b705783..30a6ddb 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5559,7 +5559,11 @@ tsubst_default_argument (fn, type, arg)
};
we must be careful to do name lookup in the scope of S<T>,
- rather than in the current class. */
+ rather than in the current class.
+
+ ??? current_class_type affects a lot more than name lookup. This is
+ very fragile. Fortunately, it will go away when we do 2-phase name
+ binding properly. */
if (DECL_CLASS_SCOPE_P (fn))
pushclass (DECL_CONTEXT (fn), 2);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index e0f7361..641d82b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1844,7 +1844,11 @@ maybe_dummy_object (type, binfop)
if (binfop)
*binfop = binfo;
- if (current_class_ref && context == current_class_type)
+ if (current_class_ref && context == current_class_type
+ // Kludge: Make sure that current_class_type is actually correct.
+ // It might not be if we're in the middle of tsubst_default_argument.
+ && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)),
+ current_class_type))
decl = current_class_ref;
else
decl = build_dummy_object (context);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 593e2bb..be07b2e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1826,10 +1826,9 @@ build_object_ref (datum, basetype, field)
}
else if (is_aggr_type (basetype, 1))
{
- tree binfo = binfo_or_else (basetype, dtype);
- if (binfo)
- return build_x_component_ref (build_scoped_ref (datum, basetype),
- field, binfo, 1);
+ tree binfo = NULL_TREE;
+ datum = build_scoped_ref (datum, basetype, &binfo);
+ return build_x_component_ref (datum, field, binfo, 1);
}
return error_mark_node;
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 48caade..d7ac3d7 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -954,7 +954,7 @@ process_init_constructor (type, init, elts)
/* Given a structure or union value DATUM, construct and return
the structure or union component which results from narrowing
- that value by the type specified in BASETYPE. For example, given the
+ that value to the base specified in BASETYPE. For example, given the
hierarchy
class L { int ii; };
@@ -975,29 +975,36 @@ process_init_constructor (type, init, elts)
I used to think that this was nonconformant, that the standard specified
that first we look up ii in A, then convert x to an L& and pull out the
ii part. But in fact, it does say that we convert x to an A&; A here
- is known as the "naming class". (jason 2000-12-19) */
+ is known as the "naming class". (jason 2000-12-19)
+
+ BINFO_P points to a variable initialized either to NULL_TREE or to the
+ binfo for the specific base subobject we want to convert to. */
tree
-build_scoped_ref (datum, basetype)
+build_scoped_ref (datum, basetype, binfo_p)
tree datum;
tree basetype;
+ tree *binfo_p;
{
- tree ref;
tree binfo;
if (datum == error_mark_node)
return error_mark_node;
- binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL);
+ if (*binfo_p)
+ binfo = *binfo_p;
+ else
+ binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL);
- if (binfo == error_mark_node)
- return error_mark_node;
- if (!binfo)
- return error_not_base_type (TREE_TYPE (datum), basetype);
-
- ref = build_unary_op (ADDR_EXPR, datum, 0);
- ref = build_base_path (PLUS_EXPR, ref, binfo, 1);
+ if (!binfo || binfo == error_mark_node)
+ {
+ *binfo_p = NULL_TREE;
+ if (!binfo)
+ error_not_base_type (basetype, TREE_TYPE (datum));
+ return error_mark_node;
+ }
- return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
+ *binfo_p = binfo;
+ return build_base_path (PLUS_EXPR, datum, binfo, 1);
}
/* Build a reference to an object specified by the C++ `->' operator.