aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2001-07-05 11:39:36 -0400
committerJason Merrill <jason@gcc.gnu.org>2001-07-05 11:39:36 -0400
commit01f9e964bd55fd0f52f4a084f70ee7a5e071cfa9 (patch)
tree0709114363ae3b357e7e3dc92f90a62a000a2673 /gcc/cp
parent021c4bfd955ee14e054e0af78941e7401dbb9012 (diff)
downloadgcc-01f9e964bd55fd0f52f4a084f70ee7a5e071cfa9.zip
gcc-01f9e964bd55fd0f52f4a084f70ee7a5e071cfa9.tar.gz
gcc-01f9e964bd55fd0f52f4a084f70ee7a5e071cfa9.tar.bz2
cvt.c (convert_lvalue): New fn.
* cvt.c (convert_lvalue): New fn. * cp-tree.h: Declare it. * method.c (do_build_assign_ref): Use it. (do_build_copy_constructor): Convert parm to base types before calling base constructors. * typeck.c (check_return_expr): Check DECL_ALIGN instead of DECL_USER_ALIGN. Check flag_elide_constructors instead of optimize. * semantics.c (cp_expand_stmt): Don't destroy the named return value. From-SVN: r43780
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cvt.c14
-rw-r--r--gcc/cp/method.c27
-rw-r--r--gcc/cp/semantics.c4
-rw-r--r--gcc/cp/typeck.c5
6 files changed, 48 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dfe82c0..5e6195c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+2001-07-05 Jason Merrill <jason_merrill@redhat.com>
+
+ * cvt.c (convert_lvalue): New fn.
+ * cp-tree.h: Declare it.
+ * method.c (do_build_assign_ref): Use it.
+ (do_build_copy_constructor): Convert parm to base types
+ before calling base constructors.
+
+ * typeck.c (check_return_expr): Check DECL_ALIGN instead of
+ DECL_USER_ALIGN. Check flag_elide_constructors instead of
+ optimize.
+ * semantics.c (cp_expand_stmt): Don't destroy the named return value.
+
2001-07-02 Nathan Sidwell <nathan@codesourcery.com>
* optimize.c (optimize_inline_calls): New function, broken out
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cebc926..2ccb3b7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3735,6 +3735,7 @@ extern tree get_primary_binfo PARAMS ((tree));
/* in cvt.c */
extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree));
extern tree convert_from_reference PARAMS ((tree));
+extern tree convert_lvalue PARAMS ((tree, tree));
extern tree convert_pointer_to_real PARAMS ((tree, tree));
extern tree convert_pointer_to PARAMS ((tree, tree));
extern tree ocp_convert PARAMS ((tree, tree, int, int));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 1dff9e5..33be568 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -597,6 +597,20 @@ convert_from_reference (val)
return build_indirect_ref (val, NULL);
return val;
}
+
+/* Implicitly convert the lvalue EXPR to another lvalue of type TOTYPE,
+ preserving cv-qualification. */
+
+tree
+convert_lvalue (totype, expr)
+ tree totype, expr;
+{
+ totype = cp_build_qualified_type (totype, TYPE_QUALS (TREE_TYPE (expr)));
+ totype = build_reference_type (totype);
+ expr = convert_to_reference (totype, expr, CONV_IMPLICIT, LOOKUP_NORMAL,
+ NULL_TREE);
+ return convert_from_reference (expr);
+}
/* Call this when we know (for any reason) that expr is not, in fact,
zero. This routine is like convert_pointer_to, but it pays
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index ceb569c..6f6a14b 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -557,25 +557,31 @@ do_build_copy_constructor (fndecl)
int cvquals = CP_TYPE_QUALS (TREE_TYPE (parm));
int i;
- /* Initialize all the base-classes. */
+ /* Initialize all the base-classes with the parameter converted to
+ their type so that we get their copy constructor and not another
+ constructor that takes current_class_type. */
for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
t = TREE_CHAIN (t))
- base_init_list
- = tree_cons (BINFO_TYPE (TREE_VALUE (t)), parm,
- base_init_list);
+ {
+ tree type = BINFO_TYPE (TREE_VALUE (t));
+ base_init_list = tree_cons (type, convert_lvalue (type, parm),
+ base_init_list);
+ }
+
for (i = 0; i < n_bases; ++i)
{
t = TREE_VEC_ELT (binfos, i);
if (TREE_VIA_VIRTUAL (t))
continue;
- base_init_list
- = tree_cons (BINFO_TYPE (t), parm, base_init_list);
+ t = BINFO_TYPE (t);
+ base_init_list = tree_cons (t, convert_lvalue (t, parm),
+ base_init_list);
}
for (; fields; fields = TREE_CHAIN (fields))
{
- tree init, t;
+ tree init;
tree field = fields;
if (TREE_CODE (field) != FIELD_DECL)
@@ -645,12 +651,7 @@ do_build_assign_ref (fndecl)
for (i = 0; i < n_bases; ++i)
{
tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
- tree p = build_qualified_type (basetype, cvquals);
-
- p = convert_to_reference
- (build_reference_type (p), parm,
- CONV_IMPLICIT, LOOKUP_COMPLAIN, NULL_TREE);
- p = convert_from_reference (p);
+ tree p = convert_lvalue (basetype, parm);
p = build_member_call (basetype, ansi_assopname (NOP_EXPR),
build_tree_list (NULL_TREE, p));
finish_expr_stmt (p);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 050e1be..66f36ab 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2156,7 +2156,9 @@ cp_expand_stmt (t)
switch (TREE_CODE (t))
{
case CLEANUP_STMT:
- genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
+ /* Don't destroy the chosen named return value. */
+ if (CLEANUP_DECL (t) != current_function_return_value)
+ genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
break;
case CTOR_STMT:
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index cb1146e..43f38f3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6684,7 +6684,7 @@ check_return_expr (retval)
returned expression uses the chosen variable somehow. And people expect
this restriction, anyway. (jason 2000-11-19) */
- if (fn_returns_value_p && optimize)
+ if (fn_returns_value_p && flag_elide_constructors)
{
if (retval != NULL_TREE
&& (current_function_return_value == NULL_TREE
@@ -6692,7 +6692,8 @@ check_return_expr (retval)
&& TREE_CODE (retval) == VAR_DECL
&& DECL_CONTEXT (retval) == current_function_decl
&& ! TREE_STATIC (retval)
- && ! DECL_USER_ALIGN (retval)
+ && (DECL_ALIGN (retval)
+ == DECL_ALIGN (DECL_RESULT (current_function_decl)))
&& same_type_p (TREE_TYPE (retval),
TREE_TYPE (TREE_TYPE (current_function_decl))))
current_function_return_value = retval;