typeck.c (c_expand_return): Always convert_for_initialization before checking for returning a pointer to local.

* typeck.c (c_expand_return): Always convert_for_initialization
 	before checking for returning a pointer to local.

From-SVN: r15064
This commit is contained in:
Jason Merrill 1997-09-03 20:01:18 +00:00 committed by Jason Merrill
parent fa8b602464
commit c1bc6829b4
3 changed files with 67 additions and 86 deletions

View File

@ -1,5 +1,8 @@
Wed Sep 3 11:09:25 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (c_expand_return): Always convert_for_initialization
before checking for returning a pointer to local.
* pt.c (type_unification): If strict and the function parm doesn't
use template parms, just compare types.

View File

@ -321,7 +321,9 @@ int flag_memoize_lookups; int flag_save_memoized_contexts;
int write_virtuals;
/* Nonzero means we should attempt to elide constructors when possible. */
/* Nonzero means we should attempt to elide constructors when possible.
FIXME: This flag is obsolete, and should be torn out along with the
old overloading code. */
int flag_elide_constructors;

View File

@ -7204,24 +7204,48 @@ c_expand_return (retval)
expand_return (retval);
return;
}
/* Now deal with possible C++ hair:
(1) Compute the return value.
(2) If there are aggregate values with destructors which
must be cleaned up, clean them (taking care
not to clobber the return value).
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TREE_TYPE (retval) == void_type_node)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
}
else
{
retval = convert_for_initialization
(NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
"return", NULL_TREE, 0);
if (retval == error_mark_node)
{
/* Avoid warning about control reaching end of function. */
expand_null_return ();
return;
}
/* We can't initialize a register from a NEW_EXPR. */
else if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 1)) == NEW_EXPR)
retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
TREE_OPERAND (retval, 0));
/* Add some useful error checking for C++. */
else if (TREE_CODE (valtype) == REFERENCE_TYPE)
{
tree whats_returned;
tree tmp_result = result;
/* Don't initialize directly into a non-BLKmode retval, since that
could lose when being inlined by another caller. (GCC can't
read the function return register in an inline function when
the return value is being ignored). */
if (result && TYPE_MODE (TREE_TYPE (tmp_result)) != BLKmode)
tmp_result = 0;
/* convert to reference now, so we can give error if we
return an reference to a non-lvalue. */
retval = convert_for_initialization
(tmp_result, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
"return", NULL_TREE, 0);
/* Sort through common things to see what it is
we are returning. */
@ -7268,54 +7292,6 @@ c_expand_return (retval)
&& !TREE_PUBLIC (whats_returned))
cp_warning_at ("address of local variable `%D' returned", whats_returned);
}
else if (TREE_CODE (retval) == VAR_DECL)
{
if (TREE_CODE (TREE_TYPE (retval)) == ARRAY_TYPE
&& DECL_NAME (retval)
&& IDENTIFIER_LOCAL_VALUE (DECL_NAME (retval))
&& !TREE_STATIC (retval)
&& !TREE_PUBLIC (retval))
cp_warning_at ("address of local array `%D' returned", retval);
}
/* Now deal with possible C++ hair:
(1) Compute the return value.
(2) If there are aggregate values with destructors which
must be cleaned up, clean them (taking care
not to clobber the return value).
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
if (retval == result
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TREE_TYPE (retval) == void_type_node)
{
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
}
else
{
/* We already did this above for refs, don't do it again. */
if (TREE_CODE (valtype) != REFERENCE_TYPE)
retval = convert_for_initialization
(NULL_TREE, valtype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
"return", NULL_TREE, 0);
/* We can't initialize a register from a NEW_EXPR. */
if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 1)) == NEW_EXPR)
retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
TREE_OPERAND (retval, 0));
if (retval == error_mark_node)
{
/* Avoid warning about control reaching end of function. */
expand_null_return ();
return;
}
}
if (retval != NULL_TREE