* 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
+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
/* 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));
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);
+}
\f
/* 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
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)
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);
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:
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
&& 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;